gwnavruntime/pathfollower/avoidancesolver.h Source File

avoidancesolver.h
Go to the documentation of this file.
1 /*
2 * Copyright 2015 Autodesk, Inc. All rights reserved.
3 * Use of this software is subject to the terms of the Autodesk license agreement and any attachments or Appendices thereto provided at the time of installation or download,
4 * or which otherwise accompanies this software in either electronic or hard copy form, or which is signed by you and accepted by Autodesk.
5 */
6 
7 // primary contact: MUBI - secondary contact: LAPA
8 #ifndef Navigation_AvoidanceSolver_H
9 #define Navigation_AvoidanceSolver_H
10 
14 #include "gwnavruntime/world/bot.h"
19 
20 
21 namespace Kaim
22 {
23 
24 class CosAndSinAngle;
25 
26 class NormalizedUtilityFunctionInfluenceRatios
27 {
28 public:
29  NormalizedUtilityFunctionInfluenceRatios(const AvoidanceConfig* avoidanceConfig)
30  {
31  const Kaim::AvoidanceUtilityFunctionConfig& utilityconfig = avoidanceConfig->m_utilityFunctionConfig;
32  KyFloat32 influenceSum =
33  utilityconfig.m_avoidanceInfluence +
34  utilityconfig.m_desiredVelocityInfluence +
35  utilityconfig.m_previousVelocityInfluence;
36 
37  KyFloat32 influenceSumInv = 1.0f / influenceSum;
38 
39  m_avoidanceInfluence = influenceSumInv * utilityconfig.m_avoidanceInfluence;
40  m_desiredVelocityInfluence = influenceSumInv * utilityconfig.m_desiredVelocityInfluence;
41  m_previousVelocityInfluence = influenceSumInv * utilityconfig.m_previousVelocityInfluence;
42  }
43 
44  KyFloat32 m_avoidanceInfluence;
45  KyFloat32 m_desiredVelocityInfluence;
46  KyFloat32 m_previousVelocityInfluence;
47 };
48 
49 typedef RayCastQueryResult(*PerformRaycastFromBotPositionCallback)
50  (const AvoidanceSolverConfig& config, const Vec2f& direction, KyFloat32 speed, KyFloat32 time,
51  LocalCostAwareTraverseLogicData& localCostAwareTraverseLogicData, Vec3f& collisionPos);
52 
53 typedef DiskCollisionQueryResult(*PerformDiskCollisionFromBotPositionCallback)
54  (const AvoidanceSolverConfig& config, KyFloat32 speed, KyFloat32 time, LocalCostAwareTraverseLogicData& localCostAwareTraverseLogicData);
55 
56 class VelocitySample
57 {
58 public:
59 
60  VelocitySample()
61  : m_normalizedDirection (0.0f, 0.0f)
62  , m_type (Avoidance_NoAvoidance)
63  , m_avoidanceScore (0.0f)
64  , m_desiredVelocityScore (0.0f)
65  , m_previousVelocityScore (0.0f)
66  , m_collisionTime (0.0f)
67  , m_colliderIndex (-1)
68  {}
69 
70  Vec2f m_normalizedDirection;
71  AvoidanceResult m_type;
72 
73  KyFloat32 m_avoidanceScore;
74  KyFloat32 m_desiredVelocityScore;
75  KyFloat32 m_previousVelocityScore;
76  KyFloat32 m_collisionTime;
77  KyInt32 m_colliderIndex; // if -1 no colliders, or static one (i.e. navmesh or channel borders)
78 
79  KyFloat32 ComputeFinalScore(const NormalizedUtilityFunctionInfluenceRatios& utilityFunctionRatios) const
80  {
81  return ((m_avoidanceScore * utilityFunctionRatios.m_avoidanceInfluence) +
82  (m_desiredVelocityScore * utilityFunctionRatios.m_desiredVelocityInfluence) +
83  (m_previousVelocityScore * utilityFunctionRatios.m_previousVelocityInfluence));
84  }
85 
86  // VelocitySamplesArray::ScoreForDistanceToDirection(desiredDirection, &VelocitySample::ScoreDesiredVelocity);
87  // => (velocitySample.*scoreFunction)(score);
88  // ScoreForDistanceToDirection(previousDirection, &VelocitySample::ScorePreviousVelocity);
89  void ScoreDesiredVelocity (KyFloat32 score) { m_desiredVelocityScore = score; }
90  void ScorePreviousVelocity(KyFloat32 score) { m_previousVelocityScore = score; }
91  typedef void(VelocitySample::*ScoreVelocityFunction)(KyFloat32);
92 
93  // Debugging functions
94  KyFloat32 GetAvoidanceScore (const NormalizedUtilityFunctionInfluenceRatios& ) const { return m_avoidanceScore; }
95  KyFloat32 GetDesiredVelocityScore (const NormalizedUtilityFunctionInfluenceRatios& ) const { return m_desiredVelocityScore; }
96  KyFloat32 GetPreviousVelocityScore (const NormalizedUtilityFunctionInfluenceRatios& ) const { return m_previousVelocityScore; }
97 
98  typedef KyFloat32(VelocitySample::*ScoreAccessorFunction)(const NormalizedUtilityFunctionInfluenceRatios&) const;
99 
100 public: // internal
101  void AdjustScoreAgainstChannel(const AvoidanceSolverConfig& config, KyFloat32 movingSpeed, KyFloat32 timeHorizon, RayCastInChannel& rayCastInChannel);
102  void AdjustScoreAgainstNavMesh(const AvoidanceSolverConfig& config, KyFloat32 movingSpeed, KyFloat32 timeHorizon,
103  LocalCostAwareTraverseLogicData& localCostAwareTraverseLogicData, PerformRaycastFromBotPositionCallback raycastFunction);
104 private:
105  void AdjustScoreToStaticObstacleCollision(const AvoidanceSolverConfig& config, KyFloat32 movingSpeed, KyFloat32 timeHorizon, const Vec2f& botPosition, const Vec2f& collisionPos);
106 };
107 
108 typedef KyArrayPOD<VelocitySample, MemStat_PathFollowing, Kaim::ArrayConstPolicy<0, 16, true> > VelocitySampleArrayType;
109 
110 class VelocitySampleArray
111 {
112 public:
113  void Clear();
114  void ComputeTurningVelocitiesSamples(const AvoidanceSolverConfig& config, const Vec2f& movingDirection, KyFloat32 timeHorizon);
115 
116  void ScoreForDistanceToDirection(const Vec2f& direction, VelocitySample::ScoreVelocityFunction scoreFunction);
117  void ScoreForPreviousDirection(const Vec2f& previousDirection, KyFloat32 previousSpeed);
118  KyUInt32 FindClosestSampleToDirection(const Vec2f& direction);
119  KyFloat32 SelectBestVelocitySample(const NormalizedUtilityFunctionInfluenceRatios& utilityFunctionRatios, const VelocitySample*& bestSample, const Vec2f& previousDirection);
120 
121  bool ScoreForAvoidance(const AvoidanceSolverConfig& config, KyFloat32 timeHorizon, KyFloat32 movingSpeed,
122  LocalCostAwareTraverseLogicData& localCostAwareTraverseLogicData, PerformRaycastFromBotPositionCallback raycastFunction,
123  PerformDiskCollisionFromBotPositionCallback diskCollisionFunction);
124 
125  void DebugDrawSample(ScopedDisplayList& displayList_Samples, const VelocitySample& velocitySample, const Vec3f& rootPosition,
126  VelocitySample::ScoreAccessorFunction scoreAccessorFunction, const NormalizedUtilityFunctionInfluenceRatios& utilityFunctionRatios, KyFloat32 movingSpeed);
127 
128  void DebugDrawSamples(const char* groupName, const char* displayListName, Kaim::Bot* bot, VelocitySample::ScoreAccessorFunction scoreAccessorFunction,
129  const NormalizedUtilityFunctionInfluenceRatios& utilityFunctionRatios, KyFloat32 movingSpeed);
130 
131  void DebugDrawSamplesCurve(const char* groupName, const char* displayListName, Kaim::Bot* bot, VelocitySample::ScoreAccessorFunction scoreAccessorFunction,
132  const NormalizedUtilityFunctionInfluenceRatios& utilityFunctionRatios, KyFloat32 movingSpeed);
133 
134  void DebugDraw(AvoidanceSolverConfig& config, const NormalizedUtilityFunctionInfluenceRatios& utilityFunctionRatios, const Vec2f& previousVelocity,
135  const Vec2f& desiredVelocity, const Vec2f& outputVelocity, const VelocitySample& noAvoidanceSample, const VelocitySample& favoriteSample, KyFloat32 movingSpeed);
136 
137 public:
138  VelocitySampleArrayType m_velocitySamples;
139 };
140 
141 
142 // what's is point of this AvoidanceSolverImplementation class ?
143 class AvoidanceSolverImplementation
144 {
145  KY_DEFINE_NEW_DELETE_OPERATORS(MemStat_PathFollowing)
146 
147 public:
148  AvoidanceSolverImplementation() {}
149 
150  AvoidanceResult Solve(AvoidanceSolverConfig& config, const Vec2f& previousVelocity, const Vec2f& desiredVelocity,
151  Vec2f& outputVelocity, Vec2f& outputFrontDirection, bool& collide,
152  PerformRaycastFromBotPositionCallback raycastFunction,
153  PerformDiskCollisionFromBotPositionCallback diskCollisionFunction);
154 
155  AvoidanceResult ComputeAvoidanceVelocity(
156  const Vec2f& previousVelocity, const Vec2f& desiredVelocity, Vec2f& outputVelocity, Vec2f& outputFrontDirection,
157  PerformRaycastFromBotPositionCallback raycastFunction,
158  PerformDiskCollisionFromBotPositionCallback diskCollisionFunction);
159 
160  void ComputeMovingDirection(Vec2f& movingDirection);
161 
162  KyFloat32 ComputeTimeHorizon(KyFloat32 movingSpeed);
163 
164  bool CapDirectionChangeAngle(const Vec2f& normalizedFrom, const Vec2f& normalizedTo, Vec2f& result, CosAndSinAngle& maxAngle);
165 
166  void SolveContact(const KyFloat32 maxSpeed, const Vec2f& avoidanceDirection, bool& hasCollided, Vec2f& collideSolveDirection, KyFloat32& finalSpeed);
167 
168  void CapAvoidanceVelocityChange(
169  const KyFloat32 previousSpeed, const bool hasCollided, const Vec2f& previousDirection, const KyFloat32 movingSpeed,
170  Vec2f& finalVelocityDirection, KyFloat32& finalSpeed, Vec2f& finalFrontDirection);
171 
172  bool IsDirectionValid(const Vec2f& direction, KyFloat32 speed, KyFloat32 time,
173  PerformRaycastFromBotPositionCallback raycastFunction,
174  LocalCostAwareTraverseLogicData& localCostAwareTraverseLogicData);
175 
176 private:
177  VelocitySampleArray m_velocitySamplesArray;
178  LocalCostAwareTraverseLogicData m_localCostAwareTraverseLogicData;
179 
180  AvoidanceSolverConfig m_config;
181  Vec2f m_previousVelocityDirection;
182  KyFloat32 m_previousSpeed;
183  Vec2f m_followVelocityDirection;
184  KyFloat32 m_followSpeed;
185 };
186 
189 template<class TraverseLogic>
190 class AvoidanceSolver : public IAvoidanceSolver
191 {
192  KY_DEFINE_NEW_DELETE_OPERATORS(MemStat_PathFollowing)
193 
194 public:
195  // ---------------------------------- Public Member Functions ----------------------------------
196  AvoidanceSolver()
197  {}
198 
205  virtual AvoidanceResult Solve(
206  AvoidanceSolverConfig& config, const Vec2f& previousVelocity, const Vec2f& desiredVelocity,
207  Vec2f& outputVelocity, Vec2f& outputFrontDirection, bool& collide);
208 
209 protected:
210  static DiskCollisionQueryResult PerformDiskCollisionFromBotPosition(
211  const AvoidanceSolverConfig& config, KyFloat32 speed, KyFloat32 time,
212  LocalCostAwareTraverseLogicData& localCostAwareTraverseLogicData);
213 
214  static RayCastQueryResult PerformRaycastFromBotPosition(
215  const AvoidanceSolverConfig& config, const Vec2f& direction, KyFloat32 speed, KyFloat32 time,
216  LocalCostAwareTraverseLogicData& localCostAwareTraverseLogicData, Vec3f& collisionPos);
217 
218  AvoidanceSolverImplementation m_impl;
219 };
220 
221 } // namespace Kaim
222 
224 
225 #endif // Navigation_AvoidanceSolver_H
This class is the world element that represent an active character in Gameware Navigation.
Definition: bot.h:150
The trajectory goes in target direction at the desired speed.
Definition: iavoidancecomputer.h:22
int KyInt32
Type used internally to represent a 32-bit integer.
Definition: types.h:35
DiskCollisionQueryResult
Enumerates the possible results of a DiskCollisionQuery.
Definition: basediskcollisionquery.h:21
AvoidanceResult
Enumerates the possible results of a call to IAvoidanceComputer::Compute().
Definition: iavoidancecomputer.h:20
RayCastQueryResult
Enumerates the possible results of a RayCastQuery.
Definition: baseraycastquery.h:29
Definition: gamekitcrowddispersion.h:20
#define KY_DEFINE_NEW_DELETE_OPERATORS(MemStat)
This macro defines new and delete operators.
Definition: memory.h:137
virtual AvoidanceResult Solve(AvoidanceSolverConfig &config, const Vec2f &previousVelocity, const Vec2f &desiredVelocity, Vec2f &outputVelocity, Vec2f &outputFrontDirection, bool &collide)
Compute the more appropriate velocity.
Definition: avoidancesolver.inl:12
unsigned int KyUInt32
Type used internally to represent an unsigned 32-bit integer.
Definition: types.h:36
float KyFloat32
Type used internally to represent a 32-bit floating-point number.
Definition: types.h:43