gwnavruntime/channel/channel.h Source File

channel.h
Go to the documentation of this file.
1 /*
2 * Copyright 2016 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 #pragma once
8 
11 
12 namespace Kaim
13 {
14 
15 class Bubble;
16 class ChannelBlob;
17 class DisplayListManager;
18 
21 {
23 
24  StartGate = 1,
25  EndGate = 2,
26 
31 
35  RightTurnEnd = 10,
36 
39 
40  GATE_TYPE_COUNT
41 };
42 
43 KY_INLINE bool IsALeftTurnGate(GateType gateType) { return gateType >= SmallLeftTurn && gateType <= LeftTurnEnd; }
44 KY_INLINE bool IsARightTurnGate(GateType gateType) { return gateType >= SmallRightTurn && gateType <= RightTurnEnd; }
45 KY_INLINE bool IsATurnGate(GateType gateType) { return gateType >= SmallLeftTurn && gateType <= RightTurnEnd; }
46 
49 {
51 
56 };
57 
60 {
61 public:
62  ChannelDisplayConfig() { SetDefaults(); }
63  void SetDefaults();
64 
65  bool m_displayChannelIndex;
66  bool m_displaySectionIndex;
67  bool m_displayGateIndex;
68  bool m_displayExtremityPolylines;
69  bool m_displayOutline;
70  bool m_displayGates;
71  bool m_displayPathEdges;
72  bool m_displayPathNodes;
73  bool m_displayGateTypeLabel;
74  bool m_displayGateTypeColor;
75  bool m_displayChannelWidthLeft;
76  bool m_displayChannelWidthRight;
77 
78  Color m_channelIndexColor;
79  Color m_sectionIndexColor;
80  Color m_gateIndexColor;
81  Color m_pathColor;
82  Color m_leftBorderColor;
83  Color m_rightBorderColor;
84  Color m_nodeColor;
85 
86  Color m_gateDefaultColor;
87  Color m_gateTypeColor[GATE_TYPE_COUNT];
88 
89  Color m_preChannelPolylineColor;
90  Color m_postChannelPolylineColor;
91 
92  Color m_channelWidthLeftColor;
93  Color m_channelWidthRightColor;
94 
95  static const char* GetGateTypeText(GateType gateType);
96 
97  KyFloat32 m_nodeRenderRadius;
98  KyFloat32 m_verticalOffset;
99  KyFloat32 m_gateHeight;
100 };
101 
103 class Gate
104 {
105 public:
106  Gate()
107  : m_type(UndefinedGateType)
108  , m_leftWidth(0.0f)
109  , m_rightWidth(0.0f)
110  {}
111 
112  Gate(const Vec3f& leftPos, const Vec3f& pathPos, const Vec3f& rightPos, GateType gateType)
113  : m_type(gateType)
114  , m_leftPos(leftPos)
115  , m_pathPos(pathPos)
116  , m_rightPos(rightPos)
117  , m_leftWidth(0.0f)
118  , m_rightWidth(0.0f)
119  {}
120 
121  void Clear()
122  {
123  m_type = UndefinedGateType;
124  m_leftPos.Clear();
125  m_pathPos.Clear();
126  m_rightPos.Clear();
127  m_leftWidth = 0.0f;
128  m_rightWidth = 0.0f;
129  }
130 
131  bool IsCollapsed() const { return m_leftPos == m_rightPos; }
132 
133  GateType m_type;
134  Vec3f m_leftPos;
135  Vec3f m_pathPos;
136  Vec3f m_rightPos;
137  KyFloat32 m_leftWidth;
138  KyFloat32 m_rightWidth;
139 };
140 
141 template <class OSTREAM>
142 inline OSTREAM& operator<<(OSTREAM& os, const Gate& g)
143 {
144  os << "[L=" << g.m_leftPos << ", O=" << g.m_pathPos << ", R=" << g.m_rightPos;
145  switch (g.m_type)
146  {
147  case UndefinedGateType : os << ", type=UndefinedGateType]"; break;
148  case StartGate : os << ", type=StartGate]"; break;
149  case EndGate : os << ", type=EndGate]"; break;
150  case SmallLeftTurn : os << ", type=SmallLeftTurn]"; break;
151  case LeftTurnStart : os << ", type=LeftTurnStart]"; break;
152  case LeftTurnIntermediary : os << ", type=LeftTurnIntermediary]"; break;
153  case LeftTurnEnd : os << ", type=LeftTurnEnd]"; break;
154  case SmallRightTurn : os << ", type=SmallRightTurn]"; break;
155  case RightTurnStart : os << ", type=RightTurnStart]"; break;
156  case RightTurnIntermediary: os << ", type=RightTurnIntermediary]"; break;
157  case RightTurnEnd : os << ", type=RightTurnEnd]"; break;
158  case WidthAdjustment : os << ", type=WidthAdjustment]"; break;
159  case ClampingAdjustment : os << ", type=ClampingAdjustment]"; break;
160  default: os << ", !!! wrong gate type (" << g.m_type << ") !!!]"; break;
161  }
162  return os;
163 }
164 
165 enum ChannelSide { ChannelLeftSide, ChannelRightSide }; // use struct Side { enum Enum { Left, Right }; };
166 
169 class Channel : public RefCountBase<Channel, MemStat_Channel>
170 {
171 public:
172  Channel() : m_firstPathNodeIdx(0) {}
173 
174  ~Channel() { Clear(); }
175 
176  // ------- Main API Functions --------
177 
178  KyUInt32 GetGateCount() const { return m_gates.GetCount(); }
179  const Gate& GetGate(KyUInt32 index) const { return m_gates[index]; }
180 
181  const KyArray<Vec2f>& GetPreChannelPolyline() const { return m_preChannelPolyline; }
182  const KyArray<Vec2f>& GetPostChannelPolyline() const { return m_postChannelPolyline; }
183 
184  KyUInt32 GetSectionCount() const { KyUInt32 count = GetGateCount(); return (count ? (count + 1) : 0); }
185  KyUInt32 GetLastSectionIdx() const { return m_gates.GetCount(); }
186  KyUInt32 GetSectionStartGateIdx(KyUInt32 sectionIdx) const { return Kaim::Max<KyUInt32>(sectionIdx, 1) - 1; }
187  KyUInt32 GetSectionEndGateIdx(KyUInt32 sectionIdx) const { return Kaim::Min<KyUInt32>(sectionIdx, GetGateCount() - 1); }
188  const Gate& GetSectionStartGate(KyUInt32 sectionIdx) const { return GetGate(GetSectionStartGateIdx(sectionIdx)); }
189  const Gate& GetSectionEndGate(KyUInt32 sectionIdx) const { return GetGate(GetSectionEndGateIdx(sectionIdx)); }
190 
193  const Vec3f& GetStartPos() const { return m_gates[0].m_pathPos; }
194 
197  const Vec3f& GetEndPos() const { return m_gates[GetGateCount() - 1].m_pathPos; }
198 
200  KyUInt32 GetFirstPathNodeIdx() const { return m_firstPathNodeIdx; }
201 
203  KyUInt32 GetGatePathNodeIdx(KyUInt32 gateIndex) const { return m_firstPathNodeIdx + gateIndex; }
204 
207  bool IsPositionInSection(const Vec2f& position, KyUInt32 sectionIndex, KyUInt32& positionFlags) const;
208 
210  bool IsPositionInSection(const Vec2f& position, KyUInt32 sectionIndex) const;
211 
214  KyResult GetSectionFromPositionAndSeed(const Kaim::Vec3f& previousPosition, KyUInt32 previousSectionIdx, const Kaim::Vec3f& newPosition, KyUInt32& newSectionIdx) const;
215 
218  KyResult GetSectionFromPositionAndSeed_AlongBubble(const Bubble& bubble, const Kaim::Vec3f& previousPosition, KyUInt32 previousSectionIdx, const Kaim::Vec3f& newPosition, KyUInt32& newSectionIdx) const;
219 
220  bool IsConcaveCorner(KyUInt32 gateIdx, ChannelSide side) const;
221 
222 public: // internal
223  KyResult GetSectionFromPositionAndSeed( const Kaim::Vec3f& prevPos, KyUInt32 prevSectionIdx, const Kaim::Vec3f& newPos, KyUInt32& newSectionIdx, KyFloat32 maxProgress) const;
224  KyResult GetSectionFromPositionAndSeed_Forward( const Kaim::Vec3f& prevPos, KyUInt32 prevGateIdx , const Kaim::Vec3f& newPos, KyUInt32& newGateIdx , KyFloat32 maxProgress) const;
225  KyResult GetSectionFromPositionAndSeed_Backward(const Kaim::Vec3f& prevPos, KyUInt32 prevGateIdx , const Kaim::Vec3f& newPos, KyUInt32& newGateIdx , KyFloat32 maxProgress) const;
226 
227  bool IntersectSegmentVsPreChannelPolyline( const Vec2f& A, const Vec2f& B, Vec2f& intersection) const { return IntersectSegmentVsPolyline(A, B, m_preChannelPolyline , intersection); }
228  bool IntersectSegmentVsPostChannelPolyline(const Vec2f& A, const Vec2f& B, Vec2f& intersection) const { return IntersectSegmentVsPolyline(A, B, m_postChannelPolyline, intersection); }
229 
230  void SendVisualDebug(DisplayListManager* displayListManager, const ChannelDisplayConfig& displayConfig = ChannelDisplayConfig(), KyUInt32 indexInChannelArray = 0, const char* listBaseName = "", const char* groupName = "Channel", KyUInt32 visualDebugId = KyUInt32MAXVAL) const;
231 
232  // -------- Creation functions ------
235 
236  KyResult InitFromBlob(const ChannelBlob& channelBlob);
237 
238  void Initialize() { Clear(); }
239  void Clear();
240  void AddGate(const Gate& gate) { m_gates.PushBack(gate); }
241  Gate& GetGate(KyUInt32 index) { return m_gates[index]; }
242  void SetPreChannelPolyline(const KyArray<Vec2f>& polyline) { m_preChannelPolyline = polyline; }
243  void SetPostChannelPolyline(const KyArray<Vec2f>& polyline) { m_postChannelPolyline = polyline; }
244  void SetPolylineFromBlob(const BlobArray<Vec2f>& polylineBlob, KyArray<Vec2f>& polyline);
245 
246  void SetFirstPathNodeIdx(KyUInt32 firstPathNodeIdx) { m_firstPathNodeIdx = firstPathNodeIdx; }
247 
248  KyResult ComputeChannelWidth();
249 
250 public: // internal : to be used with lot of precaution
251  // Computes if the given position is inside the polyline, with polyline being
252  // a function on its closure segment (for each point P along the polyline, its
253  // orthogonal projection M on the closure segment is so that [MP[ doesn't
254  // intersect the polyline.
255  // Beware to check if position is before the closure segment, if it is consider position out of polyline
256  // using Math::IsOnTheLeftOfSegment2d(position, polyline[0], polyline[polyline.GetCount()]).
257  bool IsInsidePolyline(const Vec2f& position, const KyArray<Vec2f>& polyline) const;
258 
259  bool IntersectSegmentVsPolyline(const Vec2f& A, const Vec2f& B, const KyArray<Vec2f>& polyline, Vec2f& intersection) const;
260  bool IsPositionWithinSectionBorders(const Vec2f& newPos2d, const Vec2f& A, const Vec2f& B, const Vec2f& C, const Vec2f& D) const;
261 
262  KyResult ComputeChannelWidth_GateLeftCorner(KyUInt32 gateIdx);
263  KyResult ComputeChannelWidth_LeftSideForward(KyUInt32 gateIdx, const Vec2f& computedGateLeftPos2d, const Vec2f& computedGateRightPos2d, KyFloat32& gateLeftSquareWidth);
264  KyResult ComputeChannelWidth_LeftSideBackward(KyUInt32 gateIdx, const Vec2f& computedGateLeftPos2d, const Vec2f& computedGateRightPos2d, KyFloat32& gateLeftSquareWidth);
265 
266  KyResult ComputeChannelWidth_GateRightCorner(KyUInt32 gateIdx);
267  KyResult ComputeChannelWidth_RightSideForward(KyUInt32 gateIdx, const Vec2f& computedGateLeftPos2d, const Vec2f& computedGateRightPos2d, KyFloat32& gateRightSquareWidth);
268  KyResult ComputeChannelWidth_RightSideBackward(KyUInt32 gateIdx, const Vec2f& computedGateLeftPos2d, const Vec2f& computedGateRightPos2d, KyFloat32& gateRightSquareWidth);
269 
270 public: // internal
271  KyArray<Gate> m_gates;
272  KyArray<Vec2f> m_preChannelPolyline;
273  KyArray<Vec2f> m_postChannelPolyline;
274  KyUInt32 m_firstPathNodeIdx;
275 };
276 
277 KY_INLINE void Channel::Clear()
278 {
279  m_gates.Clear();
280  m_preChannelPolyline.Clear();
281  m_postChannelPolyline.Clear();
282 }
283 
284 KY_INLINE bool Channel::IsPositionInSection(const Vec2f& position, KyUInt32 sectionIndex) const
285 {
286  KyUInt32 unusedPositionFlags;
287  return IsPositionInSection(position, sectionIndex, unusedPositionFlags);
288 }
289 
290 } // namespace Kaim
291 
Indicates the Gate is the start of a sampled turn to the left (CCW). The next Gate must have either L...
Definition: channel.h:28
Position is outside the section: it lays on the left of the left Border.
Definition: channel.h:54
Class that configures the Channel visual debug display.
Definition: channel.h:59
Indicates the Gate is a right turn end.
Definition: channel.h:35
const Vec3f & GetEndPos() const
Returns the channel end position, i.e.
Definition: channel.h:197
GateType
Enumerates the different kind of Gates.
Definition: channel.h:20
Indicates the Gate is a left turn end.
Definition: channel.h:30
std::uint32_t KyUInt32
uint32_t
Definition: types.h:29
Indicates the Gate is a sampled left turn intermediary Gate.
Definition: channel.h:29
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...
Definition: channel.cpp:323
KyUInt32 GetGatePathNodeIdx(KyUInt32 gateIndex) const
Return PathNodeIdx of the gate at gateIndex.
Definition: channel.h:203
Indicates the Gate is the start of a sampled turn to the right (CW). The next Gate must have either R...
Definition: channel.h:33
Indicates the Gate is not defined.
Definition: channel.h:22
General purpose array for movable objects that require explicit construction/destruction.
Definition: kyarray.h:162
bool IsPositionInSection(const Vec2f &position, KyUInt32 sectionIndex, KyUInt32 &positionFlags) const
Checks a provided 2D position is inside a channel section.
Definition: channel.cpp:114
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...
Definition: channel.cpp:287
Indicates the Gate is a small turn to the left (CCW).
Definition: channel.h:27
Position is outside the section: it lays before the section start Gate.
Definition: channel.h:52
Indicates the Gate is a Channel start Gate.
Definition: channel.h:24
RelativePositionToChannelSectionFlag
Enumerates the Channel::IsPositionInSection relative position flags.
Definition: channel.h:48
This class represents a circle with potential rotation limitation.
Definition: bubble.h:31
2d vector using KyFloat32.
Definition: vec2f.h:18
Position is outside the section: it lays after the section end Gate.
Definition: channel.h:53
Indicates the Gate is a Channel width adjustment Gate. There is no direction modification there...
Definition: channel.h:37
Navigation return code class.
Definition: types.h:108
KyResult InitFromBlob(const ChannelBlob &channelBlob)
These functions are expected to be used internally in Channel computation classes.
Definition: channel.cpp:621
The Autodesk Navigation namespace.
Definition: gamekitcrowddispersion.cpp:17
const Vec3f & GetStartPos() const
Returns the channel start position, i.e.
Definition: channel.h:193
Channel enrich Path with clearance information on each side of the Path.
Definition: channel.h:169
RGBA color.
Definition: color.h:16
KyUInt32 GetFirstPathNodeIdx() const
Return PathNodeIdx of the first gate.
Definition: channel.h:200
Position is inside the section.
Definition: channel.h:50
Indicates the Gate is a small turn to the right (clockwise).
Definition: channel.h:32
Indicates the Gate is a Channel end Gate.
Definition: channel.h:25
This class represents Channel section limit segment. See Channel class description.
Definition: channel.h:103
void Clear()
Sets x=0.0f, y=0.0f and z=0.0f.
Definition: vec3f.h:34
Indicates the Gate is a Channel altitude clamping adjustment Gate. There is no direction modification...
Definition: channel.h:38
Indicates the Gate is a sampled right turn intermediary Gate.
Definition: channel.h:34
Position is outside the section: it lays on the right of the right Border.
Definition: channel.h:55
#define KyUInt32MAXVAL
KyUInt32 max value
Definition: types.h:68
float KyFloat32
float
Definition: types.h:32
3d vector using 32bits floating points.
Definition: vec3f.h:16