gwnavruntime/channel/diagonalstrip.h Source File

diagonalstrip.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 
10 
14 
15 namespace Kaim
16 {
17 
18 class DisplayListManager;
19 class DisplayListIdArray;
20 
21 class DiagonalStripDisplayListIds
22 {
23 public:
24  DiagonalStripDisplayListIds()
25  : m_left(KyUInt32MAXVAL)
26  , m_right(KyUInt32MAXVAL)
27  , m_corners(KyUInt32MAXVAL)
28  , m_nearestOpposite(KyUInt32MAXVAL)
29  , m_diskToNearestOpposite(KyUInt32MAXVAL)
30  , m_diagonals(KyUInt32MAXVAL)
31  , m_cornerIdx(KyUInt32MAXVAL)
32  , m_triangles(KyUInt32MAXVAL)
33  {}
34 
35  void RemoveAll(DisplayListManager* displayListManager);
36 
37 public:
38  KyUInt32 m_left;
39  KyUInt32 m_right;
40  KyUInt32 m_corners;
41  KyUInt32 m_nearestOpposite;
42  KyUInt32 m_diskToNearestOpposite;
43  KyUInt32 m_diagonals;
44  KyUInt32 m_cornerIdx;
45  KyUInt32 m_triangles;
46 };
47 
48 class DiagonalStripDisplayConfig
49 {
50 public:
51  DiagonalStripDisplayConfig() { SetDefaults(); }
52  void SetDefaults();
53 
54  KyFloat32 m_contourVerticalOffset;
55  ShapeColor m_triangleColor;
56  Color m_leftColor;
57  Color m_rightColor;
58  ShapeColor m_cornerDiskColor;
59  ShapeColor m_diagonalColor;
60 };
61 
62 
63 enum CornerType
64 {
65  UndefinedCornerType, // only when not initialized.
66  PathStart, // used only in string pulled path
67  PathEnd, // used only in string pulled path
68  LeftSide,
69  RightSide
70 };
71 
72 class StripCorner
73 {
74 public:
75  StripCorner()
76  : m_cornerType(UndefinedCornerType)
77  , m_maxRadius(0.0f)
78  {}
79 
80  StripCorner(const Vec3f& position, CornerType cornerType, KyFloat32 maxRadius)
81  {
82  Set(position, cornerType, maxRadius);
83  }
84 
85  static CornerType GetOppositeSide(CornerType cornerType)
86  {
87  switch (cornerType)
88  {
89  case LeftSide: return RightSide;
90  case RightSide: return LeftSide;
91  default: return cornerType;
92  }
93  }
94 
95  void Set(const Vec3f& position, CornerType cornerType, KyFloat32 maxRadius)
96  {
97  m_position = position;
98  m_cornerType = cornerType;
99  m_maxRadius = maxRadius;
100  m_oppositeNearestPositionIsSet = false;
101  }
102 
103  void SetCornerNearestOppositePosition(const Vec3f& nearestOppositePosition)
104  {
105  SetMaxRadius(0.49f * Distance2d(m_position, nearestOppositePosition));
106  m_oppositeNearestPosition = nearestOppositePosition;
107  m_oppositeNearestPositionIsSet = true;
108  }
109 
110  void SetMaxRadius(KyFloat32 maxRadius)
111  {
112  m_maxRadius = maxRadius;
113  }
114 
115  void PreciseType(CornerType cornerType) { m_cornerType = cornerType; }
116 
117  const Vec3f& GetPosition() const { return m_position; }
118  CornerType GetCornerType() const { return m_cornerType; }
119  KyFloat32 GetMaxRadius() const { return m_maxRadius; }
120 
121  bool IsOppositeNearestPositionSet() const { return m_oppositeNearestPositionIsSet; }
122  const Vec3f& GetOppositeNearestPosition() const { return m_oppositeNearestPosition; }
123 
124  bool IsValid() const
125  {
126  return (m_cornerType != UndefinedCornerType);
127  }
128 
129 
130 public:
131  friend class DiagonalStrip;
132 
133  Vec3f m_position;
134  CornerType m_cornerType;
135  KyFloat32 m_maxRadius;
136 
137  Vec3f m_oppositeNearestPosition;
138  bool m_oppositeNearestPositionIsSet;
139 };
140 
141 KY_INLINE RotationDirection GetBubbleRotationDirectionFromCornerType(CornerType cornerType)
142 {
143  return
144  (cornerType == LeftSide) ? CounterClockwise :
145  (cornerType == RightSide) ? Clockwise :
146  UndefinedRotationDirection;
147 }
148 
149 KY_INLINE FunnelSide GetFunnelSideFromCornerType(CornerType cornerType)
150 {
151  return
152  (cornerType == LeftSide) ? FunnelLeft :
153  (cornerType == RightSide) ? FunnelRight :
154  FunnelBothSides;
155 }
156 
157 
158 class NearestOppositePositionUpdator
159 {
160 public:
161  NearestOppositePositionUpdator(const Vec3f& position)
162  : m_position(position)
163  , m_nearestPosition(KyFloat32MAXVAL, KyFloat32MAXVAL, KyFloat32MAXVAL)
164  , m_minSqDist(KyFloat32MAXVAL)
165  {}
166 
167  void UpdateWithOppositeSegment(const Vec3f& A, const Vec3f& B);
168 
169  Vec3f m_position;
170  Vec3f m_nearestPosition;
171  KyFloat32 m_minSqDist;
172 };
173 
174 
175 class DiagonalStrip
176 {
177 public:
178  enum GetBorderResult
179  {
180  BorderFound,
181  BorderNotFound,
182  NearestFoundIsStartOrEnd,
183  AskedCornerIsDiagonalStripStartOrEnd
184  };
185 
186  DiagonalStrip() {}
187 
188  void PushBackCorner(const Vec3f& position, CornerType cornerType, KyFloat32 maxRadius)
189  {
190  StripCorner corner(position, cornerType, maxRadius);
191  m_corners.PushBack(corner);
192  }
193 
194  void Clear();
195  void SendVisualDebug(DisplayListManager* displayListManager, DiagonalStripDisplayListIds& displayListIds, const DiagonalStripDisplayConfig& displayConfig = DiagonalStripDisplayConfig());
196 
197  bool IsEmpty() const { return m_corners.IsEmpty(); }
198  KyUInt32 GetCornerCount() const { return m_corners.GetCount(); }
199  const StripCorner& GetCorner(KyUInt32 cornerIdx) const { return m_corners[cornerIdx]; }
200  StripCorner& GetCorner(KyUInt32 cornerIdx) { return m_corners[cornerIdx]; }
201 
202  KyUInt32 GetIncomingBorderStartIdx(KyUInt32 cornerIdx) const;
203  KyUInt32 GetOutgoingBorderEndIdx(KyUInt32 cornerIdx) const;
204  StripCorner GetIncomingBorderStart(KyUInt32 cornerIdx) const;
205  StripCorner GetOutgoingBorderEnd(KyUInt32 cornerIdx) const;
206  GetBorderResult GetNearestOppositeSidePosition(KyUInt32 cornerIdx, KyFloat32 searchRadius, Vec3f& nearestPosition) const;
207 
208  void SetCornerRadius(KyUInt32 cornerIdx, KyFloat32 cornerRadius) { m_corners[cornerIdx].m_maxRadius = cornerRadius; }
209  void SetCornerNearestOppositePosition(KyUInt32 cornerIdx, const Vec3f& pos) { m_corners[cornerIdx].SetCornerNearestOppositePosition(pos); }
210  void SetCornerMaxRadius(KyUInt32 cornerIdx, KyFloat32 maxRadius) { m_corners[cornerIdx].SetMaxRadius(maxRadius); }
211 
212  KyUInt32 GetLastCornerIdxOfType(CornerType cornerType);
213  void ChangePosOfLastCorner(CornerType cornerType, const Vec3f& pos);
214  bool GetLastButOneCornerPos(CornerType cornerType, Vec3f& pos) const;
215  StripCorner& GetLastCorner(CornerType cornerType);
216 
217 private:
218  void SendDiagonalStripVisualDebug(DisplayListManager* displayListManager, DiagonalStripDisplayListIds& displayListIds, const DiagonalStripDisplayConfig& displayConfig);
219  void ApplyToVisibleOppositeSegmentsForward(NearestOppositePositionUpdator& updator, KyUInt32 cornerIdx, KyFloat32 searchRadius) const;
220  void ApplyToVisibleOppositeSegmentsBackward(NearestOppositePositionUpdator& updator, KyUInt32 cornerIdx, KyFloat32 searchRadius) const;
221 
222 public:
223  KyArray<StripCorner> m_corners;
224 };
225 
226 
227 inline KyUInt32 DiagonalStrip::GetLastCornerIdxOfType(CornerType cornerType)
228 {
229  KY_ASSERT(GetCornerCount() > 0);
230  KyUInt32 cornerIdx = GetCornerCount() - 1;
231  for(;;)
232  {
233  StripCorner& corner = GetCorner(cornerIdx);
234  if (corner.GetCornerType() == cornerType)
235  return cornerIdx;
236 
237  if (cornerIdx == 0)
238  return KyUInt32MAXVAL;
239 
240  --cornerIdx;
241  }
242 }
243 
244 inline void DiagonalStrip::ChangePosOfLastCorner(CornerType cornerType, const Vec3f& pos)
245 {
246  KY_ASSERT(GetCornerCount() > 0);
247  KyUInt32 cornerIdx = GetCornerCount() - 1;
248  for(;;)
249  {
250  StripCorner& corner = GetCorner(cornerIdx);
251  if (corner.GetCornerType() == cornerType)
252  {
253  corner.m_position = pos;
254  return;
255  }
256 
257  if (cornerIdx == 0)
258  return;
259 
260  --cornerIdx;
261  }
262 }
263 
264 inline StripCorner& DiagonalStrip::GetLastCorner(CornerType cornerType)
265 {
266  KY_ASSERT(GetCornerCount() > 0);
267  KyUInt32 cornerIdx = GetCornerCount() - 1;
268  for(;;)
269  {
270  StripCorner& corner = GetCorner(cornerIdx);
271  if (corner.GetCornerType() == cornerType)
272  return corner;
273 
274  --cornerIdx;
275  }
276 }
277 
278 inline bool DiagonalStrip::GetLastButOneCornerPos(CornerType cornerType, Vec3f& pos) const
279 {
280  KY_ASSERT(GetCornerCount() > 0);
281  KyUInt32 cornerIdx = GetCornerCount() - 1;
282  bool foundOne = false;
283  for(;;)
284  {
285  const StripCorner& corner = GetCorner(cornerIdx);
286  if (corner.GetCornerType() == cornerType)
287  {
288  if (foundOne)
289  {
290  pos = corner.GetPosition();
291  return true;
292  }
293 
294  foundOne = true;
295  }
296 
297  if (cornerIdx == 0)
298  break;
299 
300  --cornerIdx;
301  }
302 
303  return false;
304 }
305 
306 } // namespace Kaim
307 
#define KyFloat32MAXVAL
KyFloat32 max value
Definition: types.h:71
std::uint32_t KyUInt32
uint32_t
Definition: types.h:29
RotationDirection
Defines the 4 possible cases of possibly constrained rotation in the horizontal plane for a given ele...
Definition: rotation.h:15
The Autodesk Navigation namespace.
Definition: gamekitcrowddispersion.cpp:17
#define KyUInt32MAXVAL
KyUInt32 max value
Definition: types.h:68
float KyFloat32
float
Definition: types.h:32