BVB Source Codes

CRYENGINE Show FlightNavRegion2.cpp Source code

Return Download CRYENGINE: download FlightNavRegion2.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 "FlightNavRegion2.h"
  5. #include "AILog.h"
  6. #include <CryPhysics/IPhysics.h>
  7. #include <algorithm>
  8. #include <limits>
  9. #include <CrySystem/ISystem.h>
  10. #include <CryRenderer/IRenderer.h>      // this is needed for debug drawing
  11. #include <CryRenderer/IRenderAuxGeom.h> // this is needed for debug drawing
  12. //#include <CryFile.h>
  13. #include <CrySystem/ITimer.h>
  14. #include <Cry3DEngine/I3DEngine.h>
  15. #include <CryMath/Cry_GeoOverlap.h>
  16. #include "AICollision.h"
  17. #include <CryNetwork/ISerialize.h>
  18. #include "Navigation.h"     // NOTE Feb 22, 2008: <pvl> for SpecialArea declaration
  19.  
  20. #include "GenericAStarSolver.h"
  21.  
  22. #define BAI_FNAV2_FILE_VERSION_READ  21
  23. #define BAI_FNAV2_FILE_VERSION_WRITE 21
  24.  
  25. //#pragma optimize("", off)
  26. //#pragma inline_depth(0)
  27.  
  28. static const int8 offsets[8][2] = {
  29.         { -1, 0 }, { -1, 1 }, { 0, 1 }, { 1, 1 }, { 1, 0 }, { 1, -1 }, { 0, -1 }, { -1, -1 }
  30. };
  31.  
  32. // no need to expose those in the header
  33. enum DebugDraws
  34. {
  35.         OFF              = 0,
  36.         DRAWNAVDATA      = 1,
  37.         DRAWCONNECTTIONS = 2,
  38.         DRAWPATH         = 3,
  39.         DRAWPORTALS      = 4,
  40. };
  41.  
  42. STRUCT_INFO_BEGIN(SpanDesc)
  43. STRUCT_VAR_INFO(x, TYPE_INFO(int))
  44. STRUCT_VAR_INFO(y, TYPE_INFO(int))
  45. STRUCT_VAR_INFO(smin, TYPE_INFO(int))
  46. STRUCT_VAR_INFO(smax, TYPE_INFO(int))
  47. STRUCT_INFO_END(SpanDesc)
  48.  
  49. struct AStarNodeCompare
  50. {
  51.         bool operator()(const AStarNode<Vec3i>& LHS, const AStarNode<Vec3i>& RHS) const
  52.         {
  53.                 uint32 left = LHS.graphNodeIndex.x + LHS.graphNodeIndex.y * 1000 + LHS.graphNodeIndex.z * 1000000;
  54.                 uint32 right = RHS.graphNodeIndex.x + RHS.graphNodeIndex.y * 1000 + RHS.graphNodeIndex.z * 1000000;
  55.  
  56.                 return left < right;
  57.         }
  58. };
  59.  
  60. class ClosedList
  61. {
  62.         std::set<Vec3i, AStarNodeCompare> closedList;
  63. public:
  64.  
  65.         void Resize(Vec3i size)
  66.         {
  67.                 closedList.clear();
  68.         }
  69.  
  70.         void Close(Vec3i index)
  71.         {
  72.                 closedList.insert(index);
  73.         }
  74.  
  75.         bool IsClosed(Vec3i index) const
  76.         {
  77.                 return closedList.find(index) != closedList.end();
  78.         }
  79.  
  80.         //For users debug benefit they may template specialize this function:
  81.         void Print() const;
  82. };
  83.  
  84. class NodeContainer
  85. {
  86.         std::set<AStarNode<Vec3i>, AStarNodeCompare> aStarNodes;
  87.  
  88. public:
  89.  
  90.         AStarNode<Vec3i>* GetAStarNode(Vec3i nodeIndex)
  91.         {
  92.                 std::pair<std::set<AStarNode<Vec3i>, AStarNodeCompare>::iterator, bool> result =
  93.                   aStarNodes.insert(AStarNode<Vec3i>(nodeIndex));
  94.  
  95.                 return const_cast<AStarNode<Vec3i>*>(&*result.first);
  96.         }
  97.  
  98.         void Clear()
  99.         {
  100.                 aStarNodes.clear();
  101.         }
  102. };
  103.  
  104. GenericAStarSolver<CFlightNavRegion2::NavData, CFlightNavRegion2::NavData, CFlightNavRegion2::NavData, DefaultOpenList<Vec3i>, ClosedList, NodeContainer> astar;
  105.  
  106. bool CFlightNavRegion2::NavData::Span::Overlaps(const Span* other, float amount) const
  107. {
  108.         bool ret = false;
  109.  
  110.         if (other)
  111.         {
  112.                 float testMinHeight = other->heightMin;
  113.                 float testMaxHeight = other->heightMax;
  114.  
  115.                 ret = !(heightMax > testMaxHeight) && !(heightMin < testMinHeight);
  116.                 ret |= (heightMin > testMinHeight) && (testMaxHeight - heightMin) > amount;
  117.                 ret |= (testMinHeight > heightMin) && (heightMax - testMinHeight) > amount;
  118.  
  119.         }
  120.  
  121.         return ret;
  122. }
  123.  
  124. bool CFlightNavRegion2::NavData::Span::Overlaps(const Vec3& pos) const
  125. {
  126.         bool ret = false;
  127.  
  128.         if (!(heightMin > pos.z) && !(heightMax < pos.z))
  129.         {
  130.                 ret = true;
  131.         }
  132.  
  133.         return ret;
  134. }
  135.  
  136. bool CFlightNavRegion2::NavData::Span::GetPortal(const Span* other, float& top, float& bottom, float amount) const
  137. {
  138.         bool ret = false;
  139.  
  140.         if (other)
  141.         {
  142.                 top = static_cast<float>(__fsel(other->heightMax - heightMax, heightMax - amount, other->heightMax - amount));
  143.                 bottom = static_cast<float>(__fsel(other->heightMin - heightMin, other->heightMin + amount, heightMin + amount));
  144.  
  145.                 ret = true;
  146.         }
  147.  
  148.         return ret;
  149. }
  150.  
  151. CFlightNavRegion2::NavData::NavData(uint32 _width, uint32 _height, uint32 _spanCount)
  152.         : width(_width)
  153.         , height(_height)
  154.         , maxSpans(_spanCount + 1)
  155.         , spanCount(1)
  156.         , horVoxelSize(0.0f)
  157.         , agentHeight(0.0f)
  158.         , basePos(ZERO)
  159. {
  160.         spans = new Span[_spanCount + 1];
  161.  
  162.         grid = new uint32[width * height];
  163.         memset(grid, 0, width * height * sizeof(grid[0]));
  164. }
  165.  
  166. CFlightNavRegion2::NavData::~NavData()
  167. {
  168.         delete[] spans;
  169.         delete[] grid;
  170. }
  171.  
  172. void CFlightNavRegion2::NavData::AddSpan(int x, int y, float minHeight, float maxHeight, uint32 flags)
  173. {
  174.         if (spanCount < maxSpans)
  175.         {
  176. #ifdef _DEBUG
  177.                 gEnv->pLog->Log("Adding span x=%d, y=%d, min=%f, max=%f (spancount = %d)", x, y, minHeight, maxHeight, spanCount - 1);
  178. #endif
  179.  
  180.                 spans[spanCount].heightMin = minHeight;
  181.                 spans[spanCount].heightMax = maxHeight;
  182.  
  183.                 if (IsColumnSet(x, y))
  184.                 {
  185.                         Span& span = GetColumn(x, y);
  186.  
  187.                         while (span.next)
  188.                         {
  189.                                 span = *span.next;
  190.                         }
  191.  
  192.                         span.next = &spans[spanCount];
  193.                 }
  194.                 else
  195.                 {
  196.                         GetGridCell(x, y) = spanCount;
  197.                 }
  198.  
  199.                 ++spanCount;
  200.         }
  201. }
  202.  
  203. const CFlightNavRegion2::NavData::Span& CFlightNavRegion2::NavData::GetNeighbourColumn(uint x, uint y, Span::Neighbour neigh) const
  204. {
  205.         int xOff = offsets[neigh][0];
  206.         int yOff = offsets[neigh][1];
  207.  
  208.         uint32 xr = x + xOff;
  209.         uint32 yr = y + yOff;
  210.  
  211.         if (xr < width && yr < height)
  212.         {
  213.                 return GetColumn(xr, yr);
  214.         }
  215.  
  216.         return spans[0];
  217. }
  218.  
  219. bool CFlightNavRegion2::NavData::GetEnclosing(const Vec3& pos, Vec3i& spanPos, Vec3* outPos) const
  220. {
  221.         bool ret = false;
  222.  
  223.         int32 offX = 0;
  224.         int32 offY = 0;
  225.         int32 offZ = 0;
  226.  
  227.         Vec3 diff = pos - basePos;
  228.         //float horVoxelSize = horVoxelSize;
  229.  
  230.         offX = static_cast<int>(diff.x / horVoxelSize);
  231.         offY = static_cast<int>(diff.y / horVoxelSize);
  232.  
  233.         if (!(offX < 0 || (uint32)offX > width || offY < 0 || (uint32)offY > height))
  234.         {
  235.  
  236.                 const NavData::Span* span = &GetColumn(offX, offY);
  237.                 if (IsSpanValid(span))
  238.                 {
  239.                         offZ = 0;
  240.                         while (span)
  241.                         {
  242.                                 if (span->Overlaps(diff))
  243.                                 {
  244.                                         spanPos.x = offX;
  245.                                         spanPos.y = offY;
  246.                                         spanPos.z = offZ;
  247.  
  248.                                         ret = true;
  249.                                         break;
  250.                                 }
  251.  
  252.                                 ++offZ;
  253.                                 span = span->next;
  254.                         }
  255.                 }
  256.         }
  257.  
  258.         return ret;
  259. }
  260.  
  261. Vec3i CFlightNavRegion2::NavData::GetNumNodes() const
  262. {
  263.         return Vec3i(width, height, 50);
  264. }
  265.  
  266. Vec3i CFlightNavRegion2::NavData::GetBestNodeIndex(Vec3& referencePoint) const
  267. {
  268.         Vec3i ret(-1, -1, -1);
  269.  
  270.         GetEnclosing(referencePoint, ret);
  271.  
  272.         if (-1 == ret.x || -1 == ret.y || -1 == ret.z)
  273.         {
  274.                 Vec3 center;
  275.                 GetClosestSpan(referencePoint, ret, center);
  276.         }
  277.  
  278.         return ret;
  279. }
  280.  
  281. Vec3 CFlightNavRegion2::NavData::GetNodeReferencePoint(Vec3i nodeIndex) const
  282. {
  283.         Vec3 pos;
  284.         const Span* span = GetSpan(nodeIndex.x, nodeIndex.y, nodeIndex.z);
  285.  
  286.         if (span)
  287.         {
  288.                 pos.x = (static_cast<float>(nodeIndex.x) + 0.5f) * horVoxelSize;
  289.                 pos.y = (static_cast<float>(nodeIndex.y) + 0.5f) * horVoxelSize;
  290.                 pos.z = (span->heightMin + span->heightMax) * 0.5f;
  291.         }
  292.  
  293.         return pos;
  294. }
  295.  
  296. int CFlightNavRegion2::NavData::GetNumLinks(Vec3i nodeIndex) const
  297. {
  298.         int ret = 0;
  299.  
  300.         const Span* span = GetSpan(nodeIndex.x, nodeIndex.y, nodeIndex.z);
  301.  
  302.         if (span)
  303.         {
  304.                 for (uint32 loop = 0; loop < 8; ++loop)
  305.                 {
  306.                         if (span->neighbours[loop][0])
  307.                         {
  308.                                 ret += span->neighbours[loop][1] - span->neighbours[loop][0] + 1;
  309.                         }
  310.                 }
  311.         }
  312.  
  313.         return ret;
  314. }
  315.  
  316. Vec3i CFlightNavRegion2::NavData::GetNextNodeIndex(Vec3i graphNodeIndex, int linkIndex) const
  317. {
  318.         Vec3i ret(-1, -1, -1);
  319.  
  320.         const Span* span = GetSpan(graphNodeIndex.x, graphNodeIndex.y, graphNodeIndex.z);
  321.  
  322.         if (span)
  323.         {
  324.                 for (uint32 loop = 0; loop < 8; ++loop)
  325.                 {
  326.                         if (span->neighbours[loop][0])
  327.                         {
  328.                                 uint32 diff = span->neighbours[loop][1] - span->neighbours[loop][0] + 1;
  329.                                 if ((uint32)linkIndex < diff)
  330.                                 {
  331.                                         uint32 z = span->neighbours[loop][0] + linkIndex - 1;
  332.                                         return Vec3i(graphNodeIndex.x + offsets[loop][0], graphNodeIndex.y + offsets[loop][1], z);
  333.                                 }
  334.                                 else
  335.                                 {
  336.                                         linkIndex -= diff;
  337.                                 }
  338.                         }
  339.                 }
  340.         }
  341.  
  342.         return ret;
  343. }
  344.  
  345. //heuristics and cost function
  346. float CFlightNavRegion2::NavData::H(const NavData* graph, Vec3i currentNodeIndex, Vec3i endNodeIndex) const
  347. {
  348.         float ret = FLT_MAX;
  349.  
  350.         if (graph)
  351.         {
  352.                 const Span* cur = graph->GetSpan(currentNodeIndex.x, currentNodeIndex.y, currentNodeIndex.z);
  353.                 const Span* end = graph->GetSpan(endNodeIndex.x, endNodeIndex.y, endNodeIndex.z);
  354.  
  355.                 if ((cur != NULL) && (end != NULL))
  356.                 {
  357.                         Vec3i diff = endNodeIndex - currentNodeIndex;
  358.  
  359.                         float curHeight = cur->heightMin; //(cur->heightMax + cur->heightMin) * 0.5f;
  360.                         float endHeight = end->heightMin;//(end->heightMax + end->heightMin) * 0.5f;
  361.                         endHeight -= curHeight;
  362.  
  363.                         ret = diff.x * diff.x * horVoxelSize * horVoxelSize + diff.y * diff.y * horVoxelSize * horVoxelSize + endHeight * endHeight;
  364.                 }
  365.         }
  366.  
  367.         return ret;
  368. }
  369.  
  370. //link traversalcost
  371. float CFlightNavRegion2::NavData::GetCost(const NavData* graph, Vec3i currentNodeIndex, Vec3i nextNodeIndex) const
  372. {
  373.         float ret = FLT_MAX;
  374.  
  375.         if (graph)
  376.         {
  377.                 const Span* cur = graph->GetSpan(currentNodeIndex.x, currentNodeIndex.y, currentNodeIndex.z);
  378.                 const Span* end = graph->GetSpan(nextNodeIndex.x, nextNodeIndex.y, nextNodeIndex.z);
  379.  
  380.                 if ((cur != NULL) && (end != NULL))
  381.                 {
  382.                         //Vec3i diff = nextNodeIndex - currentNodeIndex;
  383.                         //ret = diff.x * diff.x * horVoxelSize  * horVoxelSize + diff.y * diff.y * horVoxelSize  * horVoxelSize;
  384.  
  385.                         Vec3i diff = nextNodeIndex - currentNodeIndex;
  386.  
  387.                         float curHeight = cur->heightMin; //(cur->heightMax + cur->heightMin) * 0.5f;
  388.                         float endHeight = end->heightMin;//(end->heightMax + end->heightMin) * 0.5f;;
  389.                         endHeight -= curHeight;
  390.  
  391.                         ret = diff.x * diff.x * horVoxelSize * horVoxelSize + diff.y * diff.y * horVoxelSize * horVoxelSize + endHeight * endHeight;
  392.  
  393.                 }
  394.         }
  395.  
  396.         return ret;
  397. }
  398.  
  399. bool CFlightNavRegion2::NavData::CreateEightConnected()
  400. {
  401.         uint32 sizeX = width;
  402.         uint32 sizeY = height;
  403.  
  404.         for (uint32 loopX = 0; loopX < sizeX; ++loopX)
  405.         {
  406.                 for (uint32 loopY = 0; loopY < sizeY; ++loopY)
  407.                 {
  408.                         if (IsColumnSet(loopX, loopY))
  409.                         {
  410.                                 NavData::Span* column = &GetColumn(loopX, loopY);
  411.  
  412.                                 while (column)
  413.                                 {
  414.                                         for (uint8 innerloop = 0; innerloop < 8; innerloop += 2)
  415.                                         {
  416.                                                 ConnectDirection(column, loopX, loopY, static_cast<Span::Neighbour>(innerloop));
  417.  
  418.                                                 //const NavData::Span *neigh = &GetNeighbourColumn(loopX, loopY, static_cast<Span::Neighbour>(innerloop));
  419.  
  420.                                                 //if (IsSpanValid(neigh))
  421.                                                 //{
  422.                                                 //      if (spans->neighbours[innerloop][0] == 0)
  423.                                                 //      {
  424.                                                 //              uint32 z = 1;
  425.  
  426.                                                 //              while (neigh && !spans->Overlaps(neigh, 8.0f) )
  427.                                                 //              {
  428.                                                 //                      ++z;
  429.                                                 //                      neigh = neigh->next;
  430.                                                 //              }
  431.  
  432.                                                 //              //lower overlap bound
  433.                                                 //              if (neigh && spans->Overlaps(neigh, 8.0f))
  434.                                                 //              {
  435.                                                 //                      spans->neighbours[innerloop][0] = z;
  436.                                                 //                      neigh = neigh->next;
  437.                                                 //              }
  438.                                                 //              else
  439.                                                 //              {
  440.                                                 //                      continue;
  441.                                                 //              }
  442.  
  443.                                                 //              while (neigh && spans->Overlaps(neigh, 8.0f) )
  444.                                                 //              {
  445.                                                 //                      ++z;
  446.                                                 //                      neigh = neigh->next;
  447.                                                 //              }
  448.  
  449.                                                 //              //upper overlap bound
  450.                                                 //              spans->neighbours[innerloop][1] = z;
  451.                                                 //      }
  452.                                                 //}
  453.                                         }
  454.  
  455.                                         for (uint8 innerloop = 1; innerloop < 8; innerloop += 2)
  456.                                         {
  457.                                                 if (column->neighbours[innerloop - 1][0] && column->neighbours[(innerloop + 1) % 8][0])
  458.                                                 {
  459.                                                         ConnectDirection(column, loopX, loopY, static_cast<Span::Neighbour>(innerloop));
  460.                                                 }
  461.                                         }
  462.  
  463.                                         column = column->next;
  464.                                 }
  465.                         }
  466.                 }
  467.         }
  468.  
  469.         return true;
  470. }
  471.  
  472. void CFlightNavRegion2::NavData::ConnectDirection(NavData::Span* startSpan, uint32 x, uint32 y, Span::Neighbour dir)
  473. {
  474.         uint32 sizeX = width;
  475.         uint32 sizeY = height;
  476.  
  477.         if (startSpan)
  478.         {
  479.                 const NavData::Span* neigh = &GetNeighbourColumn(x, y, static_cast<NavData::Span::Neighbour>(dir));
  480.  
  481.                 if (IsSpanValid(neigh))
  482.                 {
  483.                         if (startSpan->neighbours[dir][0] == 0)
  484.                         {
  485.                                 uint32 z = 1;
  486.  
  487.                                 while (neigh && !startSpan->Overlaps(neigh, 8.0f))
  488.                                 {
  489.                                         ++z;
  490.                                         neigh = neigh->next;
  491.                                 }
  492.  
  493.                                 //lower overlap bound
  494.                                 if (neigh && startSpan->Overlaps(neigh, 8.0f))
  495.                                 {
  496.                                         startSpan->neighbours[dir][0] = z;
  497.                                         neigh = neigh->next;
  498.                                 }
  499.                                 else
  500.                                 {
  501.                                         return;
  502.                                 }
  503.  
  504.                                 while (neigh && startSpan->Overlaps(neigh, 8.0f))
  505.                                 {
  506.                                         ++z;
  507.                                         neigh = neigh->next;
  508.                                 }
  509.  
  510.                                 //upper overlap bound
  511.                                 startSpan->neighbours[dir][1] = z;
  512.                         }
  513.                 }
  514.         }
  515. }
  516.  
  517. // ---------------------------------------------------
  518. // This method expects the path to be in reverse order
  519. // ---------------------------------------------------
  520. void CFlightNavRegion2::NavData::BeautifyPath(const Vec3& _startPos, const Vec3& _endPos, const std::vector<Vec3i>& pathRaw, std::vector<Vec3>& pathOut) const
  521. {
  522.         FRAME_PROFILER("CFlightNavRegion2::NavData::BeautifyPath", gEnv->pSystem, PROFILE_AI);
  523.         float oldTop = -FLT_MAX;
  524.         float oldMin = FLT_MAX;
  525.         Vec3 portalPos(_startPos);
  526.         Vec3 lastDir(ZERO);
  527.  
  528.         Vec3 endTemp = _endPos;
  529.         Vec3 diff = _startPos - _endPos;
  530.         diff.Normalize();
  531.  
  532.         //pathOut.push_back(endTemp);
  533.  
  534.         if (!pathRaw.empty())
  535.         {
  536.                 std::vector<Vec3i>::const_iterator it = pathRaw.begin();
  537.  
  538.                 const Span* span = GetSpan(it->x, it->y, it->z);
  539.  
  540.                 if (span)
  541.                 {
  542.                         Vec3 temp;
  543.                         GetHorCenter(it->x, it->y, temp);
  544.                         temp.z = _endPos.z;
  545.  
  546.                         float tempMin = span->heightMin + basePos.z;
  547.                         float tempMax = span->heightMax + basePos.z;
  548.  
  549.                         temp.z = static_cast<float>(__fsel(_endPos.z - tempMin, temp.z, tempMin));
  550.                         temp.z = static_cast<float>(__fsel(temp.z - tempMax, tempMax, temp.z));
  551.  
  552.                         pathOut.push_back(temp);
  553.                 }
  554.  
  555.                 for (; pathRaw.end() != it; ++it)
  556.                 {
  557.                         std::vector<Vec3i>::const_iterator itP1 = it;
  558.                         ++itP1;
  559.  
  560.                         if (itP1 != pathRaw.end())
  561.                         {
  562.                                 const Vec3i& coordsStart = *it;
  563.                                 const Vec3i& coordsEnd = *itP1;
  564.  
  565.                                 Vec3 centerStart;
  566.                                 GetHorCenter(coordsStart.x, coordsStart.y, centerStart);
  567.  
  568.                                 Vec3 centerEnd;
  569.                                 GetHorCenter(coordsEnd.x, coordsEnd.y, centerEnd);
  570.  
  571.                                 Vec3 dir = centerEnd - centerStart;
  572.                                 dir.z = 0.0f;
  573.                                 dir.Normalize();
  574.  
  575.                                 Vec3 newP = (centerStart + centerEnd) * 0.5f;
  576.                                 newP.z += basePos.z;
  577.                                 float dist = (newP - endTemp).GetLength2D();
  578.  
  579.                                 const Span* spanStart = GetSpan(coordsStart.x, coordsStart.y, coordsStart.z);
  580.                                 const Span* spanEnd = GetSpan(coordsEnd.x, coordsEnd.y, coordsEnd.z);
  581.  
  582.                                 if (IsSpanValid(spanStart) && IsSpanValid(spanEnd))
  583.                                 {
  584.                                         float top, bottom;
  585.                                         if (spanStart->GetPortal(spanEnd, top, bottom, 0.0f))
  586.                                         {
  587.                                                 float dirChange = static_cast<float>(__fsel(lastDir.x * lastDir.x + lastDir.y * lastDir.y + lastDir.z * lastDir.z - 0.5f,
  588.                                                                                             dir.x * lastDir.x + dir.y * lastDir.y + dir.z * lastDir.z, 1.0f));
  589.  
  590.                                                 float tempZ = endTemp.z + dist * diff.z;
  591.                                                 float aboveBelow = static_cast<float>(__fsel(top + basePos.z - tempZ, 0.0f, 1.0f));
  592.                                                 aboveBelow += static_cast<float>(__fsel(tempZ - bottom - basePos.z, 0.0f, 1.0f));
  593.  
  594.                                                 newP.z = static_cast<float>(__fsel(top + basePos.z - tempZ, tempZ, top + basePos.z));
  595.                                                 newP.z = static_cast<float>(__fsel(tempZ - bottom - basePos.z, tempZ, bottom + basePos.z + 1.0f));
  596.  
  597.                                                 if (dirChange < 0.9f || aboveBelow > 0.5f)
  598.                                                 {
  599.                                                         if (dirChange < 0.9f)
  600.                                                         {
  601.                                                                 centerStart.z = newP.z;
  602.                                                                 AddPathPoint(pathOut, centerStart);
  603.                                                         }
  604.  
  605.                                                         AddPathPoint(pathOut, newP);
  606.  
  607.                                                         endTemp = newP;
  608.  
  609.                                                         diff = _startPos - endTemp;
  610.                                                         diff.Normalize();
  611.                                                 }
  612.  
  613.                                                 lastDir = dir;
  614.                                         }
  615.                                 }
  616.                         }
  617.                 }
  618.  
  619.                 AddPathPoint(pathOut, _startPos);
  620.         }
  621. }
  622.  
  623. void CFlightNavRegion2::NavData::AddPathPoint(std::vector<Vec3>& pathOut, const Vec3& newPoint) const
  624. {
  625.         if (pathOut.size() > 1)
  626.         {
  627.                 Vec3& last = pathOut.back();
  628.                 const Vec3& penUltimate = *(&last - 1);
  629.  
  630.                 Vec3 newSeg = newPoint - last;
  631.                 Vec3 oldSeg = last - penUltimate;
  632.  
  633.                 newSeg.z = 0.0f;
  634.                 oldSeg.z = 0.0f;
  635.  
  636.                 float newSegLen = newSeg.len();
  637.                 float oldSegLen = oldSeg.len();
  638.  
  639.                 newSeg /= newSegLen;
  640.                 oldSeg /= oldSegLen;
  641.  
  642.                 if (oldSeg.dot(newSeg) < 0.5f)
  643.                 {
  644.                         Vec3 tempDiff = (newSeg - oldSeg);
  645.                         tempDiff.Normalize();
  646.  
  647.                         Vec3 buffer = last;
  648.                         last -= oldSeg * (oldSegLen * 0.5f);
  649.  
  650.                         //buffer += tempDiff * 15.0f;
  651.                         pathOut.push_back(buffer + tempDiff * 5.0f);
  652.  
  653.                         pathOut.push_back(buffer + newSeg * (newSegLen * 0.5f));
  654.                 }
  655.         }
  656.  
  657.         pathOut.push_back(newPoint);
  658. }
  659.  
  660. void CFlightNavRegion2::NavData::GetRandomSpan(Vec3i& spanCoord, Vec3& center) const
  661. {
  662.         uint32 gridCell = 0;
  663.  
  664.         while (!gridCell)
  665.         {
  666.                 uint32 testX = cry_random(0U, width - 1);
  667.                 uint32 testY = cry_random(0U, height - 1);
  668.  
  669.                 gridCell = GetGridCell(testX, testY);
  670.  
  671.                 if (gridCell > 0)
  672.                 {
  673.                         const Span* span = &spans[gridCell];
  674.  
  675.                         spanCoord.z = 0;
  676.  
  677.                         if (span->next && cry_random(0, 99) > 49)
  678.                         {
  679.                                 span = span->next;
  680.                                 spanCoord.z = 1;
  681.                         }
  682.  
  683.                         spanCoord.x = testX;
  684.                         spanCoord.y = testY;
  685.  
  686.                         GetHorCenter(testX, testY, center);
  687.  
  688.                         float minH = span->heightMin;
  689.                         float maxH = span->heightMax;
  690.                         float diff = maxH - minH;
  691.  
  692.                         float h = minH + diff * clamp_tpl(cry_random(0.0f, 1.0f), 0.2f, 0.8f);
  693.  
  694.                         center.z = basePos.z + h;
  695.                 }
  696.         }
  697. }
  698.  
  699. void CFlightNavRegion2::NavData::GetClosestSpan(const Vec3& pos, Vec3i& spanCoord, Vec3& center) const
  700. {
  701.         GetGridOffset(pos, spanCoord);
  702.  
  703.         Limit(spanCoord.x, 0, (int)width);
  704.         Limit(spanCoord.y, 0, (int)height);
  705.  
  706.         uint32 offsetX = spanCoord.x;
  707.         uint32 offsetY = spanCoord.y;
  708.  
  709.         uint32 mindist = 10000000;
  710.  
  711.         uint32 gridCell = 0;
  712.  
  713.         for (int32 x = 0; x < (int32)width; ++x)
  714.         {
  715.                 for (int32 y = 0; y < (int32)height; ++y)
  716.                 {
  717.                         if (GetGridCell(x, y))
  718.                         {
  719.                                 uint32 dist = (x - spanCoord.x) * (x - spanCoord.x) + (y - spanCoord.y) * (y - spanCoord.y);
  720.  
  721.                                 if (dist < mindist)
  722.                                 {
  723.                                         mindist = dist;
  724.                                         offsetX = x;
  725.                                         offsetY = y;
  726.                                 }
  727.                         }
  728.                 }
  729.         }
  730.  
  731.         if (gridCell = GetGridCell(offsetX, offsetY))
  732.         {
  733.                 const Span* span = GetSpan(offsetX, offsetY, 0);
  734.  
  735.                 int32 offsetZ = 0;
  736.  
  737.                 spanCoord.x = offsetX;
  738.                 spanCoord.y = offsetY;
  739.                 spanCoord.z = 0;
  740.  
  741.                 while (span)
  742.                 {
  743.                         float z = pos.z - basePos.z;
  744.  
  745.                         if (!(span->heightMin > z) && !(span->heightMax < z))
  746.                         {
  747.                                 spanCoord.z = offsetZ;
  748.                         }
  749.  
  750.                         span = span->next;
  751.                 }
  752.  
  753.                 span = GetSpan(spanCoord.x, spanCoord.y, spanCoord.z);
  754.                 GetHorCenter(offsetX, offsetY, center);
  755.  
  756.                 center.z = static_cast<float>(__fsel(span->heightMin + basePos.z - pos.z, span->heightMin + basePos.z, pos.z));
  757.                 center.z = static_cast<float>(__fsel(span->heightMax + basePos.z - center.z, center.z, span->heightMax + basePos.z));
  758.         }
  759. }
  760.  
  761. void CFlightNavRegion2::NavData::GetSpansAlongLine(const Vec3& startPos, const Vec3& endPos, std::vector<Vec3i>& spanCoords) const
  762. {
  763.         Vec3i spanCoordStart;
  764.         GetGridOffset(startPos, spanCoordStart);
  765.  
  766.         Vec3i spanCoordEnd;
  767.         GetGridOffset(endPos, spanCoordEnd);
  768.  
  769.         Limit(spanCoordStart.x, 0, (int)width);
  770.         Limit(spanCoordStart.y, 0, (int)height);
  771.         Limit(spanCoordEnd.x, 0, (int)width);
  772.         Limit(spanCoordEnd.y, 0, (int)height);
  773.  
  774.         uint32 offsetX = spanCoordStart.x;
  775.         uint32 offsetY = spanCoordStart.y;
  776.         uint32 mindist = 10000000;
  777.         uint32 gridCell = 0;
  778.  
  779.         // now breesenham along the direction
  780.         int dx = spanCoordEnd.x - spanCoordStart.x;
  781.         int dy = spanCoordEnd.y - spanCoordStart.y;
  782.  
  783.         int incx = (dx > 0) ? 1 : (dx < 0) ? -1 : 0;
  784.         int incy = (dy > 0) ? 1 : (dy < 0) ? -1 : 0;
  785.  
  786.         if (0 > dx)
  787.         {
  788.                 dx = -dx;
  789.         }
  790.  
  791.         if (0 > dy)
  792.         {
  793.                 dy = -dy;
  794.         }
  795.  
  796.         int pdx, pdy, ddx, ddy, es, el;
  797.         if (dx > dy)
  798.         {
  799.                 pdx = incx;
  800.                 pdy = 0;
  801.                 ddx = incx;
  802.                 ddy = incy;
  803.                 es = dy;
  804.                 el = dx;
  805.         }
  806.         else
  807.         {
  808.                 pdx = 0;
  809.                 pdy = incy;
  810.                 ddx = incx;
  811.                 ddy = incy;
  812.                 es = dx;
  813.                 el = dy;
  814.         }
  815.  
  816.         int x = spanCoordStart.x;
  817.         int y = spanCoordStart.y;
  818.         int err = el / 2;
  819.  
  820.         if (GetGridCell(x, y))
  821.         {
  822.                 int doit1 = 1;
  823.                 Vec3i temp(x, y, 0);
  824.                 spanCoords.push_back(temp);
  825.         }
  826.  
  827.         for (int t = 0; t < el; ++t)
  828.         {
  829.                 err -= es;
  830.                 if (0 > err)
  831.                 {
  832.                         err += el;
  833.  
  834.                         x += ddx;
  835.                         y += ddy;
  836.                 }
  837.                 else
  838.                 {
  839.                         x += pdx;
  840.                         y += pdy;
  841.                 }
  842.  
  843.                 if (GetGridCell(x, y))
  844.                 {
  845.                         int doit = 0;
  846.                         Vec3i temp(x, y, 0);
  847.                         spanCoords.push_back(temp);
  848.                 }
  849.         }
  850. }
  851.  
  852. int CFlightNavRegion2::m_DebugDraw;
  853.  
  854. void CFlightNavRegion2::InitCVars()
  855. {
  856.         REGISTER_CVAR2("ai_DebugDrawFlight2", &m_DebugDraw, 0, VF_CHEAT | VF_CHEAT_NOCHECK, "Set AI features to behave in earlier milestones - please use sparingly");
  857. }
  858.  
  859. CFlightNavRegion2::CFlightNavRegion2(IPhysicalWorld* pPhysWorld, CGraph* pGraph)
  860.         : m_pPhysWorld(pPhysWorld)
  861.         , m_pGraph(pGraph)
  862. {
  863. }
  864.  
  865. CFlightNavRegion2::~CFlightNavRegion2()
  866. {
  867.         Clear();
  868. }
  869.  
  870. void CFlightNavRegion2::Clear()
  871. {
  872.         for (std::vector<NavData*>::iterator it = m_FlightNavData.begin(); m_FlightNavData.end() != it; ++it)
  873.         {
  874.                 if (*it)
  875.                 {
  876.                         delete *it;
  877.                 }
  878.         }
  879.  
  880.         m_FlightNavData.clear();
  881. }
  882.  
  883. // temp, will be removed soon
  884. const float with = 2.0f;
  885. const float factor = 5.0f;
  886.  
  887. //void CFlightNavRegion2::Process(I3DEngine* p3DEngine, const std::list<SpecialArea*>& flightAreas)
  888. //{
  889. //}
  890.  
  891. bool CFlightNavRegion2::ReadFromFile(const char* pName)
  892. {
  893.         Clear();
  894.  
  895.         CCryFile file;
  896.         if (!file.Open(pName, "rb"))
  897.         {
  898.                 AIWarning("could not load AI flight nav. [%s]", pName);
  899.                 return false;
  900.         }
  901.  
  902.         int nFileVersion;
  903.         file.ReadType(&nFileVersion, 1);
  904.  
  905.         if (BAI_FNAV2_FILE_VERSION_WRITE != nFileVersion)
  906.         {
  907.                 AIWarning("unsupported file version for Flight V2.0. [%s]", pName);
  908.                 return false;
  909.         }
  910.  
  911.         uint32 countModifier;
  912.         file.ReadType(&countModifier, 1);
  913.  
  914.         uint32 width, height;
  915.  
  916.         for (uint32 loop = 0; loop < countModifier; ++loop)
  917.         {
  918.                 file.ReadType(&width, 1);
  919.                 file.ReadType(&height, 1);
  920.  
  921.                 Vec3 basePos;
  922.                 file.ReadType(&basePos, 1);
  923.                 float horVoxelSize, agentHeight;
  924.                 file.ReadType(&horVoxelSize, 1);
  925.                 file.ReadType(&agentHeight, 1);
  926.  
  927.                 uint32 spanCount;
  928.                 file.ReadType(&spanCount, 1);
  929.  
  930.                 if (0 < spanCount)
  931.                 {
  932.                         std::vector<SpanDesc> readBuffer;
  933.                         readBuffer.resize(spanCount);
  934.  
  935.                         file.ReadType(&readBuffer[0], spanCount);
  936.  
  937.                         m_FlightNavData.push_back(new NavData(width, height, spanCount));
  938.                         NavData& data = *m_FlightNavData.back();
  939.                         //data.spans = new LayeredNavMesh::SpanBuffer(0, 0);
  940.  
  941.                         data.horVoxelSize = horVoxelSize;
  942.                         data.agentHeight = agentHeight;
  943.                         data.basePos = basePos;
  944.  
  945.                         for (uint32 innerLoop = 0; innerLoop < spanCount; ++innerLoop)
  946.                         {
  947.                                 SpanDesc& desc = readBuffer[innerLoop];
  948.                                 //data.spans->AddSpan(desc.x, desc.y, desc/*.span*/.smin, desc/*.span*/.smax, 0);
  949.                                 data.AddSpan(desc.x, desc.y, static_cast<float>(desc.smin), static_cast<float>(desc.smax));
  950.                         }
  951.  
  952.                         data.CreateEightConnected();
  953.                 }
  954.         }
  955.  
  956.         return true; //CreateEightConnected();
  957. }
  958.  
  959. unsigned CFlightNavRegion2::GetEnclosing(int x, int y, const Vec3& pos, Vec3* closestValid, Vec3* spanPos)
  960. {
  961.         // that's easy :-) and not strictly needed here
  962.  
  963.         return 0;
  964. }
  965.  
  966. //Todo: make it really handle multiple regions
  967. const CFlightNavRegion2::NavData* CFlightNavRegion2::GetEnclosing(const Vec3& pos, Vec3i& spanPos, Vec3* outPos) const
  968. {
  969.         /*bool ret = false;*/
  970.  
  971.         int32 offX = 0;
  972.         int32 offY = 0;
  973.         int32 offZ = 0;
  974.  
  975.         for (std::vector<NavData*>::const_iterator it = m_FlightNavData.begin(); m_FlightNavData.end() != it; ++it)
  976.         {
  977.                 Vec3 diff = pos - (*it)->basePos;
  978.                 float horVoxelSize = (*it)->horVoxelSize;
  979.  
  980.                 offX = static_cast<int>(diff.x / horVoxelSize);
  981.                 offY = static_cast<int>(diff.y / horVoxelSize);
  982.  
  983.                 if (offX < 0 || (uint32)offX > (*it)->width || offY < 0 || (uint32)offY > (*it)->height)
  984.                 {
  985.                         continue;
  986.                 }
  987.  
  988.                 const NavData::Span* span = &(*it)->GetColumn(offX, offY);
  989.                 if ((*it)->IsSpanValid(span))
  990.                 {
  991.                         offZ = 0;
  992.                         while (span)
  993.                         {
  994.                                 if (span->Overlaps(diff))
  995.                                 {
  996.                                         spanPos.x = offX;
  997.                                         spanPos.y = offY;
  998.                                         spanPos.z = offZ;
  999.  
  1000.                                         //ret = true;
  1001.  
  1002.                                         return *(it);
  1003.                                         //break;
  1004.                                 }
  1005.  
  1006.                                 ++offZ;
  1007.                                 span = span->next;
  1008.                         }
  1009.  
  1010.                         break;
  1011.                 }
  1012.         }
  1013.  
  1014.         return 0;
  1015. }
  1016.  
  1017. void CFlightNavRegion2::DrawPath(const std::vector<Vec3>& path)
  1018. {
  1019.         if (path.size() > 1)
  1020.         {
  1021.                 std::vector<Vec3>::const_iterator segmentStart = path.begin();
  1022.                 std::vector<Vec3>::const_iterator segmentEnd = path.begin() + 1;
  1023.                 ColorB c(255, 0, 0);
  1024.  
  1025.                 SDrawTextInfo ti;
  1026.                 ti.color[0] = ti.color[1] = ti.color[2] = ti.color[3] = 1.0f;
  1027.                 ti.flags = eDrawText_Center;
  1028.                 ti.scale = Vec2(8.0f);
  1029.  
  1030.                 uint32 num = path.size();
  1031.                 char buffer[16];
  1032.                 cry_sprintf(buffer, "%d", --num);
  1033.                 IRenderAuxText::DrawLabel(*segmentStart, 2.0f, buffer);
  1034.  
  1035.                 for (; path.end() != segmentEnd; ++segmentEnd, ++segmentStart)
  1036.                 {
  1037.                         gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(*segmentStart, c, *segmentEnd, c, 20.0f);
  1038.  
  1039.                         cry_sprintf(buffer, "%d", --num);
  1040.                         IRenderAuxText::DrawLabel(*segmentEnd, 2.0f, buffer);
  1041.                 }
  1042.         }
  1043. }
  1044.  
  1045. void CFlightNavRegion2::DebugDraw() const
  1046. {
  1047.         ColorB col(255, 255, 255, 128);
  1048.         ColorB colw(255, 255, 255, 255);
  1049.         ColorB colg(0, 255, 0, 255);
  1050.         ColorB colSpan(0, 0, 255, 255);
  1051.         ColorB colSpanStart(0, 255, 0, 255);
  1052.         ColorB colSpanEnd(255, 0, 0, 255);
  1053.  
  1054.         IEntity* debugEntStart = gEnv->pEntitySystem->FindEntityByName("DebugFlightStart");
  1055.         IEntity* debugEntEnd = gEnv->pEntitySystem->FindEntityByName("DebugFlightEnd");
  1056.  
  1057.         Vec3i spanStart, spanEnd;
  1058.         bool drawStart = false;
  1059.         bool drawEnd = false;
  1060.  
  1061.         if (debugEntStart)
  1062.         {
  1063.                 drawStart = GetEnclosing(debugEntStart->GetPos(), spanStart) != 0;
  1064.         }
  1065.  
  1066.         if (debugEntEnd)
  1067.         {
  1068.                 drawEnd = GetEnclosing(debugEntEnd->GetPos(), spanEnd) != 0;
  1069.         }
  1070.  
  1071.         static std::vector<Vec3i> path;
  1072.         static std::vector<Vec3> pathSmooth;
  1073.         if (drawStart && drawEnd && path.empty())
  1074.         {
  1075.                 path.clear();
  1076.                 pathSmooth.clear();
  1077.  
  1078.                 astar.StartPathFind(*m_FlightNavData.begin(), *m_FlightNavData.begin(), *m_FlightNavData.begin(), debugEntStart->GetPos(), debugEntEnd->GetPos());
  1079.                 astar.Update(2000);
  1080.  
  1081.                 astar.GetPathReversed(path);
  1082.  
  1083.                 Vec3i span;
  1084.                 const NavData* graph = GetEnclosing(debugEntStart->GetPos(), span);
  1085.  
  1086.                 if (graph)
  1087.                 {
  1088.                         graph->BeautifyPath(debugEntStart->GetPos(), debugEntEnd->GetPos(), path, pathSmooth);
  1089.                 }
  1090.         }
  1091.         else if (!drawStart || !drawEnd)
  1092.         {
  1093.                 path.clear();
  1094.         }
  1095.  
  1096.         switch (m_DebugDraw)
  1097.         {
  1098.  
  1099.         case DRAWCONNECTTIONS:
  1100.                 {
  1101.                         for (std::vector<NavData*>::const_iterator it = m_FlightNavData.begin(); m_FlightNavData.end() != it; ++it)
  1102.                         {
  1103.                                 uint32 count = 0;
  1104.                                 Vec3 basePos = (*it)->basePos;
  1105.  
  1106.                                 uint32 sizeX = (*it)->width;
  1107.                                 uint32 sizeZ = (*it)->height;
  1108.  
  1109.                                 float horSize = (*it)->horVoxelSize;
  1110.  
  1111.                                 const NavData& data = *(*it);
  1112.  
  1113.                                 for (uint32 loopX = 0; loopX < sizeX; ++loopX)
  1114.                                 {
  1115.                                         for (uint32 loopZ = 0; loopZ < sizeZ; ++loopZ)
  1116.                                         {
  1117.                                                 colSpan.a = 128;
  1118.                                                 if (data.IsColumnSet(loopX, loopZ))
  1119.                                                 {
  1120.                                                         const NavData::Span* span = &data.GetColumn(loopX, loopZ);
  1121.  
  1122.                                                         while (span)
  1123.                                                         {
  1124.                                                                 Vec3 offset(loopX * horSize, loopZ * horSize, (span->heightMin + span->heightMax) * 0.5f);
  1125.  
  1126.                                                                 for (uint8 innerloop = 0; innerloop < 8; innerloop += 2)
  1127.                                                                 {
  1128.                                                                         if (span->neighbours[innerloop][0] != 0)
  1129.                                                                         {
  1130.                                                                                 Vec3 start = basePos + offset;
  1131.                                                                                 //Vec3 end = start + (offsets[innerloop][0] * Vec3(7.5f, 0.0f, 0.0f)) + (offsets[innerloop][1] * Vec3(0.0f, 7.5f, 0.0f));
  1132.  
  1133.                                                                                 uint32 x = loopX + offsets[innerloop][0];
  1134.                                                                                 uint32 y = loopZ + offsets[innerloop][1];
  1135.  
  1136.                                                                                 Vec3 end, end2;
  1137.                                                                                 data.GetHorCenter(x, y, end);
  1138.                                                                                 end2 = end;
  1139.  
  1140.                                                                                 const NavData::Span* spanFirst = data.GetSpan(x, y, span->neighbours[innerloop][0] - 1);
  1141.                                                                                 const NavData::Span* spanLast = data.GetSpan(x, y, span->neighbours[innerloop][1] - 1);
  1142.  
  1143.                                                                                 end.z = basePos.z + (spanFirst->heightMin + spanFirst->heightMax) * 0.5f;
  1144.                                                                                 //                                                                              gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(start, colg, end, colw, 2.0f);
  1145.  
  1146.                                                                                 end2.z = basePos.z + (spanLast->heightMin + spanLast->heightMax) * 0.5f;
  1147.                                                                                 //gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(start, colg, end, colw, 2.0f);
  1148.  
  1149.                                                                                 gEnv->pRenderer->GetIRenderAuxGeom()->DrawTriangle(start, colg, end, colw, end2, colw);
  1150.                                                                         }
  1151.                                                                 }
  1152.  
  1153.                                                                 span = span->next;
  1154.                                                         }
  1155.                                                 }
  1156.                                         }
  1157.                                 }
  1158.                         }
  1159.                 }
  1160.  
  1161.         case DRAWPATH:
  1162.                 {
  1163.                         for (std::vector<NavData*>::const_iterator it = m_FlightNavData.begin(); m_FlightNavData.end() != it; ++it)
  1164.                         {
  1165.                                 Vec3 basePos = (*it)->basePos;
  1166.                                 float horSize = (*it)->horVoxelSize;
  1167.  
  1168.                                 if (!path.empty())
  1169.                                         for (std::vector<Vec3i>::const_iterator coords = path.begin() + 1; path.end() != coords; ++coords)
  1170.                                         {
  1171.                                                 const Vec3i& coord = *coords;
  1172.                                                 const NavData::Span* span = (*it)->GetSpan(coord.x, coord.y, coord.z);
  1173.  
  1174.                                                 if (span)
  1175.                                                 {
  1176.                                                         Vec3 offset(coord.x * horSize, coord.y * horSize, span->heightMin);
  1177.                                                         Vec3 offset2((coord.x + 1) * horSize, (coord.y + 1) * horSize, span->heightMax);
  1178.  
  1179.                                                         gEnv->pRenderer->GetIRenderAuxGeom()->DrawAABB(AABB(basePos + offset, basePos + offset2), true, colw, eBBD_Faceted);
  1180.  
  1181.                                                         //spanStart = span;
  1182.                                                 }
  1183.                                                 else
  1184.                                                 {
  1185.                                                         break;
  1186.                                                 }
  1187.                                         }
  1188.                         }
  1189.  
  1190.                         DrawPath(pathSmooth);
  1191.                 }
  1192.                 break;
  1193.  
  1194.         case DRAWPORTALS:
  1195.                 for (std::vector<NavData*>::const_iterator it = m_FlightNavData.begin(); m_FlightNavData.end() != it; ++it)
  1196.                 {
  1197.                         Vec3 basePos = (*it)->basePos;
  1198.                         float horSize = (*it)->horVoxelSize;
  1199.  
  1200.                         ColorB colwA(255, 255, 255, 128);
  1201.                         ColorB colPortal(0, 0, 255, 128);
  1202.  
  1203.                         if (!path.empty())
  1204.                                 for (std::vector<Vec3i>::const_iterator coords = path.begin() + 1; path.end() != coords; ++coords)
  1205.                                 {
  1206.                                         const Vec3i& coord = *coords;
  1207.                                         const NavData::Span* span = (*it)->GetSpan(coord.x, coord.y, coord.z);
  1208.  
  1209.                                         if (span)
  1210.                                         {
  1211.                                                 Vec3 offset(coord.x * horSize, coord.y * horSize, span->heightMin);
  1212.                                                 Vec3 offset2((coord.x + 1) * horSize, (coord.y + 1) * horSize, span->heightMax);
  1213.  
  1214.                                                 gEnv->pRenderer->GetIRenderAuxGeom()->DrawAABB(AABB(basePos + offset, basePos + offset2), true, colwA, eBBD_Faceted);
  1215.  
  1216.                                                 Vec3 center = basePos + (offset + offset2) * 0.5f;
  1217.  
  1218.                                                 SDrawTextInfo ti;
  1219.                                                 ti.color[0] = ti.color[1] = 0.0f;
  1220.                                                 ti.color[2] = ti.color[3] = 1.0f;
  1221.                                                 ti.flags = eDrawText_Center;
  1222.                                                 ti.scale = Vec2(8.0f);
  1223.  
  1224.                                                 uint32 num = path.size();
  1225.                                                 char buffer[16];
  1226.                                                 cry_sprintf(buffer, "(%d, %d, %d)", coord.x, coord.y, coord.z);
  1227.                                                 IRenderAuxText::DrawLabel(center, 2.0f, buffer);
  1228.  
  1229.                                                 std::vector<Vec3i>::const_iterator coordsNext = coords + 1;
  1230.  
  1231.                                                 if (coordsNext != path.end())
  1232.                                                 {
  1233.                                                         const Vec3i& coordNext = *coordsNext;
  1234.                                                         const NavData::Span* otherSpan = (*it)->GetSpan(coordNext.x, coordNext.y, coordNext.z);
  1235.  
  1236.                                                         float top, bottom;
  1237.                                                         span->GetPortal(otherSpan, top, bottom, 0.0f);
  1238.  
  1239.                                                         if (coordNext.x == coord.x || coordNext.y == coords->y)
  1240.                                                         {
  1241.                                                                 Vec3i diff = coordNext - coord;
  1242.  
  1243.                                                                 diff.x = (diff.x < 0) ? 0 : diff.x;
  1244.                                                                 diff.y = (diff.y < 0) ? 0 : diff.y;
  1245.  
  1246.                                                                 if (coordNext.x == coord.x)
  1247.                                                                 {
  1248.                                                                         Vec3 offsetA(coord.x * horSize, (coord.y + diff.y) * horSize, bottom);
  1249.                                                                         Vec3 offsetB(coord.x * horSize, (coord.y + diff.y) * horSize, top);
  1250.                                                                         Vec3 offsetC((coord.x + 1) * horSize, (coord.y + diff.y) * horSize, bottom);
  1251.                                                                         Vec3 offsetD((coord.x + 1) * horSize, (coord.y + diff.y) * horSize, top);
  1252.  
  1253.                                                                         SAuxGeomRenderFlags flags = gEnv->pRenderer->GetIRenderAuxGeom()->GetRenderFlags();
  1254.                                                                         SAuxGeomRenderFlags newflags(flags);
  1255.                                                                         newflags.SetCullMode(e_CullModeNone);
  1256.                                                                         gEnv->pRenderer->GetIRenderAuxGeom()->SetRenderFlags(newflags);
  1257.                                                                         gEnv->pRenderer->GetIRenderAuxGeom()->DrawTriangle(offsetA + basePos, colPortal,
  1258.                                                                                                                            offsetB + basePos, colPortal,
  1259.                                                                                                                            offsetC + basePos, colPortal);
  1260.                                                                         gEnv->pRenderer->GetIRenderAuxGeom()->DrawTriangle(offsetB + basePos, colPortal,
  1261.                                                                                                                            offsetD + basePos, colPortal,
  1262.                                                                                                                            offsetC + basePos, colPortal);
  1263.  
  1264.                                                                         gEnv->pRenderer->GetIRenderAuxGeom()->SetRenderFlags(flags);
  1265.  
  1266.                                                                 }
  1267.                                                                 else
  1268.                                                                 {
  1269.                                                                         SAuxGeomRenderFlags flags = gEnv->pRenderer->GetIRenderAuxGeom()->GetRenderFlags();
  1270.                                                                         SAuxGeomRenderFlags newflags(flags);
  1271.                                                                         newflags.SetCullMode(e_CullModeNone);
  1272.                                                                         gEnv->pRenderer->GetIRenderAuxGeom()->SetRenderFlags(newflags);
  1273.  
  1274.                                                                         Vec3 offsetA((coord.x + diff.x) * horSize, coord.y * horSize, bottom);
  1275.                                                                         Vec3 offsetB((coord.x + diff.x) * horSize, coord.y * horSize, top);
  1276.                                                                         Vec3 offsetC((coord.x + diff.x) * horSize, (coord.y + 1) * horSize, bottom);
  1277.                                                                         Vec3 offsetD((coord.x + diff.x) * horSize, (coord.y + 1) * horSize, top);
  1278.  
  1279.                                                                         gEnv->pRenderer->GetIRenderAuxGeom()->DrawTriangle(offsetA + basePos, colPortal,
  1280.                                                                                                                            offsetB + basePos, colPortal,
  1281.                                                                                                                            offsetC + basePos, colPortal);
  1282.  
  1283.                                                                         gEnv->pRenderer->GetIRenderAuxGeom()->DrawTriangle(offsetB + basePos, colPortal,
  1284.                                                                                                                            offsetD + basePos, colPortal,
  1285.                                                                                                                            offsetC + basePos, colPortal);
  1286.                                                                         gEnv->pRenderer->GetIRenderAuxGeom()->SetRenderFlags(flags);
  1287.                                                                 }
  1288.                                                         }
  1289.                                                         else
  1290.                                                         {
  1291.                                                                 Vec3i diff = coordNext - coord;
  1292.                                                                 Vec3 offset3((coord.x + 0.5f + 0.5f * diff.x) * horSize, (coord.y + 0.5f + 0.5f * diff.y) * horSize, span->heightMax);
  1293.  
  1294.                                                                 Vec3 start = offset3 + basePos;
  1295.                                                                 Vec3 end = offset3 + basePos;
  1296.  
  1297.                                                                 start.z = basePos.z + bottom;
  1298.                                                                 end.z = basePos.z + top;
  1299.                                                                 gEnv->pRenderer->GetIRenderAuxGeom()->DrawLine(start, colPortal, end, colPortal, 20.0f);
  1300.                                                         }
  1301.                                                 }
  1302.                                         }
  1303.                                         else
  1304.                                         {
  1305.                                                 break;
  1306.                                         }
  1307.                                 }
  1308.  
  1309.                         DrawPath(pathSmooth);
  1310.                 }
  1311.  
  1312.                 break;
  1313.  
  1314.         case DRAWNAVDATA:
  1315.                 {
  1316.                         for (std::vector<NavData*>::const_iterator it = m_FlightNavData.begin(); m_FlightNavData.end() != it; ++it)
  1317.                         {
  1318.                                 uint32 count = 0;
  1319.                                 Vec3 basePos = (*it)->basePos;
  1320.  
  1321.                                 uint32 sizeX = (*it)->width;
  1322.                                 uint32 sizeZ = (*it)->height;
  1323.  
  1324.                                 float horSize = (*it)->horVoxelSize;
  1325.  
  1326.                                 const NavData& data = *(*it);
  1327.  
  1328.                                 for (uint32 loopX = 0; loopX < sizeX; ++loopX)
  1329.                                 {
  1330.                                         for (uint32 loopZ = 0; loopZ < sizeZ; ++loopZ)
  1331.                                         {
  1332.                                                 if (data.IsColumnSet(loopX, loopZ))
  1333.                                                 {
  1334.                                                         const NavData::Span* span = &data.GetColumn(loopX, loopZ);
  1335.  
  1336.                                                         uint32 zOffset = 0;
  1337.                                                         while (span)
  1338.                                                         {
  1339.                                                                 ++count;
  1340.                                                                 Vec3 offset(loopX * horSize, loopZ * horSize, span->heightMin);
  1341.                                                                 Vec3 offset2((loopX + 1) * horSize, (loopZ + 1) * horSize, span->heightMax);
  1342.  
  1343.                                                                 bool startSpan = drawStart && (loopX == spanStart.x) && (loopZ == spanStart.y) && (zOffset == spanStart.z);
  1344.                                                                 bool endSpan = drawEnd && (loopX == spanEnd.x) && (loopZ == spanEnd.y) && (zOffset == spanEnd.z);
  1345.  
  1346.                                                                 ColorB colour = colSpan;
  1347.  
  1348.                                                                 if (startSpan)
  1349.                                                                 {
  1350.                                                                         colour = colSpanStart;
  1351.                                                                 }
  1352.                                                                 else if (endSpan)
  1353.                                                                 {
  1354.                                                                         colour = colSpanEnd;
  1355.                                                                 }
  1356.                                                                 else if (drawStart || drawEnd)
  1357.                                                                 {
  1358.                                                                         colour.a = 128;
  1359.                                                                 }
  1360.  
  1361.                                                                 gEnv->pRenderer->GetIRenderAuxGeom()->DrawAABB(AABB(basePos + offset, basePos + offset2), true, colour, eBBD_Faceted);
  1362.  
  1363.                                                                 ++zOffset;
  1364.                                                                 span = span->next;
  1365.                                                         }
  1366.                                                 }
  1367.                                         }
  1368.                                 }
  1369.  
  1370.                                 int m = 0;
  1371.                         }
  1372.  
  1373.                         //gEnv->pRenderer->GetIRenderAuxGeom()->DrawAABB (boundingBox, false, colw, eBBD_Faceted);
  1374.                 }
  1375.                 break;
  1376.  
  1377.         }
  1378. }
  1379.  
  1380. //====================================================================
  1381. // Serialize
  1382. //====================================================================
  1383. void CFlightNavRegion2::Serialize(TSerialize ser)
  1384. {
  1385.         ser.BeginGroup("FlightNavRegion");
  1386.  
  1387.         ser.EndGroup();
  1388. }
  1389.  
downloadFlightNavRegion2.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