BVB Source Codes

CRYENGINE Show MNM.h Source code

Return Download CRYENGINE: download MNM.h Source code - Download CRYENGINE Source code - Type:.h
  1. // Copyright 2001-2016 Crytek GmbH / Crytek Group. All rights reserved.
  2.  
  3. #ifndef __MNM_H
  4. #define __MNM_H
  5.  
  6. #pragma once
  7.  
  8. #include <CryAISystem/IMNM.h>
  9. #include <CryAISystem/NavigationSystem/MNMTile.h>
  10. #include "MNM_Type_info.h"
  11. #include "OpenList.h"
  12.  
  13. #if !defined(_RELEASE) && CRY_PLATFORM_WINDOWS
  14.         #define DEBUG_MNM_ENABLED 1
  15. #else
  16.         #define DEBUG_MNM_ENABLED 0
  17. #endif
  18.  
  19. // If you want to debug the data consistency just set this define to 1
  20. #define DEBUG_MNM_DATA_CONSISTENCY_ENABLED 0
  21.  
  22. // Log additional information about OffMesh link operation (add, remove, ...)
  23. #define DEBUG_MNM_LOG_OFFMESH_LINK_OPERATIONS 0
  24.  
  25. #if CRY_PLATFORM_WINDOWS
  26.         #define MNM_USE_EXPORT_INFORMATION 1
  27. #else
  28.         #define MNM_USE_EXPORT_INFORMATION 0
  29. #endif
  30.  
  31. namespace MNM
  32. {
  33.  
  34. struct WayTriangleData
  35. {
  36.         WayTriangleData()
  37.                 : triangleID(0)
  38.                 , offMeshLinkID(0)
  39.                 , costMultiplier(1.0f)
  40.                 , incidentEdge((unsigned int)MNM::Constants::InvalidEdgeIndex)
  41.         {
  42.  
  43.         }
  44.  
  45.         WayTriangleData(const TriangleID _triangleID, const OffMeshLinkID _offMeshLinkID)
  46.                 : triangleID(_triangleID)
  47.                 , offMeshLinkID(_offMeshLinkID)
  48.                 , costMultiplier(1.f)
  49.                 , incidentEdge((unsigned int)MNM::Constants::InvalidEdgeIndex)
  50.         {
  51.  
  52.         }
  53.  
  54.         operator bool() const
  55.         {
  56.                 return (triangleID != 0);
  57.         }
  58.  
  59.         bool operator<(const WayTriangleData& other) const
  60.         {
  61.                 return triangleID == other.triangleID ? offMeshLinkID < other.offMeshLinkID : triangleID < other.triangleID;
  62.         }
  63.  
  64.         bool operator==(const WayTriangleData& other) const
  65.         {
  66.                 return ((triangleID == other.triangleID) && (offMeshLinkID == other.offMeshLinkID));
  67.         }
  68.  
  69.         TriangleID    triangleID;
  70.         OffMeshLinkID offMeshLinkID;
  71.         float         costMultiplier;
  72.         unsigned int  incidentEdge;
  73. };
  74.  
  75. inline bool IsTriangleAlreadyInWay(const TriangleID triangleID, const TriangleID* const way, const size_t wayTriCount)
  76. {
  77.         assert(way);
  78.         return std::find(way, way + wayTriCount, triangleID) != (way + wayTriCount);
  79. }
  80.  
  81. struct AStarContention
  82. {
  83.         void SetFrameTimeQuota(float frameTimeQuota)
  84.         {
  85.                 m_frameTimeQuota.SetSeconds(frameTimeQuota);
  86.         }
  87.  
  88.         struct ContentionStats
  89.         {
  90.                 float  frameTimeQuota;
  91.  
  92.                 uint32 averageSearchSteps;
  93.                 uint32 peakSearchSteps;
  94.  
  95.                 float  averageSearchTime;
  96.                 float  peakSearchTime;
  97.         };
  98.  
  99.         ContentionStats GetContentionStats()
  100.         {
  101.                 ContentionStats stats;
  102.                 stats.frameTimeQuota = m_frameTimeQuota.GetMilliSeconds();
  103.  
  104.                 stats.averageSearchSteps = m_totalSearchCount ? m_totalSearchSteps / m_totalSearchCount : 0;
  105.                 stats.peakSearchSteps = m_peakSearchSteps;
  106.  
  107.                 stats.averageSearchTime = m_totalSearchCount ? m_totalComputationTime / (float)m_totalSearchCount : 0.0f;
  108.                 stats.peakSearchTime = m_peakSearchTime;
  109.  
  110.                 return stats;
  111.         }
  112.  
  113.         void ResetConsumedTimeDuringCurrentFrame()
  114.         {
  115.                 m_consumedFrameTime.SetValue(0);
  116.         }
  117.  
  118. protected:
  119.         AStarContention(float frameTimeQuota = 0.001f)
  120.         {
  121.                 m_frameTimeQuota.SetSeconds(frameTimeQuota);
  122.                 ResetContentionStats();
  123.         }
  124.  
  125.         inline void StartSearch()
  126.         {
  127.                 m_currentSearchSteps = 0;
  128.                 m_currentSearchTime.SetValue(0);
  129.         }
  130.  
  131.         inline void EndSearch()
  132.         {
  133.                 m_totalSearchCount++;
  134.  
  135.                 m_totalSearchSteps += m_currentSearchSteps;
  136.                 m_peakSearchSteps = max(m_peakSearchSteps, m_currentSearchSteps);
  137.  
  138.                 const float lastSearchTime = m_currentSearchTime.GetMilliSeconds();
  139.                 m_totalComputationTime += lastSearchTime;
  140.                 m_peakSearchTime = max(m_peakSearchTime, lastSearchTime);
  141.         }
  142.  
  143.         inline void StartStep()
  144.         {
  145.                 m_currentStepStartTime = gEnv->pTimer->GetAsyncTime();
  146.                 m_currentSearchSteps++;
  147.         }
  148.  
  149.         inline void EndStep()
  150.         {
  151.                 const CTimeValue stepTime = (gEnv->pTimer->GetAsyncTime() - m_currentStepStartTime);
  152.                 m_consumedFrameTime += stepTime;
  153.                 m_currentSearchTime += stepTime;
  154.         }
  155.  
  156.         inline bool FrameQuotaReached() const
  157.         {
  158.                 return (m_frameTimeQuota > CTimeValue()) ? (m_consumedFrameTime >= m_frameTimeQuota) : false;
  159.         }
  160.  
  161.         void ResetContentionStats()
  162.         {
  163.                 m_consumedFrameTime.SetValue(0);
  164.                 m_currentStepStartTime.SetValue(0);
  165.  
  166.                 m_totalSearchCount = 0;
  167.  
  168.                 m_currentSearchSteps = 0;
  169.                 m_totalSearchSteps = 0;
  170.                 m_peakSearchSteps = 0;
  171.  
  172.                 m_totalComputationTime = 0.0f;
  173.                 m_currentSearchTime.SetValue(0);
  174.                 m_peakSearchTime = 0.0f;
  175.         }
  176.  
  177. protected:
  178.         CTimeValue m_frameTimeQuota;
  179.         CTimeValue m_consumedFrameTime;
  180.         CTimeValue m_currentStepStartTime;
  181.         CTimeValue m_currentSearchTime;
  182.  
  183.         uint32     m_totalSearchCount;
  184.  
  185.         uint32     m_currentSearchSteps;
  186.         uint32     m_totalSearchSteps;
  187.         uint32     m_peakSearchSteps;
  188.  
  189.         float      m_totalComputationTime;
  190.         float      m_peakSearchTime;
  191. };
  192.  
  193. struct AStarOpenList
  194.         : public AStarContention
  195. {
  196.         typedef AStarContention ContentionPolicy;
  197.  
  198.         struct Node
  199.         {
  200.                 Node()
  201.                         : prevTriangle(0, 0)
  202.                         , open(false)
  203.                 {
  204.                 }
  205.  
  206.                 Node(TriangleID _prevTriangleID, OffMeshLinkID _prevOffMeshLinkID, const vector3_t& _location, const real_t _cost = 0,
  207.                      bool _open = false)
  208.                         : prevTriangle(_prevTriangleID, _prevOffMeshLinkID)
  209.                         , location(_location)
  210.                         , cost(_cost)
  211.                         , estimatedTotalCost(FLT_MAX)
  212.                         , open(_open)
  213.                 {
  214.                 }
  215.  
  216.                 Node(TriangleID _prevTriangleID, OffMeshLinkID _prevOffMeshLinkID, const vector3_t& _location, const real_t _cost = 0,
  217.                      const real_t _estitmatedTotalCost = real_t::max(), bool _open = false)
  218.                         : prevTriangle(_prevTriangleID, _prevOffMeshLinkID)
  219.                         , location(_location)
  220.                         , cost(_cost)
  221.                         , estimatedTotalCost(_estitmatedTotalCost)
  222.                         , open(_open)
  223.                 {
  224.                 }
  225.  
  226.                 bool operator<(const Node& other) const
  227.                 {
  228.                         return estimatedTotalCost < other.estimatedTotalCost;
  229.                 }
  230.  
  231.                 WayTriangleData prevTriangle;
  232.                 vector3_t       location;
  233.  
  234.                 real_t          cost;
  235.                 real_t          estimatedTotalCost;
  236.  
  237.                 bool            open : 1;
  238.         };
  239.  
  240.         struct OpenNodeListElement
  241.         {
  242.                 OpenNodeListElement(WayTriangleData _triData, Node* _pNode, real_t _fCost)
  243.                         : triData(_triData)
  244.                         , pNode(_pNode)
  245.                         , fCost(_fCost)
  246.                 {
  247.  
  248.                 }
  249.  
  250.                 WayTriangleData triData;
  251.                 Node*           pNode;
  252.                 real_t          fCost;
  253.  
  254.                 bool operator<(const OpenNodeListElement& rOther) const
  255.                 {
  256.                         return fCost < rOther.fCost;
  257.                 }
  258.         };
  259.  
  260.         // to get the size of the map entry, use typedef to provide us with value_type
  261.         typedef std::map<WayTriangleData, Node>                                                NodesSizeHelper;
  262.         typedef stl::STLPoolAllocator<NodesSizeHelper::value_type, stl::PSyncMultiThread>      OpenListAllocator;
  263.         typedef std::map<WayTriangleData, Node, std::less<WayTriangleData>, OpenListAllocator> Nodes;
  264.  
  265.         void SetUpForPathSolving(const uint32 triangleCount, const TriangleID fromTriangleID, const vector3_t& startLocation, const real_t dist_start_to_end)
  266.         {
  267.                 ContentionPolicy::StartSearch();
  268.  
  269.                 const size_t EstimatedNodeCount = triangleCount + 64;
  270.                 const size_t MinOpenListSize = NextPowerOfTwo(EstimatedNodeCount);
  271.  
  272.                 m_openList.clear();
  273.                 m_openList.reserve(MinOpenListSize);
  274.                 m_nodeLookUp.clear();
  275.  
  276.                 std::pair<AStarOpenList::Nodes::iterator, bool> firstEntryIt = m_nodeLookUp.insert(std::make_pair(WayTriangleData(fromTriangleID, 0), AStarOpenList::Node(fromTriangleID, 0, startLocation, 0, dist_start_to_end, true)));
  277.                 m_openList.push_back(OpenNodeListElement(WayTriangleData(fromTriangleID, 0), &firstEntryIt.first->second, dist_start_to_end));
  278.  
  279.         }
  280.  
  281.         void PathSolvingDone()
  282.         {
  283.                 ContentionPolicy::EndSearch();
  284.         }
  285.  
  286.         inline OpenNodeListElement PopBestNode()
  287.         {
  288.                 ContentionPolicy::StartStep();
  289.  
  290.                 OpenList::iterator it = std::min_element(m_openList.begin(), m_openList.end());
  291.  
  292.                 //Switch the smallest element with the last one and pop the last element
  293.                 OpenNodeListElement element = *it;
  294.                 *it = m_openList.back();
  295.                 m_openList.pop_back();
  296.  
  297.                 return element;
  298.         }
  299.  
  300.         inline bool InsertNode(const WayTriangleData& triangle, Node** pNextNode)
  301.         {
  302.                 std::pair<Nodes::iterator, bool> itInsert = m_nodeLookUp.insert(std::make_pair(triangle, Node()));
  303.                 (*pNextNode) = &itInsert.first->second;
  304.  
  305.                 assert(pNextNode);
  306.  
  307.                 return itInsert.second;
  308.         }
  309.  
  310.         inline const Node* FindNode(const WayTriangleData& triangle) const
  311.         {
  312.                 Nodes::const_iterator it = m_nodeLookUp.find(triangle);
  313.  
  314.                 return (it != m_nodeLookUp.end()) ? &it->second : NULL;
  315.         }
  316.  
  317.         inline void AddToOpenList(const WayTriangleData& triangle, Node* pNode, real_t cost)
  318.         {
  319.                 assert(pNode);
  320.                 m_openList.push_back(OpenNodeListElement(triangle, pNode, cost));
  321.         }
  322.  
  323.         inline bool CanDoStep() const
  324.         {
  325.                 return (!m_openList.empty() && !ContentionPolicy::FrameQuotaReached());
  326.         }
  327.  
  328.         inline void StepDone()
  329.         {
  330.                 ContentionPolicy::EndStep();
  331.         }
  332.  
  333.         inline bool Empty() const
  334.         {
  335.                 return m_openList.empty();
  336.         }
  337.  
  338.         void Reset()
  339.         {
  340.                 ResetContentionStats();
  341.  
  342.                 stl::free_container(m_openList);
  343.                 stl::free_container(m_nodeLookUp);
  344.         }
  345.  
  346.         bool TileWasVisited(const TileID tileID) const
  347.         {
  348.                 Nodes::const_iterator nodesEnd = m_nodeLookUp.end();
  349.  
  350.                 for (Nodes::const_iterator nodeIt = m_nodeLookUp.begin(); nodeIt != nodesEnd; ++nodeIt)
  351.                 {
  352.                         if (ComputeTileID(nodeIt->first.triangleID) != tileID)
  353.                                 continue;
  354.  
  355.                         return true;
  356.                 }
  357.  
  358.                 return false;
  359.         }
  360.  
  361. private:
  362.  
  363.         size_t NextPowerOfTwo(size_t n)
  364.         {
  365.                 n = n - 1;
  366.                 n = n | (n >> 1);
  367.                 n = n | (n >> 2);
  368.                 n = n | (n >> 4);
  369.                 n = n | (n >> 8);
  370.                 n = n | (n >> 16);
  371.                 n = n + 1;
  372.  
  373.                 return n;
  374.         }
  375.  
  376.         typedef std::vector<OpenNodeListElement> OpenList;
  377.         OpenList m_openList;
  378.         Nodes    m_nodeLookUp;
  379. };
  380.  
  381. template<typename Ty>
  382. inline bool maximize(Ty& val, const Ty& x)
  383. {
  384.         if (val < x)
  385.         {
  386.                 val = x;
  387.                 return true;
  388.         }
  389.  
  390.         return false;
  391. }
  392.  
  393. template<typename Ty>
  394. inline bool minimize(Ty& val, const Ty& x)
  395. {
  396.         if (val > x)
  397.         {
  398.                 val = x;
  399.                 return true;
  400.         }
  401.  
  402.         return false;
  403. }
  404.  
  405. template<typename Ty>
  406. inline void sort2(Ty& x, Ty& y)
  407. {
  408.         if (x > y)
  409.                 std::swap(x, y);
  410. }
  411.  
  412. template<typename Ty>
  413. inline void rsort2(Ty& x, Ty& y)
  414. {
  415.         if (x < y)
  416.                 std::swap(x, y);
  417. }
  418.  
  419. template<typename Ty>
  420. inline Ty clamp(const Ty& x, const Ty& min, const Ty& max)
  421. {
  422.         if (x > max)
  423.                 return max;
  424.         if (x < min)
  425.                 return min;
  426.         return x;
  427. }
  428.  
  429. template<typename Ty>
  430. inline Ty clampunit(const Ty& x)
  431. {
  432.         if (x > Ty(1))
  433.                 return Ty(1);
  434.         if (x < Ty(0))
  435.                 return Ty(0);
  436.         return x;
  437. }
  438.  
  439. template<typename Ty>
  440. inline Ty next_mod3(const Ty& x)
  441. {
  442.         return (x + 1) % 3;
  443. }
  444.  
  445. template<typename VecType>
  446. inline real_t ProjectionPointLineSeg(const VecType& p, const VecType& a0, const VecType& a1)
  447. {
  448.         const VecType a = a1 - a0;
  449.         const real_t lenSq = a.lenSq();
  450.  
  451.         if (lenSq > 0)
  452.         {
  453.                 const VecType ap = p - a0;
  454.                 const real_t dot = a.dot(ap);
  455.                 return dot / lenSq;
  456.         }
  457.  
  458.         return 0;
  459. }
  460.  
  461. template<typename VecType>
  462. inline real_t DistPointLineSegSq(const VecType& p, const VecType& a0, const VecType& a1)
  463. {
  464.         const VecType a = a1 - a0;
  465.         const VecType ap = p - a0;
  466.         const VecType bp = p - a1;
  467.  
  468.         const real_t e = ap.dot(a);
  469.         if (e <= 0)
  470.                 return ap.dot(ap);
  471.  
  472.         const real_t f = a.dot(a);
  473.         if (e >= f)
  474.                 return bp.dot(bp);
  475.  
  476.         return ap.dot(ap) - ((e * e) / f);
  477. }
  478.  
  479. template<typename VecType>
  480. inline VecType ClosestPtPointTriangle(const VecType& p, const VecType& a, const VecType& b, const VecType& c)
  481. {
  482.         const VecType ab = b - a;
  483.         const VecType ac = c - a;
  484.         const VecType ap = p - a;
  485.  
  486.         const real_t d1 = ab.dot(ap);
  487.         const real_t d2 = ac.dot(ap);
  488.  
  489.         if ((d1 <= 0) && (d2 <= 0))
  490.                 return a;
  491.  
  492.         const VecType bp = p - b;
  493.         const real_t d3 = ab.dot(bp);
  494.         const real_t d4 = ac.dot(bp);
  495.  
  496.         if ((d3 >= 0) && (d4 <= d3))
  497.                 return b;
  498.  
  499.         const real_t vc = d1 * d4 - d3 * d2;
  500.         if ((vc <= 0) && (d1 >= 0) && (d3 < 0))
  501.         {
  502.                 const real_t v = d1 / (d1 - d3);
  503.                 return a + (ab * v);
  504.         }
  505.  
  506.         const VecType cp = p - c;
  507.         const real_t d5 = ab.dot(cp);
  508.         const real_t d6 = ac.dot(cp);
  509.  
  510.         if ((d6 >= 0) && (d5 <= d6))
  511.                 return c;
  512.  
  513.         const real_t vb = d5 * d2 - d1 * d6;
  514.         if ((vb <= 0) && (d2 >= 0) && (d6 < 0))
  515.         {
  516.                 const real_t w = d2 / (d2 - d6);
  517.                 return a + (ac * w);
  518.         }
  519.  
  520.         const real_t va = d3 * d6 - d5 * d4;
  521.         if ((va <= 0) && ((d4 - d3) >= 0) && ((d5 - d6) > 0))
  522.         {
  523.                 const real_t w = (d4 - d3) / ((d4 - d3) + (d5 - d6));
  524.                 return b + ((c - b) * w);
  525.         }
  526.  
  527.         // do not factorize the divisions : Fixed point precision requires it
  528.         const real_t denom = va + vb + vc;
  529.         const real_t v = vb / denom;
  530.         const real_t w = vc / denom;
  531.  
  532.         return a + ab * v + ac * w;
  533. }
  534.  
  535. inline bool PointInTriangle(const vector2_t& p, const vector2_t& a, const vector2_t& b, const vector2_t& c)
  536. {
  537.         const bool e0 = (p - a).cross(a - b) >= 0;
  538.         const bool e1 = (p - b).cross(b - c) >= 0;
  539.         const bool e2 = (p - c).cross(c - a) >= 0;
  540.  
  541.         return (e0 == e1) && (e0 == e2);
  542. }
  543.  
  544. template<typename VecType>
  545. inline real_t ClosestPtSegmentSegment(const VecType& a0, const VecType& a1, const VecType& b0, const VecType& b1,
  546.                                       real_t& s, real_t& t, VecType& closesta, VecType& closestb)
  547. {
  548.         const VecType da = a1 - a0;
  549.         const VecType db = b1 - b0;
  550.         const VecType r = a0 - b0;
  551.         const real_t a = da.lenSq();
  552.         const real_t e = db.lenSq();
  553.         const real_t f = db.dot(r);
  554.  
  555.         if ((a == 0) && (e == 0))
  556.         {
  557.                 s = t = 0;
  558.                 closesta = a0;
  559.                 closestb = b0;
  560.  
  561.                 return (closesta - closestb).lenSq();
  562.         }
  563.  
  564.         if (a == 0)
  565.         {
  566.                 s = 0;
  567.                 t = f / e;
  568.                 t = clampunit(t);
  569.         }
  570.         else
  571.         {
  572.                 const real_t c = da.dot(r);
  573.  
  574.                 if (e == 0)
  575.                 {
  576.                         t = 0;
  577.                         s = clampunit(-c / a);
  578.                 }
  579.                 else
  580.                 {
  581.                         const real_t b = da.dot(db);
  582.                         const real_t denom = (a * e) - (b * b);
  583.  
  584.                         if (denom != 0)
  585.                                 s = clampunit(((b * f) - (c * e)) / denom);
  586.                         else
  587.                                 s = 0;
  588.  
  589.                         const real_t tnom = (b * s) + f;
  590.  
  591.                         if (tnom < 0)
  592.                         {
  593.                                 t = 0;
  594.                                 s = clampunit(-c / a);
  595.                         }
  596.                         else if (tnom > e)
  597.                         {
  598.                                 t = 1;
  599.                                 s = clampunit((b - c) / a);
  600.                         }
  601.                         else
  602.                                 t = tnom / e;
  603.                 }
  604.         }
  605.  
  606.         closesta = a0 + da * s;
  607.         closestb = b0 + db * t;
  608.  
  609.         return (closesta - closestb).lenSq();
  610. }
  611.  
  612. template<typename VecType>
  613. inline vector2_t ClosestPtPointSegment(const VecType& p, const VecType& a0, const VecType& a1, real_t& t)
  614. {
  615.         const VecType a = a1 - a0;
  616.  
  617.         t = (p - a0).dot(a);
  618.  
  619.         if (t <= 0)
  620.         {
  621.                 t = 0;
  622.                 return a0;
  623.         }
  624.         else
  625.         {
  626.                 const real_t denom = a.lenSq();
  627.  
  628.                 if (t >= denom)
  629.                 {
  630.                         t = 1;
  631.                         return a1;
  632.                 }
  633.                 else
  634.                 {
  635.                         t = t / denom;
  636.                         return a0 + (a * t);
  637.                 }
  638.         }
  639. }
  640.  
  641. // Intersection between two segments in 2D. The two parametric values are set to between 0 and 1
  642. // if intersection occurs. If intersection does not occur their values will indicate the
  643. // parametric values for intersection of the lines extended beyond the segment lengths.
  644. // Parallel lines will result in a negative result.
  645. enum EIntersectionResult
  646. {
  647.         eIR_NoIntersection,
  648.         eIR_Intersection,
  649.         eIR_ParallelOrCollinearSegments,
  650. };
  651.  
  652. template<typename VecType>
  653. inline EIntersectionResult DetailedIntersectSegmentSegment(const VecType& a0, const VecType& a1, const VecType& b0, const VecType& b1,
  654.                                                            real_t& s, real_t& t)
  655. {
  656.         /*
  657.            a0
  658.          |
  659.            s
  660.            b0-----t----------b1
  661.          |
  662.          |
  663.            a1
  664.  
  665.            Assuming
  666.            da = a1 - a0
  667.            db = b1 - 0
  668.            we can define the equations of the two segments as
  669.            a0 + s * da = 0    with s = [0...1]
  670.            b0 + t * db = 0    with t = [0...1]
  671.            We have an intersection if
  672.  
  673.            a0 + s * da = b0 + t * db
  674.  
  675.            We then cross product both side for db ( to calculate s) obtaining
  676.  
  677.            (a0 - b0) x db + s * (da x db) = t * (db x db)
  678.            (a0 - b0) x db + s * (da x db) = 0
  679.  
  680.            we call e = (a0 - b0)
  681.  
  682.            s = ( e x db ) / ( da x db )
  683.  
  684.            We can now calculate t with the same procedure.
  685.          */
  686.  
  687.         const VecType e = b0 - a0;
  688.         const VecType da = a1 - a0;
  689.         const VecType db = b1 - b0;
  690.         // | da.x   da.y |
  691.         // | db.x   db.y |
  692.         // If det is zero then the two vectors are dependent, meaning
  693.         // they are parallel or colinear.
  694.         const real_t det = da.x * db.y - da.y * db.x;
  695.         const real_t tolerance = real_t::epsilon();
  696.         const real_t signAdjustment = det >= real_t(0.0f) ? real_t(1.0f) : real_t(-1.0f);
  697.         const real_t minAllowedValue = real_t(.0f) - tolerance;
  698.         const real_t maxAllowedValue = (real_t(1.0f) * det * signAdjustment) + tolerance;
  699.         if (det != 0)
  700.         {
  701.                 s = (e.x * db.y - e.y * db.x) * signAdjustment;
  702.  
  703.                 if ((s < minAllowedValue) || (s > maxAllowedValue))
  704.                         return eIR_NoIntersection;
  705.  
  706.                 t = (e.x * da.y - e.y * da.x) * signAdjustment;
  707.                 if ((t < minAllowedValue) || (t > maxAllowedValue))
  708.                         return eIR_NoIntersection;
  709.  
  710.                 s = clampunit(s / det * signAdjustment);
  711.                 t = clampunit(t / det * signAdjustment);
  712.                 return eIR_Intersection;
  713.         }
  714.  
  715.         return eIR_ParallelOrCollinearSegments;
  716. }
  717.  
  718. template<typename VecType>
  719. inline bool IntersectSegmentSegment(const VecType& a0, const VecType& a1, const VecType& b0, const VecType& b1,
  720.                                     real_t& s, real_t& t)
  721. {
  722.         return DetailedIntersectSegmentSegment(a0, a1, b0, b1, s, t) == eIR_Intersection;
  723. }
  724. }
  725.  
  726. namespace MNMUtils
  727. {
  728. inline const MNM::real_t CalculateMinHorizontalRange(const uint16 radiusVoxelUnits, const float voxelHSize)
  729. {
  730.         assert(voxelHSize > 0.0f);
  731.  
  732.         // The horizontal x-y size for the voxels it's recommended to be the same.
  733.         return MNM::real_t(max(radiusVoxelUnits * voxelHSize * 2.0f, 1.0f));
  734. }
  735.  
  736. inline const MNM::real_t CalculateMinVerticalRange(const uint16 agentHeightVoxelUnits, const float voxelVSize)
  737. {
  738.         assert(voxelVSize > 0.0f);
  739.  
  740.         return MNM::real_t(max(agentHeightVoxelUnits * voxelVSize, 1.0f));
  741. }
  742. }
  743.  
  744. #endif  // #ifndef __MNM_H
  745.  
downloadMNM.h 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