gwnavruntime/channel/diagonalstrip.h Source File

diagonalstrip.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_DiagonalStrip_H
8 #define Navigation_DiagonalStrip_H
9 
11 
15 
16 
17 namespace Kaim
18 {
19 
20 class World;
21 
22 //class DisplayListToggle
23 //{
24 //public:
25 // enum ToggleValue
26 // {
27 // ShowByDefault,
28 // SendButDontShow,
29 // DontSend
30 // };
31 //
32 // DisplayListToggle()
33 // : m_toggleValue(ShowByDefault)
34 // {}
35 //
36 // bool MustBeSent() const { return (m_toggleValue != DontSend); }
37 // bool MustNotBeShown() const { return (m_toggleValue != ShowByDefault); }
38 //
39 // ToggleValue m_toggleValue;
40 //};
41 
43 //
44 // DiagonalStripDisplayConfig
45 //
47 class DiagonalStripPersistentDisplayListIds
48 {
49 public:
50  DiagonalStripPersistentDisplayListIds()
51  : m_world(KY_NULL)
52  , m_singleFrame(true)
53  , m_displayListId_Left(KyUInt32MAXVAL)
54  , m_displayListId_Right(KyUInt32MAXVAL)
55  , m_displayListId_Corners(KyUInt32MAXVAL)
56  , m_displayListId_NearestOpposite(KyUInt32MAXVAL)
57  , m_displayListId_DiskToNearestOpposite(KyUInt32MAXVAL)
58  , m_displayListId_Diagonals(KyUInt32MAXVAL)
59  , m_displayListId_CornerIdx(KyUInt32MAXVAL)
60  , m_displayListId_Triangles(KyUInt32MAXVAL)
61  {}
62 
63  ~DiagonalStripPersistentDisplayListIds() {}
64 
65  void Initialize(World* world);
66  void Release();
67 
68 public:
69  World* m_world;
70  bool m_singleFrame;
71 
72  KyUInt32 m_displayListId_Left;
73  KyUInt32 m_displayListId_Right;
74  KyUInt32 m_displayListId_Corners;
75  KyUInt32 m_displayListId_NearestOpposite;
76  KyUInt32 m_displayListId_DiskToNearestOpposite;
77  KyUInt32 m_displayListId_Diagonals;
78  KyUInt32 m_displayListId_CornerIdx;
79  KyUInt32 m_displayListId_Triangles;
80 };
81 
82 class DiagonalStripDisplayConfig
83 {
84 public:
85  DiagonalStripDisplayConfig() { SetDefaults(); }
86  void SetDefaults();
87 
88  //DisplayListToggle m_toggleCorners;
89  //DisplayListToggle m_toggleCornerIdx;
90  //DisplayListToggle m_toggleCornerNearest;
91  //DisplayListToggle m_toggleDiagonals;
92  //DisplayListToggle m_toggleTriangles;
93 
94  KyFloat32 m_contourVerticalOffset;
95  VisualShapeColor m_triangleColor;
96  VisualShapeColor m_leftColor;
97  VisualShapeColor m_rightColor;
98  VisualShapeColor m_cornerDiskColor;
99  VisualShapeColor m_diagonalColor;
100 
101  DiagonalStripPersistentDisplayListIds m_persistentDisplayListIds;
102 };
103 
104 
106 //
107 // StripCorner
108 //
110 enum CornerType
111 {
112  UndefinedCornerType, // only when not initialized.
113  PathStart, // used only in string pulled path
114  PathEnd, // used only in string pulled path
115  LeftSide,
116  RightSide
117 };
118 
119 class StripCorner
120 {
121 public:
122  StripCorner()
123  : m_cornerType(UndefinedCornerType)
124  , m_maxRadius(0.0f)
125  {}
126 
127  StripCorner(const Vec3f& position, CornerType cornerType, KyFloat32 maxRadius)
128  {
129  Set(position, cornerType, maxRadius);
130  }
131 
132  static CornerType GetOppositeSide(CornerType cornerType)
133  {
134  switch (cornerType)
135  {
136  case LeftSide: return RightSide;
137  case RightSide: return LeftSide;
138  default: return cornerType;
139  }
140  }
141 
142  void Set(const Vec3f& position, CornerType cornerType, KyFloat32 maxRadius)
143  {
144  m_position = position;
145  m_cornerType = cornerType;
146  m_maxRadius = maxRadius;
147  m_oppositeNearestPositionIsSet = false;
148  }
149 
150  void SetCornerNearestOppositePosition(const Vec3f& nearestOppositePosition)
151  {
152  SetMaxRadius(0.49f * Distance2d(m_position, nearestOppositePosition));
153  m_oppositeNearestPosition = nearestOppositePosition;
154  m_oppositeNearestPositionIsSet = true;
155  }
156 
157  void SetMaxRadius(KyFloat32 maxRadius)
158  {
159  m_maxRadius = maxRadius;
160  }
161 
162  void PreciseType(CornerType cornerType) { m_cornerType = cornerType; }
163 
164  const Vec3f& GetPosition() const { return m_position; }
165  CornerType GetCornerType() const { return m_cornerType; }
166  KyFloat32 GetMaxRadius() const { return m_maxRadius; }
167 
168  bool IsOppositeNearestPositionSet() const { return m_oppositeNearestPositionIsSet; }
169  const Vec3f& GetOppositeNearestPosition() const { return m_oppositeNearestPosition; }
170 
171  bool IsValid() const
172  {
173  return (m_cornerType != UndefinedCornerType);
174  }
175 
176 
177 public:
178  friend class DiagonalStrip;
179 
180  Vec3f m_position;
181  CornerType m_cornerType;
182  KyFloat32 m_maxRadius;
183 
184  Vec3f m_oppositeNearestPosition;
185  bool m_oppositeNearestPositionIsSet;
186 };
187 
188 KY_INLINE RotationDirection GetBubbleRotationDirectionFromCornerType(CornerType cornerType)
189 {
190  return
191  (cornerType == LeftSide) ? CounterClockwise :
192  (cornerType == RightSide) ? Clockwise :
193  UndefinedRotationDirection;
194 }
195 
196 KY_INLINE FunnelSide GetFunnelSideFromCornerType(CornerType cornerType)
197 {
198  return
199  (cornerType == LeftSide) ? FunnelLeft :
200  (cornerType == RightSide) ? FunnelRight :
201  FunnelBothSides;
202 }
203 
204 
205 class NearestOppositePositionUpdator
206 {
207 public:
208  NearestOppositePositionUpdator(const Vec3f& position)
209  : m_position(position)
210  , m_nearestPosition(KyFloat32MAXVAL, KyFloat32MAXVAL, KyFloat32MAXVAL)
211  , m_minSqDist(KyFloat32MAXVAL)
212  {}
213 
214  void UpdateWithOppositeSegment(const Vec3f& A, const Vec3f& B);
215 
216  Vec3f m_position;
217  Vec3f m_nearestPosition;
218  KyFloat32 m_minSqDist;
219 };
220 
222 //
223 // DiagonalStrip
224 //
226 class DiagonalStrip
227 {
228 public:
229  enum GetBorderResult
230  {
231  BorderFound,
232  BorderNotFound,
233  NearestFoundIsStartOrEnd,
234  AskedCornerIsDiagonalStripStartOrEnd
235  };
236 
237  DiagonalStrip()
238  {
239  }
240 
241  void PushBackCorner(const Vec3f& position, CornerType cornerType, KyFloat32 maxRadius)
242  {
243  StripCorner corner(position, cornerType, maxRadius);
244  m_corners.PushBack(corner);
245  }
246 
247  void Clear();
248  void SendVisualDebug(World* navWorld, DiagonalStripDisplayConfig& displayConfig);
249 
250  bool IsEmpty() const { return m_corners.IsEmpty(); }
251  KyUInt32 GetCornerCount() const { return m_corners.GetCount(); }
252  const StripCorner& GetCorner(KyUInt32 cornerIdx) const { return m_corners[cornerIdx]; }
253  StripCorner& GetCorner(KyUInt32 cornerIdx) { return m_corners[cornerIdx]; }
254 
255  KyUInt32 GetIncomingBorderStartIdx(KyUInt32 cornerIdx) const;
256  KyUInt32 GetOutgoingBorderEndIdx(KyUInt32 cornerIdx) const;
257  StripCorner GetIncomingBorderStart(KyUInt32 cornerIdx) const;
258  StripCorner GetOutgoingBorderEnd(KyUInt32 cornerIdx) const;
259  GetBorderResult GetNearestOppositeSidePosition(KyUInt32 cornerIdx, KyFloat32 searchRadius, Vec3f& nearestPosition) const;
260 
261  void SetCornerRadius(KyUInt32 cornerIdx, KyFloat32 cornerRadius);
262  void SetCornerNearestOppositePosition(KyUInt32 cornerIdx, const Vec3f& nearestOppositePosition);
263  void SetCornerMaxRadius(KyUInt32 cornerIdx, KyFloat32 maxRadius);
264 
265  KyUInt32 GetLastCornerIdxOfType(CornerType cornerType);
266  void ChangePosOfLastCorner(CornerType cornerType, const Vec3f& pos);
267  bool GetLastButOneCornerPos(CornerType cornerType, Vec3f& pos) const;
268  StripCorner& GetLastCorner(CornerType cornerType);
269 private:
270  void SendDiagonalStripVisualDebug(World* world, DiagonalStripDisplayConfig& displayConfig);
271  void ApplyToVisibleOppositeSegmentsForward(NearestOppositePositionUpdator& updator, KyUInt32 cornerIdx, KyFloat32 searchRadius) const;
272  void ApplyToVisibleOppositeSegmentsBackward(NearestOppositePositionUpdator& updator, KyUInt32 cornerIdx, KyFloat32 searchRadius) const;
273 public: // to call reserve
274  KyArray<StripCorner> m_corners;
275 
276 public:
277  // dbg
278  World* m_world;
279 };
280 
281 
282 KY_INLINE void DiagonalStrip::SetCornerRadius(KyUInt32 cornerIdx, KyFloat32 cornerRadius)
283 {
284  KY_ASSERT(cornerIdx < m_corners.GetCount());
285  m_corners[cornerIdx].m_maxRadius = cornerRadius;
286 }
287 
288 KY_INLINE void DiagonalStrip::SetCornerNearestOppositePosition(KyUInt32 cornerIdx, const Vec3f& nearestOppositePosition)
289 {
290  KY_ASSERT(cornerIdx < m_corners.GetCount());
291  m_corners[cornerIdx].SetCornerNearestOppositePosition(nearestOppositePosition);
292 }
293 
294 KY_INLINE void DiagonalStrip::SetCornerMaxRadius(KyUInt32 cornerIdx, KyFloat32 maxRadius)
295 {
296  KY_ASSERT(cornerIdx < m_corners.GetCount());
297  m_corners[cornerIdx].SetMaxRadius(maxRadius);
298 }
299 
300 
301 inline KyUInt32 DiagonalStrip::GetLastCornerIdxOfType(CornerType cornerType)
302 {
303  KY_ASSERT(GetCornerCount() > 0);
304  KyUInt32 cornerIdx = GetCornerCount() - 1;
305  for(;;)
306  {
307  StripCorner& corner = GetCorner(cornerIdx);
308  if (corner.GetCornerType() == cornerType)
309  return cornerIdx;
310 
311  if (cornerIdx == 0)
312  return KyUInt32MAXVAL;
313 
314  --cornerIdx;
315  }
316 }
317 
318 inline void DiagonalStrip::ChangePosOfLastCorner(CornerType cornerType, const Vec3f& pos)
319 {
320  KY_ASSERT(GetCornerCount() > 0);
321  KyUInt32 cornerIdx = GetCornerCount() - 1;
322  for(;;)
323  {
324  StripCorner& corner = GetCorner(cornerIdx);
325  if (corner.GetCornerType() == cornerType)
326  {
327  corner.m_position = pos;
328  return;
329  }
330 
331  if (cornerIdx == 0)
332  return;
333 
334  --cornerIdx;
335  }
336 }
337 
338 inline StripCorner& DiagonalStrip::GetLastCorner(CornerType cornerType)
339 {
340  KY_ASSERT(GetCornerCount() > 0);
341  KyUInt32 cornerIdx = GetCornerCount() - 1;
342  for(;;)
343  {
344  StripCorner& corner = GetCorner(cornerIdx);
345  if (corner.GetCornerType() == cornerType)
346  return corner;
347 
348  --cornerIdx;
349  }
350 }
351 
352 inline bool DiagonalStrip::GetLastButOneCornerPos(CornerType cornerType, Vec3f& pos) const
353 {
354  KY_ASSERT(GetCornerCount() > 0);
355  KyUInt32 cornerIdx = GetCornerCount() - 1;
356  bool foundOne = false;
357  for(;;)
358  {
359  const StripCorner& corner = GetCorner(cornerIdx);
360  if (corner.GetCornerType() == cornerType)
361  {
362  if (foundOne)
363  {
364  pos = corner.GetPosition();
365  return true;
366  }
367 
368  foundOne = true;
369  }
370 
371  if (cornerIdx == 0)
372  break;
373 
374  --cornerIdx;
375  }
376 
377  return false;
378 }
379 
380 } // namespace Kaim
381 
382 #endif // Navigation_DiagonalStrip_H
#define KyFloat32MAXVAL
The maximum value that can be stored in the KyFloat32 variable type.
Definition: types.h:227
KyFloat32 Distance2d(const Vec3f &v1, const Vec3f &v2)
Returns the distance between v1 and v2, ignoring Z coordinates.
Definition: vec3f.h:288
#define KY_NULL
Null value.
Definition: types.h:247
RotationDirection
Defines the 4 possible cases of possibly constrained rotation in the horizontal plane for a given ele...
Definition: rotation.h:20
Definition: gamekitcrowddispersion.h:20
unsigned int KyUInt32
Type used internally to represent an unsigned 32-bit integer.
Definition: types.h:36
#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