gwnavruntime/channel/channel.h Source File

channel.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 #ifndef Navigation_Channel_H
8 #define Navigation_Channel_H
9 
12 
13 
14 namespace Kaim
15 {
16 
17 class World;
18 class Bubble;
19 class ChannelBlob;
20 
21 
24 {
26 
27  StartGate = 1,
28  EndGate = 2,
29 
34 
38  RightTurnEnd = 10,
39 
42 
43  GATE_TYPE_COUNT
44 };
45 
46 KY_INLINE bool IsALeftTurnGate(GateType gateType) { return gateType >= SmallLeftTurn && gateType <= LeftTurnEnd; }
47 KY_INLINE bool IsARightTurnGate(GateType gateType) { return gateType >= SmallRightTurn && gateType <= RightTurnEnd; }
48 KY_INLINE bool IsATurnGate(GateType gateType) { return gateType >= SmallLeftTurn && gateType <= RightTurnEnd; }
49 
50 
53 {
55 
60 };
61 
62 
65 {
66 public:
67  ChannelDisplayConfig() { SetDefaults(); }
68  void SetDefaults();
69 
70  bool m_displayChannelIndex;
71  bool m_displaySectionIndex;
72  bool m_displayGateIndex;
73  bool m_displayExtremityPolylines;
74  bool m_displayOutline;
75  bool m_displayGates;
76  bool m_displayPathEdges;
77  bool m_displayPathNodes;
78  bool m_displayGateTypeLabel;
79  bool m_displayGateTypeColor;
80  bool m_displayChannelWidthLeft;
81  bool m_displayChannelWidthRight;
82 
83  VisualColor m_channelIndexColor;
84  VisualColor m_sectionIndexColor;
85  VisualColor m_gateIndexColor;
86  VisualColor m_pathColor;
87  VisualColor m_leftBorderColor;
88  VisualColor m_rightBorderColor;
89  VisualShapeColor m_nodeColor;
90 
91  VisualColor m_gateDefaultColor;
92  VisualColor m_gateTypeColor[GATE_TYPE_COUNT];
93 
94  VisualColor m_preChannelPolylineColor;
95  VisualColor m_postChannelPolylineColor;
96 
97  VisualShapeColor m_channelWidthLeftColor;
98  VisualShapeColor m_channelWidthRightColor;
99 
100  static const char* GetGateTypeText(GateType gateType);
101 
102  KyFloat32 m_nodeRenderRadius;
103  KyFloat32 m_verticalOffset;
104  KyFloat32 m_gateHeight;
105 };
106 
108 class Gate
109 {
110 public:
111  Gate()
112  : m_type(UndefinedGateType)
113  , m_leftWidth(0.0f)
114  , m_rightWidth(0.0f)
115  {}
116 
117  Gate(const Vec3f& leftPos, const Vec3f& pathPos, const Vec3f& rightPos, GateType gateType)
118  : m_type(gateType)
119  , m_leftPos(leftPos)
120  , m_pathPos(pathPos)
121  , m_rightPos(rightPos)
122  , m_leftWidth(0.0f)
123  , m_rightWidth(0.0f)
124  {}
125 
126  GateType m_type;
127  Vec3f m_leftPos;
128  Vec3f m_pathPos;
129  Vec3f m_rightPos;
130  KyFloat32 m_leftWidth;
131  KyFloat32 m_rightWidth;
132 };
133 
134 template <class OSTREAM>
135 inline OSTREAM& operator<<(OSTREAM& os, const Gate& g)
136 {
137  os << "[l=" << g.m_leftPos << ", p=" << g.m_pathPos << ", r=" << g.m_rightPos;
138  switch (g.m_type)
139  {
140  case UndefinedGateType : os << ", type=UndefinedGateType ]"; break;
141  case StartGate : os << ", type=StartGate ]"; break;
142  case EndGate : os << ", type=EndGate ]"; break;
143  case SmallLeftTurn : os << ", type=SmallLeftTurn ]"; break;
144  case LeftTurnStart : os << ", type=LeftTurnStart ]"; break;
145  case LeftTurnIntermediary : os << ", type=LeftTurnIntermediary ]"; break;
146  case LeftTurnEnd : os << ", type=LeftTurnEnd ]"; break;
147  case SmallRightTurn : os << ", type=SmallRightTurn ]"; break;
148  case RightTurnStart : os << ", type=RightTurnStart ]"; break;
149  case RightTurnIntermediary: os << ", type=RightTurnIntermediary]"; break;
150  case RightTurnEnd : os << ", type=RightTurnEnd ]"; break;
151  case WidthAdjustment : os << ", type=WidthAdjustment ]"; break;
152  case ClampingAdjustment : os << ", type=ClampingAdjustment ]"; break;
153 
154  default: os << ", !!! wrong gate type (" << g.m_type << ") !!!]"; break;
155  }
156 
157  return os;
158 }
159 
160 
161 enum ChannelSide
162 {
163  ChannelLeftSide,
164  ChannelRightSide
165 };
166 
167 
168 
169 
174 class Channel : public RefCountBase<Channel, MemStat_Channel>
175 {
176 public:
178  : m_firstPathNodeIdx(0)
179  {}
180 
181  ~Channel();
182 
183 
184  // ------- Main API Functions --------
185 
186  KyUInt32 GetGateCount() const;
187  const Gate& GetGate(KyUInt32 index) const;
188 
189  const KyArray<Vec2f>& GetPreChannelPolyline() const;
190  const KyArray<Vec2f>& GetPostChannelPolyline() const;
191 
192  KyUInt32 GetSectionCount() const; // GateCount + 1
193  KyUInt32 GetLastSectionIdx() const; // (SectionCount - 1) = GateCount
194  KyUInt32 GetSectionStartGateIdx(KyUInt32 sectionIdx) const;
195  KyUInt32 GetSectionEndGateIdx(KyUInt32 sectionIdx) const;
196  const Gate& GetSectionStartGate(KyUInt32 sectionIdx) const;
197  const Gate& GetSectionEndGate(KyUInt32 sectionIdx) const;
198 
201  const Vec3f& GetEndPos() const;
202 
205 
207  KyUInt32 GetGatePathNodeIdx(KyUInt32 gateIndex) const;
208 
211  bool IsPositionInSection(const Vec2f& position, KyUInt32 sectionIndex, KyUInt32& positionFlags) const;
212 
214  bool IsPositionInSection(const Vec2f& position, KyUInt32 sectionIndex) const;
215 
218  KyResult GetSectionFromPositionAndSeed(const Kaim::Vec3f& previousPosition, KyUInt32 previousSectionIdx, const Kaim::Vec3f& newPosition, KyUInt32& newSectionIdx) const;
219 
222  KyResult GetSectionFromPositionAndSeed_AlongBubble(const Bubble& bubble, const Kaim::Vec3f& previousPosition, KyUInt32 previousSectionIdx, const Kaim::Vec3f& newPosition, KyUInt32& newSectionIdx) const;
223 
224  bool IsConcaveCorner(KyUInt32 gateIdx, ChannelSide side) const;
225 
226 public: // internal
227  KyResult GetSectionFromPositionAndSeed(const Kaim::Vec3f& previousPosition, KyUInt32 previousSectionIdx, const Kaim::Vec3f& newPosition, KyUInt32& newSectionIdx, KyFloat32 maxProgress) const;
228  KyResult GetSectionFromPositionAndSeed_Forward(const Kaim::Vec3f& previousPosition, KyUInt32 previousGateIdx, const Kaim::Vec3f& newPosition, KyUInt32& newGateIdx, KyFloat32 maxProgress) const;
229  KyResult GetSectionFromPositionAndSeed_Backward(const Kaim::Vec3f& previousPosition, KyUInt32 previousGateIdx, const Kaim::Vec3f& newPosition, KyUInt32& newGateIdx, KyFloat32 maxProgress) const;
230 
231  bool IntersectSegmentVsPreChannelPolyline(const Vec2f& A, const Vec2f& B, Vec2f& intersection) const;
232  bool IntersectSegmentVsPostChannelPolyline(const Vec2f& A, const Vec2f& B, Vec2f& intersection) const;
233 
234  void SendVisualDebug(World* navWorld, const ChannelDisplayConfig& displayConfig = ChannelDisplayConfig(), KyUInt32 indexInChannelArray = 0, const char* listBaseName = "", const char* groupName = "Channel", KyUInt32 visualDebugId = KyUInt32MAXVAL) const;
235 
236  // -------- Creation functions ------
239 
240  KyResult InitFromBlob(const ChannelBlob& channelBlob);
241 
242  void Initialize();
243  void Clear();
244  void AddGate(const Gate& gate);
245  Gate& GetGate(KyUInt32 index);
246  void SetPreChannelPolyline(const KyArray<Vec2f>& polyline);
247  void SetPostChannelPolyline(const KyArray<Vec2f>& polyline);
248  void SetPolylineFromBlob(const BlobArray<Vec2f>& polylineBlob, KyArray<Vec2f>& polyline);
249 
250  void SetFirstPathNodeIdx(KyUInt32 firstPathNodeIdx) { m_firstPathNodeIdx = firstPathNodeIdx; }
251 
252  KyResult ComputeChannelWidth();
253 
254 public: // internal : to be used with lot of precaution
255  // Computes if the given position is inside the polyline, with polyline being
256  // a function on its closure segment (for each point P along the polyline, its
257  // orthogonal projection M on the closure segment is so that [MP[ doesn't
258  // intersect the polyline.
259  // Beware to check if position is before the closure segment, if it is consider position out of polyline
260  // using Intersections::IsOnTheLeftOfSegment2d(position, polyline[0], polyline[polyline.GetCount()]).
261  bool IsInsidePolyline(const Vec2f& position, const KyArray<Vec2f>& polyline) const;
262 
263  bool IntersectSegmentVsPolyline(const Vec2f& A, const Vec2f& B, const KyArray<Vec2f>& polyline, Vec2f& intersection) const;
264  bool IsPositionWithinSectionBorders(const Vec2f& newPos2d, const Vec2f& A, const Vec2f& B, const Vec2f& C, const Vec2f& D) const;
265 
266  KyResult ComputeChannelWidth_GateLeftCorner(KyUInt32 gateIdx);
267  KyResult ComputeChannelWidth_LeftSideForward(KyUInt32 gateIdx, const Vec2f& computedGateLeftPos2d, const Vec2f& computedGateRightPos2d, KyFloat32& gateLeftSquareWidth);
268  KyResult ComputeChannelWidth_LeftSideBackward(KyUInt32 gateIdx, const Vec2f& computedGateLeftPos2d, const Vec2f& computedGateRightPos2d, KyFloat32& gateLeftSquareWidth);
269 
270  KyResult ComputeChannelWidth_GateRightCorner(KyUInt32 gateIdx);
271  KyResult ComputeChannelWidth_RightSideForward(KyUInt32 gateIdx, const Vec2f& computedGateLeftPos2d, const Vec2f& computedGateRightPos2d, KyFloat32& gateRightSquareWidth);
272  KyResult ComputeChannelWidth_RightSideBackward(KyUInt32 gateIdx, const Vec2f& computedGateLeftPos2d, const Vec2f& computedGateRightPos2d, KyFloat32& gateRightSquareWidth);
273 
274 public: // internal
275  KyArray<Gate> m_gates;
276  KyArray<Vec2f> m_preChannelPolyline;
277  KyArray<Vec2f> m_postChannelPolyline;
278  KyUInt32 m_firstPathNodeIdx;
279 };
280 
281 KY_INLINE Channel::~Channel() { Clear(); }
282 
283 KY_INLINE KyUInt32 Channel::GetGateCount() const { return m_gates.GetCount(); }
284 KY_INLINE const Gate& Channel::GetGate(KyUInt32 index) const { return m_gates[index]; }
285 
286 KY_INLINE const KyArray<Vec2f>& Channel::GetPreChannelPolyline() const { return m_preChannelPolyline; }
287 KY_INLINE const KyArray<Vec2f>& Channel::GetPostChannelPolyline() const { return m_postChannelPolyline; }
288 
289 KY_INLINE KyUInt32 Channel::GetSectionCount() const { KyUInt32 count = GetGateCount(); return (count ? (count + 1) : 0); }
290 KY_INLINE KyUInt32 Channel::GetLastSectionIdx() const { return m_gates.GetCount(); }
291 KY_INLINE KyUInt32 Channel::GetSectionStartGateIdx(KyUInt32 sectionIdx) const { return Kaim::Max<KyUInt32>(sectionIdx, 1) - 1; }
292 KY_INLINE KyUInt32 Channel::GetSectionEndGateIdx(KyUInt32 sectionIdx) const { return Kaim::Min<KyUInt32>(sectionIdx, GetGateCount() - 1); }
293 KY_INLINE const Gate& Channel::GetSectionStartGate(KyUInt32 sectionIdx) const { return GetGate(GetSectionStartGateIdx(sectionIdx)); }
294 KY_INLINE const Gate& Channel::GetSectionEndGate(KyUInt32 sectionIdx) const { return GetGate(GetSectionEndGateIdx(sectionIdx)); }
295 
296 KY_INLINE const Vec3f& Channel::GetEndPos() const { return m_gates[GetGateCount() - 1].m_pathPos; }
297 
298 KY_INLINE bool Channel::IntersectSegmentVsPreChannelPolyline(const Vec2f& A, const Vec2f& B, Vec2f& intersection) const { return IntersectSegmentVsPolyline(A, B, m_preChannelPolyline , intersection); }
299 KY_INLINE bool Channel::IntersectSegmentVsPostChannelPolyline(const Vec2f& A, const Vec2f& B, Vec2f& intersection) const { return IntersectSegmentVsPolyline(A, B, m_postChannelPolyline, intersection); }
300 
301 KY_INLINE void Channel::Initialize() { Clear(); }
302 
303 KY_INLINE void Channel::Clear()
304 {
305  m_gates.Clear();
306  m_preChannelPolyline.Clear();
307  m_postChannelPolyline.Clear();
308 }
309 
310 KY_INLINE void Channel::AddGate(const Gate& gate) { m_gates.PushBack(gate); }
311 KY_INLINE Gate& Channel::GetGate(KyUInt32 index) { return m_gates[index]; }
312 
313 KY_INLINE void Channel::SetPreChannelPolyline(const KyArray<Vec2f>& polyline) { m_preChannelPolyline = polyline; }
314 KY_INLINE void Channel::SetPostChannelPolyline(const KyArray<Vec2f>& polyline) { m_postChannelPolyline = polyline; }
316 KY_INLINE KyUInt32 Channel::GetFirstPathNodeIdx() const { return m_firstPathNodeIdx; }
317 KY_INLINE KyUInt32 Channel::GetGatePathNodeIdx(KyUInt32 gateIndex) const { return m_firstPathNodeIdx + gateIndex; }
318 
319 KY_INLINE bool Channel::IsPositionInSection(const Vec2f& position, KyUInt32 sectionIndex) const
320 {
321  KyUInt32 unusedPositionFlags;
322  return IsPositionInSection(position, sectionIndex, unusedPositionFlags);
323 }
324 
325 } // namespace Kaim
326 
327 #endif // Navigation_Channel_H
Indicates the Gate is the start of a sampled turn to the left (CCW). The next Gate must have either L...
Definition: channel.h:31
Position is outside the section: it lays on the left of the left Border.
Definition: channel.h:58
Classes that configures the Channel visual debug display.
Definition: channel.h:64
Indicates the Gate is a right turn end.
Definition: channel.h:38
KyInt32 KyResult
Defines a type that can be returned by methods or functions in the Gameware Navigation SDK to indicat...
Definition: types.h:254
GateType
Enumerates the different kind of Gates.
Definition: channel.h:23
Indicates the Gate is a left turn end.
Definition: channel.h:33
Indicates the Gate is a sampled left turn intermediary Gate.
Definition: channel.h:32
KyResult GetSectionFromPositionAndSeed_AlongBubble(const Bubble &bubble, const Kaim::Vec3f &previousPosition, KyUInt32 previousSectionIdx, const Kaim::Vec3f &newPosition, KyUInt32 &newSectionIdx) const
Given a previous position and its section, computes the section for a new position that is supposed t...
KyUInt32 GetGatePathNodeIdx(KyUInt32 gateIndex) const
Return PathNodeIdx of the gate at gateIndex.
Definition: channel.h:336
Indicates the Gate is the start of a sampled turn to the right (CW). The next Gate must have either R...
Definition: channel.h:36
Indicates the Gate is not defined.
Definition: channel.h:25
General purpose array for movable objects that require explicit construction/destruction.
Definition: kyarray.h:118
bool IsPositionInSection(const Vec2f &position, KyUInt32 sectionIndex, KyUInt32 &positionFlags) const
Checks a provided 2D position is inside a channel section.
KyResult GetSectionFromPositionAndSeed(const Kaim::Vec3f &previousPosition, KyUInt32 previousSectionIdx, const Kaim::Vec3f &newPosition, KyUInt32 &newSectionIdx) const
Given a previous position and its section, computes the section for a new position that is supposed t...
Represents a single RGBA color.
Definition: visualcolor.h:19
Indicates the Gate is a small turn to the left (CCW).
Definition: channel.h:30
This class is a runtime container for Gameware Navigation WorldElements such as NavData, Bots, BoxObstacles, TagVolumes...
Definition: world.h:54
Position is outside the section: it lays before the section start Gate.
Definition: channel.h:56
Indicates the Gate is a Channel start Gate.
Definition: channel.h:27
RelativePositionToChannelSectionFlag
Enumerates the Channel::IsPositionInSection relative position flags.
Definition: channel.h:52
This class represents a circle with potential rotation limitation.
Definition: bubble.h:35
const Vec3f & GetEndPos() const
Returns the channel end position, i.e.
Definition: channel.h:315
This class defines a two-dimensional vector whose coordinates are stored using floating-point numbers...
Definition: vec2f.h:24
Position is outside the section: it lays after the section end Gate.
Definition: channel.h:57
Indicates the Gate is a Channel width adjustment Gate. There is no direction modification there...
Definition: channel.h:40
A BlobArray an array that is compatible with the blob serialization framework.
Definition: blobarray.h:28
Definition: gamekitcrowddispersion.h:20
Channels define preferred navigation areas around an original Path section on NavMesh.
Definition: channel.h:177
KyUInt32 GetFirstPathNodeIdx() const
Return PathNodeIdx of the first gate.
Definition: channel.h:335
Position is inside the section.
Definition: channel.h:54
Indicates the Gate is a small turn to the right (clockwise).
Definition: channel.h:35
Indicates the Gate is a Channel end Gate.
Definition: channel.h:28
This class represents Channel section limit segment. See Channel class description.
Definition: channel.h:109
unsigned int KyUInt32
Type used internally to represent an unsigned 32-bit integer.
Definition: types.h:36
Indicates the Gate is a Channel altitude clamping adjustment Gate. There is no direction modification...
Definition: channel.h:41
Indicates the Gate is a sampled right turn intermediary Gate.
Definition: channel.h:37
Position is outside the section: it lays on the right of the right Border.
Definition: channel.h:59
#define KyUInt32MAXVAL
The maximum value that can be stored in the KyUInt32 variable type.
Definition: types.h:226
float KyFloat32
Type used internally to represent a 32-bit floating-point number.
Definition: types.h:43
This class defines a three-dimensional vector whose coordinates are stored using floating-point numbe...
Definition: vec3f.h:23