3
0

IPathfinder.h 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. // Description : Pathfinder Interface.
  9. #pragma once
  10. struct IAIPathAgent;
  11. #include <INavigationSystem.h>
  12. #include <IMNM.h>
  13. #include <SerializeFwd.h>
  14. #include <Cry_Geo.h>
  15. #include <AzCore/std/functional.h>
  16. #include <AzCore/std/containers/vector.h>
  17. #include <AzCore/std/smart_ptr/shared_ptr.h>
  18. #include <limits>
  19. #include <list>
  20. // Hacks to deal with windows header inclusion.
  21. #ifdef GetObject
  22. #undef GetObject
  23. #endif
  24. #ifdef GetUserName
  25. #undef GetUserName
  26. #endif
  27. #ifdef DrawText
  28. #undef DrawText
  29. #endif
  30. #ifdef LoadLibrary
  31. #undef LoadLibrary
  32. #endif
  33. #ifdef max
  34. #undef max
  35. #endif
  36. /* WARNING: These interfaces and structures are soon to be deprecated.
  37. Use at your own risk of having to change your code later!
  38. */
  39. // Passing through navigational SO methods.
  40. enum ENavSOMethod
  41. {
  42. nSOmNone, // not passing or not passable
  43. nSOmAction, // execute an AI action
  44. nSOmPriorityAction, // execute a higher priority AI action
  45. nSOmStraight, // just pass straight
  46. nSOmSignalAnimation, // play signal animation
  47. nSOmActionAnimation, // play action animation
  48. nSOmLast
  49. };
  50. // Indication of (a) what a graph node represents and (b) what kind of graph node an AI entity
  51. // can navigate. In the latter case it can be used as a bit mask.
  52. // Copied from CryCommon/IAISystem.h which has been deleted.
  53. enum ENavigationType
  54. {
  55. NAV_UNSET = 1 << 0,
  56. NAV_TRIANGULAR = 1 << 1,
  57. NAV_WAYPOINT_HUMAN = 1 << 2,
  58. NAV_WAYPOINT_3DSURFACE = 1 << 3,
  59. NAV_FLIGHT = 1 << 4,
  60. NAV_VOLUME = 1 << 5,
  61. NAV_ROAD = 1 << 6,
  62. NAV_SMARTOBJECT = 1 << 7,
  63. NAV_FREE_2D = 1 << 8,
  64. NAV_CUSTOM_NAVIGATION = 1 << 9,
  65. NAV_MAX_VALUE = NAV_CUSTOM_NAVIGATION
  66. };
  67. //====================================================================
  68. // NavigationBlocker
  69. // Represents an object that might be blocking a link. Each blocker is
  70. // assumed to be spherical, with the position centred around the floor
  71. // so that links can intersect it.
  72. //====================================================================
  73. struct NavigationBlocker
  74. {
  75. /// pos and radius define the sphere.
  76. /// costAddMod is a fixed cost (in m) associated with the blocker obscuring a link - a value of 0 has
  77. /// no effect - a value of 10 would make the link effectively 10m longer than it is.
  78. /// costMultMod is the cost modification factor - a value of 0 has no effect - a value of 10 would make the link
  79. /// 10x more costly. -ve disables the link
  80. /// radialDecay indicates if the cost modifiers should decay linearly to 0 over the radius of the sphere
  81. /// directional indicates if the cost should be unaffected for motion in a radial direction
  82. NavigationBlocker(const Vec3& pos, float radius, float _costAddMod, float _costMultMod, bool _radialDecay, bool _directional)
  83. : sphere(pos, radius)
  84. , costAddMod(_costAddMod)
  85. , costMultMod(_costMultMod)
  86. , restrictedLocation(false)
  87. , radialDecay(_radialDecay)
  88. , directional(_directional) {}
  89. /// Just to allow std::vector::resize(0)
  90. NavigationBlocker()
  91. : sphere(Vec3(0, 0, 0), 0.0f)
  92. , costAddMod(0)
  93. , costMultMod(0)
  94. , radialDecay(false) {AZ_Assert(false, "Should never get called"); }
  95. ::Sphere sphere;
  96. bool radialDecay;
  97. bool directional;
  98. /// absolute cost added to any link going through this blocker (useful for small blockers)
  99. float costAddMod;
  100. /// multiplier for link costs going through this blocker (0 means no extra cost, 1 means to double etc)
  101. float costMultMod;
  102. // info to speed up the intersection checks
  103. /// If this is true then the blocker is small enough that it only affects the
  104. /// nav type it resides in. If false then it affects everything.
  105. bool restrictedLocation;
  106. ENavigationType navType;
  107. union Location
  108. {
  109. struct // similar for other nav types when there's info to go in them
  110. {
  111. // no node because the node "areas" can overlap so it's not useful
  112. int nBuildingID;
  113. } waypoint;
  114. };
  115. /// Only gets used if restrictedLocation = true
  116. Location location;
  117. };
  118. using NavigationBlockers = AZStd::vector<NavigationBlocker>;
  119. //====================================================================
  120. // PathPointDescriptor
  121. //====================================================================
  122. struct PathPointDescriptor
  123. {
  124. struct SmartObjectNavData
  125. : public _i_reference_target_t
  126. {
  127. unsigned fromIndex;
  128. unsigned toIndex;
  129. };
  130. typedef _smart_ptr< SmartObjectNavData > SmartObjectNavDataPtr;
  131. struct OffMeshLinkData
  132. {
  133. OffMeshLinkData()
  134. : meshID(0)
  135. , offMeshLinkID(0)
  136. {}
  137. uint32 meshID;
  138. MNM::OffMeshLinkID offMeshLinkID;
  139. };
  140. PathPointDescriptor(ENavigationType _navType = NAV_UNSET, const Vec3& _vPos = ZERO)
  141. : vPos(_vPos)
  142. , navType(_navType)
  143. , navTypeCustomId(0)
  144. , iTriId(0)
  145. , pSONavData(0)
  146. , navSOMethod(nSOmNone)
  147. {}
  148. PathPointDescriptor(const Vec3& _vPos)
  149. : vPos(_vPos)
  150. , navType(NAV_UNSET)
  151. , navTypeCustomId(0)
  152. , iTriId(0)
  153. , pSONavData(0)
  154. , navSOMethod(nSOmNone)
  155. {}
  156. bool IsEquivalent(const PathPointDescriptor& other) const
  157. {
  158. return (navType == other.navType) && vPos.IsEquivalent(other.vPos, 0.01f);
  159. }
  160. static bool ArePointsEquivalent(const PathPointDescriptor& point1, const PathPointDescriptor& point2)
  161. {
  162. return point1.IsEquivalent(point2);
  163. }
  164. Vec3 vPos;
  165. ENavigationType navType;
  166. uint16 navTypeCustomId;
  167. uint32 iTriId;
  168. OffMeshLinkData offMeshLinkData;
  169. SmartObjectNavDataPtr pSONavData;
  170. ENavSOMethod navSOMethod;
  171. };
  172. struct PathfindingExtraConstraint
  173. {
  174. enum EExtraConstraintType
  175. {
  176. ECT_MAXCOST,
  177. ECT_MINDISTFROMPOINT,
  178. ECT_AVOIDSPHERE,
  179. ECT_AVOIDCAPSULE
  180. };
  181. EExtraConstraintType type;
  182. union UConstraint
  183. {
  184. struct SConstraintMaxCost
  185. {
  186. float maxCost;
  187. };
  188. struct SConstraintMinDistFromPoint
  189. {
  190. float px, py, pz; // Can't use Vec3 as it has a constructor.
  191. float minDistSq;
  192. };
  193. struct SConstraintAvoidSphere
  194. {
  195. float px, py, pz; // Can't use Vec3 as it has a constructor.
  196. float minDistSq;
  197. };
  198. struct SConstraintAvoidCapsule
  199. {
  200. float px, py, pz;
  201. float qx, qy, qz;
  202. float minDistSq;
  203. };
  204. SConstraintMaxCost maxCost;
  205. SConstraintMinDistFromPoint minDistFromPoint;
  206. SConstraintAvoidSphere avoidSphere;
  207. SConstraintAvoidCapsule avoidCapsule;
  208. };
  209. UConstraint constraint;
  210. };
  211. using PathfindingExtraConstraints = AZStd::vector<PathfindingExtraConstraint>;
  212. struct PathfindRequest
  213. {
  214. enum ERequestType
  215. {
  216. TYPE_ACTOR,
  217. TYPE_RAW,
  218. };
  219. ERequestType type;
  220. unsigned startIndex;
  221. unsigned endIndex;
  222. Vec3 startPos;
  223. Vec3 startDir;
  224. Vec3 endPos;
  225. /// endDir magnitude indicates the tendency to line up at the end of the path -
  226. /// magnitude should be between 0 and 1
  227. Vec3 endDir;
  228. bool bSuccess;
  229. IAIPathAgent* pRequester;
  230. int nForceTargetBuildingId;
  231. bool allowDangerousDestination;
  232. float endTol;
  233. float endDistance;
  234. // as a result of RequestPathInDirection or RequestPathTo
  235. bool isDirectional;
  236. /// This gets set to false if the path end position doesn't match the requested end position
  237. /// (e.g. in the event of a partial path, or if the destination is in forbidden)
  238. bool bPathEndIsAsRequested;
  239. int id;
  240. float passRadius;
  241. PathfindingExtraConstraints extraConstraints;
  242. PathfindRequest(ERequestType _type)
  243. : type(_type)
  244. , startIndex(0)
  245. , endIndex(0)
  246. , pRequester(0)
  247. , bPathEndIsAsRequested(false)
  248. , allowDangerousDestination(false)
  249. , endTol(std::numeric_limits<float>::max())
  250. , endDistance(0)
  251. , nForceTargetBuildingId(-1)
  252. , isDirectional(false)
  253. , id(-1)
  254. , passRadius(0.0f)
  255. {
  256. }
  257. };
  258. struct PathFollowerParams
  259. {
  260. PathFollowerParams()
  261. : normalSpeed(0.0f)
  262. , pathRadius(0.0f)
  263. , pathLookAheadDist(1.0f)
  264. , maxAccel(0.0f)
  265. , maxDecel(1.0f)
  266. , minSpeed(0.0f)
  267. , maxSpeed(10.0f)
  268. , endAccuracy(0.2f)
  269. , endDistance(0.0f)
  270. , stopAtEnd(true)
  271. , use2D(true)
  272. , isVehicle(false)
  273. , isAllowedToShortcut(true)
  274. , passRadius(0.5f)
  275. {}
  276. // OLD: Remove this when possible, Animation to take over majority of logic
  277. float normalSpeed; ///< normal entity speed
  278. float pathRadius; ///< max deviation allowed from the path
  279. float pathLookAheadDist; ///< how far we look ahead along the path - normally the same as pathRadius
  280. float maxAccel; ///< maximum acceleration of the entity
  281. float maxDecel; ///< maximum deceleration of the entity
  282. float minSpeed; ///< minimum output speed (unless it's zero on path end etc)
  283. float maxSpeed; ///< maximum output speed
  284. // KEEP: Additions and useful state for new impl.
  285. float endAccuracy; ///< How close to the end point the agent must be to finish pathing
  286. float endDistance; ///< stop this much before the end
  287. bool stopAtEnd; ///< aim to finish the path by reaching the end position (stationary), or simply overshoot
  288. bool use2D; ///< follow in 2 or 3D
  289. bool isVehicle;
  290. bool isAllowedToShortcut;
  291. /// The minimum radius of the agent for navigating
  292. float passRadius;
  293. };
  294. struct PathFollowResult
  295. {
  296. struct SPredictedState
  297. {
  298. SPredictedState() {}
  299. SPredictedState(const Vec3& p, const Vec3& v)
  300. : pos(p)
  301. , vel(v) {}
  302. Vec3 pos;
  303. Vec3 vel;
  304. };
  305. typedef AZStd::vector<SPredictedState> TPredictedStates;
  306. // OLD: Obsolete & to be replaced by new impl.
  307. /// maximum time to predict out to - actual prediction may not go this far
  308. float desiredPredictionTime;
  309. /// the first element in predictedStates will be now + predictionDeltaTime, etc
  310. float predictionDeltaTime;
  311. /// if this is non-zero then on output the prediction will be placed into it
  312. TPredictedStates* predictedStates;
  313. PathFollowResult()
  314. : predictionDeltaTime(0.1f)
  315. , predictedStates(0)
  316. , desiredPredictionTime(0)
  317. , distanceToEnd(0.f)
  318. , reachedEnd(false)
  319. , followTargetPos(0)
  320. , inflectionPoint(0) {}
  321. float distanceToEnd;
  322. bool reachedEnd;
  323. Vec3 velocityOut;
  324. // NEW: Replaces data above
  325. // NOTE: If the turningPoint and inflectionPoint are equal, they represent the end of the path.
  326. /// The furthest point on the path we can move directly towards without colliding with anything
  327. Vec3 followTargetPos;
  328. /// The next point on the path beyond the follow target that deviates substantially from a straight-line path
  329. Vec3 inflectionPoint;
  330. /// The maximum distance the agent can safely move in a straight line beyond the turning point
  331. // float maxOverrunDistance;
  332. };
  333. // Intermediary and minimal interface to use the pathfinder without requiring an AI object
  334. // TODO: Fix the long function names. At the moment they collide with IAIObject base.
  335. // The alternative would be to make IAIObject derive from IAIPathAgent.
  336. struct IAIPathAgent
  337. {
  338. virtual ~IAIPathAgent(){}
  339. virtual const char* GetPathAgentName() const = 0;
  340. virtual unsigned short GetPathAgentType() const = 0;
  341. virtual float GetPathAgentPassRadius() const = 0;
  342. virtual Vec3 GetPathAgentPos() const = 0;
  343. virtual Vec3 GetPathAgentVelocity() const = 0;
  344. // This cannot easily be const, but has no side-effects
  345. virtual void GetPathAgentNavigationBlockers(NavigationBlockers& blockers, const PathfindRequest* pRequest) = 0;
  346. virtual void SetPathToFollow(const char* pathName) = 0;
  347. virtual void SetPathAttributeToFollow(bool bSpline) = 0;
  348. //Path finding avoids blocker type by radius.
  349. virtual void SetPFBlockerRadius(int blockerType, float radius) = 0;
  350. virtual bool GetValidPositionNearby(const Vec3& proposedPosition, Vec3& adjustedPosition) const = 0;
  351. virtual bool GetTeleportPosition(Vec3& teleportPos) const = 0;
  352. virtual class IPathFollower* GetPathFollower() const = 0;
  353. virtual bool IsPointValidForAgent(const Vec3& pos, uint32 flags) const = 0;
  354. };
  355. typedef std::list<PathPointDescriptor> TPathPoints;
  356. struct SNavPathParams
  357. {
  358. SNavPathParams(const Vec3& _start = Vec3_Zero, const Vec3& _end = Vec3_Zero,
  359. const Vec3& _startDir = Vec3_Zero, const Vec3& _endDir = Vec3_Zero,
  360. int _nForceBuildingID = -1, bool _allowDangerousDestination = false, float _endDistance = 0.0f,
  361. bool _continueMovingAtEnd = false, bool _isDirectional = false)
  362. : start(_start)
  363. , end(_end)
  364. , startDir(_startDir)
  365. , endDir(_endDir)
  366. , nForceBuildingID(_nForceBuildingID)
  367. , allowDangerousDestination(_allowDangerousDestination)
  368. , precalculatedPath(false)
  369. , inhibitPathRegeneration(false)
  370. , continueMovingAtEnd(_continueMovingAtEnd)
  371. , endDistance(_endDistance)
  372. , isDirectional(_isDirectional)
  373. {}
  374. Vec3 start;
  375. Vec3 end;
  376. Vec3 startDir;
  377. Vec3 endDir;
  378. int nForceBuildingID;
  379. bool allowDangerousDestination;
  380. /// if path is precalculated it should not be regenerated, and also some things like steering
  381. /// will be disabled
  382. bool precalculatedPath;
  383. /// sometimes it is necessary to disable a normal path from getting regenerated
  384. bool inhibitPathRegeneration;
  385. bool continueMovingAtEnd;
  386. bool isDirectional;
  387. float endDistance; // The requested cut distance of the path, positive value means distance from path end, negative value means distance from path start.
  388. NavigationMeshID meshID;
  389. void Clear()
  390. {
  391. start = Vec3_Zero;
  392. end = Vec3_Zero;
  393. startDir = Vec3_Zero;
  394. endDir = Vec3_Zero;
  395. allowDangerousDestination = false;
  396. precalculatedPath = false;
  397. inhibitPathRegeneration = false;
  398. continueMovingAtEnd = false;
  399. isDirectional = false;
  400. endDistance = 0.0f;
  401. meshID = NavigationMeshID(0);
  402. }
  403. void Serialize(TSerialize ser)
  404. {
  405. ser.Value("start", start);
  406. ser.Value("end", end);
  407. ser.Value("startDir", startDir);
  408. ser.Value("endDir", endDir);
  409. ser.Value("nForceBuildingID", nForceBuildingID);
  410. ser.Value("allowDangerousDestination", allowDangerousDestination);
  411. ser.Value("precalculatedPath", precalculatedPath);
  412. ser.Value("inhibitPathRegeneration", inhibitPathRegeneration);
  413. ser.Value("continueMovingAtEnd", continueMovingAtEnd);
  414. ser.Value("isDirectional", isDirectional);
  415. ser.Value("endDistance", endDistance);
  416. if (ser.IsReading())
  417. {
  418. uint32 meshIdAsUint32;
  419. ser.Value("meshID", meshIdAsUint32);
  420. meshID = NavigationMeshID(meshIdAsUint32);
  421. }
  422. else
  423. {
  424. uint32 meshIdAsUint32 = (uint32) meshID;
  425. ser.Value("meshID", meshIdAsUint32);
  426. }
  427. }
  428. };
  429. class INavPath
  430. {
  431. public:
  432. virtual ~INavPath(){}
  433. virtual void Release() = 0;
  434. virtual void CopyTo(INavPath* pRecipient) const = 0;
  435. virtual AZStd::shared_ptr<INavPath> Clone() const = 0;
  436. virtual NavigationMeshID GetMeshID() const = 0;
  437. virtual int GetVersion() const = 0;
  438. virtual void SetVersion(int version) = 0;
  439. virtual void SetParams(const SNavPathParams& params) = 0;
  440. virtual const SNavPathParams& GetParams() const = 0;
  441. virtual SNavPathParams& GetParams() = 0;
  442. virtual const TPathPoints& GetPath() const = 0;
  443. virtual void SetPathPoints(const TPathPoints& points) = 0;
  444. virtual float GetPathLength(bool twoD) const = 0;
  445. virtual void PushFront(const PathPointDescriptor& newPathPoint, bool force = false) = 0;
  446. virtual void PushBack(const PathPointDescriptor& newPathPoint, bool force = false) = 0;
  447. virtual void Clear(const char* contextName) = 0;
  448. virtual bool Advance(PathPointDescriptor& nextPathPoint) = 0;
  449. virtual bool GetPathEndIsAsRequested() const = 0;
  450. virtual void SetPathEndIsAsRequested(bool value) = 0;
  451. virtual bool Empty() const = 0;
  452. virtual const PathPointDescriptor* GetLastPathPoint() const = 0;
  453. virtual const PathPointDescriptor* GetPrevPathPoint() const = 0;
  454. virtual const PathPointDescriptor* GetNextPathPoint() const = 0;
  455. virtual const PathPointDescriptor* GetNextNextPathPoint() const = 0;
  456. virtual const Vec3& GetNextPathPos(const Vec3& defaultPos = Vec3_Zero) const = 0;
  457. virtual const Vec3& GetLastPathPos(const Vec3& defaultPos = Vec3_Zero) const = 0;
  458. virtual bool GetPosAlongPath(Vec3& posOut, float dist, bool twoD, bool extrapolateBeyondEnd, ENavigationType* nextPointType = NULL) const = 0;
  459. virtual float GetDistToPath(Vec3& pathPosOut, float& distAlongPathOut, const Vec3& pos, float dist, bool twoD) const = 0;
  460. virtual float GetDistToSmartObject(bool twoD) const = 0;
  461. virtual PathPointDescriptor::SmartObjectNavDataPtr GetLastPathPointAnimNavSOData() const = 0;
  462. virtual void SetPreviousPoint(const PathPointDescriptor& previousPoint) = 0;
  463. virtual AABB GetAABB(float dist) const = 0;
  464. virtual bool GetPathPropertiesAhead(float distAhead, bool twoD, Vec3& posOut, Vec3& dirOut, float* invROut, float& lowestPathDotOut, bool scaleOutputWithDist) const = 0;
  465. virtual void SetEndDir(const Vec3& endDir) = 0;
  466. virtual const Vec3& GetEndDir() const = 0;
  467. virtual bool UpdateAndSteerAlongPath(Vec3& dirOut, float& distToEndOut, float& distToPathOut, bool& isResolvingSticking, Vec3& pathDirOut, Vec3& pathAheadDirOut, Vec3& pathAheadPosOut, Vec3 currentPos, const Vec3& currentVel, float lookAhead, float pathRadius, float dt, bool resolveSticking, bool twoD) = 0;
  468. virtual void TrimPath(float length, bool twoD) = 0;
  469. virtual float GetDiscardedPathLength() const = 0;
  470. virtual float UpdatePathPosition(Vec3 agentPos, float pathLookahead, bool twoD, bool allowPathToFinish) = 0;
  471. virtual Vec3 CalculateTargetPos(Vec3 agentPos, float lookAhead, float minLookAheadAlongPath, float pathRadius, bool twoD) const = 0;
  472. virtual void Draw(const Vec3& drawOffset = ZERO) const = 0;
  473. virtual void Dump(const char* name) const = 0;
  474. };
  475. using INavPathPtr = AZStd::shared_ptr<INavPath>;
  476. enum EMNMPathResult
  477. {
  478. eMNMPR_NoPathFound = 0,
  479. eMNMPR_Success,
  480. };
  481. struct MNMPathRequestResult
  482. {
  483. MNMPathRequestResult()
  484. : cost(0.f)
  485. , id(0)
  486. , result(eMNMPR_NoPathFound)
  487. {}
  488. ILINE bool HasPathBeenFound() const
  489. {
  490. return result == eMNMPR_Success;
  491. }
  492. INavPathPtr pPath;
  493. float cost;
  494. uint32 id;
  495. EMNMPathResult result;
  496. };
  497. struct IPathObstacles
  498. {
  499. virtual ~IPathObstacles() {}
  500. virtual bool IsPathIntersectingObstacles(const NavigationMeshID meshID, const Vec3& start, const Vec3& end, float radius) const = 0;
  501. virtual bool IsPointInsideObstacles(const Vec3& position) const = 0;
  502. virtual bool IsLineSegmentIntersectingObstaclesOrCloseToThem(const Lineseg& linesegToTest, float maxDistanceToConsiderClose) const = 0;
  503. };
  504. class IPathFollower
  505. {
  506. public:
  507. virtual ~IPathFollower(){}
  508. virtual void Release() = 0;
  509. virtual void Reset() = 0;
  510. /// This attaches us to a particular path (pass 0 to detach)
  511. virtual void AttachToPath(INavPath* navPath) = 0;
  512. virtual void SetParams(const PathFollowerParams& params) = 0;
  513. /// Just view the params
  514. virtual const PathFollowerParams& GetParams() const = 0;
  515. virtual PathFollowerParams& GetParams() = 0;
  516. // Advances the follow target along the path as far as possible while ensuring the follow
  517. // target remains reachable. Returns true if the follow target is reachable, false otherwise.
  518. virtual bool Update(PathFollowResult& result, const Vec3& curPos, const Vec3& curVel, float dt) = 0;
  519. /// Advances the current state in terms of position - effectively pretending that the follower
  520. /// has gone further than it has.
  521. virtual void Advance(float distance) = 0;
  522. /// Returns the distance from the lookahead to the end, plus the distance from the position passed in
  523. /// to the LA if pCurPos != 0
  524. virtual float GetDistToEnd(const Vec3* pCurPos) const = 0;
  525. /// Returns the distance along the path from the current look-ahead position to the
  526. /// first smart object path segment. If there's no path, or no smart objects on the
  527. /// path, then std::numeric_limits<float>::max() will be returned
  528. virtual float GetDistToSmartObject() const = 0;
  529. virtual float GetDistToNavType(ENavigationType navType) const = 0;
  530. /// Returns a point on the path some distance ahead. actualDist is set according to
  531. /// how far we looked - may be less than dist if we'd reach the end
  532. virtual Vec3 GetPathPointAhead(float dist, float& actualDist) const = 0;
  533. virtual void Draw(const Vec3& drawOffset = ZERO) const = 0;
  534. virtual void Serialize(TSerialize ser) = 0;
  535. // Checks ability to walk along a piecewise linear path starting from the current position
  536. // (useful for example when animation would like to deviate from the path)
  537. virtual bool CheckWalkability(const Vec2* path, const size_t length) const = 0;
  538. // Can the pathfollower cut corners if there is space to do so? (default: true)
  539. virtual bool GetAllowCuttingCorners() const = 0;
  540. // Sets whether or not the pathfollower is allowed to cut corners if there is space to do so. (default: true)
  541. virtual void SetAllowCuttingCorners(const bool allowCuttingCorners) = 0;
  542. };
  543. namespace MNM
  544. {
  545. typedef unsigned int QueuedPathID;
  546. namespace Constants
  547. {
  548. enum EQueuedPathID
  549. {
  550. eQueuedPathID_InvalidID = 0,
  551. };
  552. }
  553. }
  554. struct MNMPathRequest
  555. {
  556. using Callback = AZStd::function<void(const MNM::QueuedPathID&, MNMPathRequestResult&)>;
  557. MNMPathRequest()
  558. : resultCallback(0)
  559. , startLocation(ZERO)
  560. , endLocation(ZERO)
  561. , endDirection(Vec3(0, 1, 0))
  562. , agentTypeID(NavigationAgentTypeID())
  563. , forceTargetBuildingId(0)
  564. , endTolerance(0.0f)
  565. , endDistance(0.0f)
  566. , allowDangerousDestination(false)
  567. , beautify(true)
  568. {
  569. }
  570. MNMPathRequest(const Vec3& start, const Vec3& end, const Vec3& _endDirection, int _forceTargetBuildingId,
  571. float _endTolerance, float _endDistance, [[maybe_unused]] bool _allowDangerousDestination, const Callback& callback,
  572. const NavigationAgentTypeID& _agentTypeID)
  573. : resultCallback(callback)
  574. , startLocation(start)
  575. , endLocation(end)
  576. , endDirection(_endDirection)
  577. , agentTypeID(_agentTypeID)
  578. , forceTargetBuildingId(_forceTargetBuildingId)
  579. , endTolerance(_endTolerance)
  580. , endDistance(_endDistance)
  581. , allowDangerousDestination(false)
  582. , beautify(true)
  583. {
  584. }
  585. Callback resultCallback;
  586. Vec3 startLocation;
  587. Vec3 endLocation;
  588. Vec3 endDirection;
  589. NavigationAgentTypeID agentTypeID;
  590. //Set beautify to false if you don't want to "beautify" the path (make it little less jagged, and more curvy)
  591. bool beautify;
  592. int forceTargetBuildingId;
  593. float endTolerance;
  594. float endDistance;
  595. bool allowDangerousDestination;
  596. };
  597. //////////////////////////////////////////////////////////////////////////
  598. //////////////////////////////////////////////////////////////////////////
  599. struct IMNMPathfinder
  600. {
  601. virtual ~IMNMPathfinder() {};
  602. //Request a path (look at MNMPathRequest for relevant request info). This request is queued and processed in a seperate
  603. //thread. The path result is sent to the callback function specified in the request. Returns an ID so you can cancel
  604. //the request.
  605. virtual MNM::QueuedPathID RequestPathTo(const IAIPathAgent* pRequester, const MNMPathRequest& request) = 0;
  606. // Returns a four-tuple: triangle ID and three vertices
  607. virtual const std::tuple<uint32, Vec3, Vec3, Vec3> GetCurrentNavTriangle(const IAIPathAgent* pRequester, NavigationAgentTypeID agentTypeID) const = 0;
  608. //Cancel a requested path by ID
  609. virtual void CancelPathRequest(MNM::QueuedPathID requestId) = 0;
  610. virtual bool CheckIfPointsAreOnStraightWalkableLine(const NavigationMeshID& meshID, const Vec3& source, const Vec3& destination, float heightOffset = 0.2f) const = 0;
  611. };