gwnavruntime/channel/channelsectionwidener.h Source File

channelsectionwidener.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 
15 #include "channelcomputerconfig.h"
16 
17 namespace Kaim
18 {
19 
20 class Database;
21 class Channel;
22 class Gate;
23 class DisplayList;
24 class ChannelComputerConfig;
25 
26 struct GateSide { enum Enum { Left, Right }; };
27 
28 // currIsStartGate==true currIsStartGate==false //
29 // NOT ORTHOGONAL ALWAYS ORTHOGONAL //
30 // P=startPos P=(currGate.m_x,currGate_y) //
31 // \ | //
32 // O-------- ---O-------- //
33 // O=(0,0) O=(currGate.m_x,0)
34 struct GateCandidate
35 {
36  enum Type { Start, Mid, End };
37 
38  GateCandidate(KyFloat32 x = 0.0f) : type(Mid), L(x, 0.0f), O(x, 0.0f), R(x, 0.0f), LCanMove(true), RCanMove(true) {}
39 
40  bool IsStart() const { return type == Start; }
41  bool IsEnd() const { return type == End; }
42 
43  KyFloat32 MinX() const { return Kaim::Min(L.x, R.x); }
44  KyFloat32 MaxX() const { return Kaim::Max(L.x, R.x); }
45 
46  Type type;
47  Vec2f L; // local, left
48  Vec2f O; // local, on edge
49  Vec2f R; // local, right
50  bool LCanMove;
51  bool RCanMove;
52 };
53 
54 struct GateFitConstraint
55 {
56  enum Type { PerfectFit_ = 0, ShrinkFit_, CollapseFit_, NoFit_ };
57 
58  GateFitConstraint() : fitType(NoFit_), shrinkY(0.0f), side(GateSide::Left) {}
59  GateFitConstraint(Type fitType_, KyFloat32 shrinkY_, const Vec2f& C_, GateSide::Enum side_) : fitType(fitType_), shrinkY(shrinkY_), side(side_), C(C_) {}
60 
61  static GateFitConstraint PerfectFit() { return GateFitConstraint(PerfectFit_ , 0.0f, Vec2f(0.0f, 0.0f), GateSide::Left); }
62  static GateFitConstraint ShrinkNewGateFit(KyFloat32 shrinkY_, const Vec2f& C_, GateSide::Enum side_) { return GateFitConstraint(ShrinkFit_ , shrinkY_, C_, side_); }
63  static GateFitConstraint ShrinkBothGatesFit(KyFloat32 shrinkY_, const Vec2f& C_, GateSide::Enum side_) { return GateFitConstraint(ShrinkFit_ , shrinkY_, C_, side_); }
64  static GateFitConstraint CollapseFit(const Vec2f& C_, GateSide::Enum side_) { return GateFitConstraint(CollapseFit_, 0.0f, C_, side_); }
65  static GateFitConstraint NoFit(const Vec2f& C_, GateSide::Enum side_) { return GateFitConstraint(NoFit_ , 0.0f, C_, side_); }
66 
67  bool HasFit() const { return fitType != NoFit_; }
68 
69  bool IsLessConstraining(const GateFitConstraint& other) const
70  {
71  if (fitType < other.fitType) return true;
72  if (fitType > other.fitType) return false;
73  return shrinkY < other.shrinkY;
74  }
75 
76  Type fitType;
77  KyFloat32 shrinkY;
78  GateSide::Enum side;
79  Vec2f C; // constraining point (local)
80 };
81 
82 struct GateFit
83 {
84  enum Type { Mid, End };
85  GateFit() : m_type(Mid) {}
86  bool HasFit() const { return m_constraint.HasFit(); }
87  KyFloat32 GetConstrainX() const { return m_constraint.C.x; }
88 
89  Type m_type;
90  GateCandidate m_currGate;
91  GateCandidate m_nextGate;
92  GateFitConstraint m_constraint;
93 };
94 
95 struct NextGateX
96 {
97  enum Mode { Mid_Constrain, Mid_No_Constrain, End };
98  NextGateX(KyFloat32 x_, Mode mode_) : x(x_), mode(mode_) {}
99  KyFloat32 x;
100  Mode mode;
101 };
102 
103 struct WidenInput
104 {
105  WidenInput() : type(UndefinedGateType) {}
106  WidenInput(const Vec3f pos_, const Vec2f left_dir_, GateType type_) : O(pos_), left_dir(left_dir_), type(type_) {}
107  Vec3f O;
108  Vec2f left_dir;
109  GateType type;
110 };
111 
112 class ChannelSectionWidener
113 {
114 public:
115  ChannelSectionWidener();
116 
117  void Clear();
118 
119  void InitializeForSection(Database* database, const ChannelComputerConfig& channelConfig, Channel* channel, KyUInt32 sectionIndex, const WidenInput& startInput, const WidenInput& endInput, const Vec3f& endGateFixedPos,
120  const NavTrianglePtr& startNavTrianglePtr, const FullDebug& fullDebug);
121 
122  enum WidenSide { WidenLeft = 1, WidenRight = 2, WidenLeftRight = WidenLeft | WidenRight };
123 
124  template<class TLogic>
125  KyResult WidenSection(WorkingMemory* workingMem, void* traverseLogicUserData, QueryDynamicOutput* queryDynamicOutput, WidenSide widenSide);
126 
127 private: //Internal
128  void ConfigureIntersector(PolylineCastIntersector& intersector);
129  KyResult SimplifyPolylinesAndMakeGates(WorkingMemory* workingMem, PolylineCastIntersector& intersector, WidenSide widenSide);
130 
131  void FillExtremityContext(PolylineExtremityContext& context, bool isOnLeft);
132 
133  void ComputeTrapezoid();
134 
135  bool CanMoveLeftStartPos() const { return m_startInput.type != LeftTurnEnd; }
136  bool CanMoveRightStartPos() const { return m_startInput.type != RightTurnEnd; }
137  bool CanMoveLeftEndPos() const { return m_endInput.type != LeftTurnStart; }
138  bool CanMoveRightEndPos() const { return m_endInput.type != RightTurnStart; }
139 
140  void CollapseSimplifiedPolyline_Left();
141  void CollapseSimplifiedPolyline_Right();
142 
143  void InitLeftAndRightArrays(WidenSide widenSide);
144 
145  // GateCandidates (Local) => Channel Gates (Global)
146  KyResult MakeChannelGates(WorkingMemory* workingMemory, WidenSide widenSide);
147  void ShrinkStartChannelGate(WidenSide widenSide);
148  void AddEndChannelGate(WidenSide widenSide);
149 
150  NextGateX ComputeNextGateX();
151 
152  KyResult MakeGates_Trapeze();
153  KyResult MakeGates_Triangle(WidenSide widenSide);
154 
155  void MakeGates_Mid_No_Constraint(KyFloat32 x);
156  KyResult MakeGates_Mid(KyFloat32 x);
157  KyResult MakeGates_End();
158 
159  bool IsGoodFit(const GateFit& gateFit);
160  bool IsBetterFit(const GateFit& a, const GateFit& b);
161 
162  void ComputeGateFit_Mid(GateFit& gateFit, KyFloat32 x) const;
163  GateFitConstraint ComputeGateFit_Mid_Left(const Vec2f* leftIt, GateFit& gateFit) const;
164  GateFitConstraint ComputeGateFit_Mid_Right(const Vec2f* rightIt, GateFit& gateFit) const;
165 
166  void ComputeGateFit_End(GateFit& gateFit) const;
167  GateFitConstraint ComputeGateFit_End_Left(const Vec2f* leftIt, GateFit& gateFit) const;
168  GateFitConstraint ComputeGateFit_End_Right(const Vec2f* rightIt, GateFit& gateFit) const;
169 
170  void InitGateFit_Mid(GateFit& gateFit, KyFloat32 nextX) const;
171  void InitGateFit_End(GateFit& gateFit) const;
172 
173  void PushGate_Mid(const GateFit& gateFit);
174  void PushGate_End(const GateFit& gateFit);
175  void AddGateSampling(const GateFit& gateFit);
176  void AdvanceToLastOrStrictlyAfterX(KyFloat32 x);
177  void UpdateStartLocal(const GateCandidate& currGate); // update m_startLeftLocal and m_startRightLocal
178  void UpdateEndLocal(const GateCandidate& endGate); // update m_endLeftLocal and m_endRightLocal
179 
180  void InitGateCandidate_Start(GateCandidate& gateCandidate) const;
181  void InitGateCandidate_End(GateCandidate& gateCandidate) const;
182 
183  void PushGateCandidate(const GateCandidate& gateCandidate);
184 
185  const SharedPoolList<Vec2f>& SimplifiedLeft() const { return m_simplifier.m_leftPolyline; }
186  const SharedPoolList<Vec2f>& SimplifiedRight() const { return m_simplifier.m_rightPolyline; }
187  SharedPoolList<Vec2f>& SimplifiedLeft() { return m_simplifier.m_leftPolyline; }
188  SharedPoolList<Vec2f>& SimplifiedRight() { return m_simplifier.m_rightPolyline; }
189  KyFloat32 ForceDeltaX() const { return m_forceDeltaX; } // 10 cm
190  KyFloat32 MinDeltaX() const { return m_channelConfig.m_advancedConfig.m_minDistBetweenIntermediaryGates; } // 50 cm
191  KyFloat32 MaxDeltaX() const { return m_channelConfig.m_advancedConfig.m_maxDistBetweenIntermediaryGates; } // 10 m
192  KyFloat32 GetChannelRadius() const { return m_channelConfig.m_channelRadius; }
193  KyFloat32 EndX() const { return m_simplifier.m_edgeLength2d; }
194  Vec2f EdgeDir() const { return m_simplifier.m_edgeDir2d; }
195 
196  const Vec2f* LeftBegin() const { return m_left.GetDataPtr(); }
197  const Vec2f* LeftLast() const { return m_left.GetDataPtr() + m_left.GetCount() - 1; }
198  const Vec2f* LeftEnd() const { return m_left.GetDataPtr() + m_left.GetCount(); }
199  const Vec2f* RightBegin() const { return m_right.GetDataPtr(); }
200  const Vec2f* RightLast() const { return m_right.GetDataPtr() + m_right.GetCount() - 1; }
201  const Vec2f* RightEnd() const { return m_right.GetDataPtr() + m_right.GetCount(); }
202 
203  Vec3f GlobalFromLocal_Left(const Vec2f& local) const { return GlobalFromLocal(local, GateSide::Left); }
204  Vec3f GlobalFromLocal_Right(const Vec2f& local) const { return GlobalFromLocal(local, GateSide::Right); }
205  Vec3f GlobalFromLocal(const Vec2f& local, GateSide::Enum side) const;
206 
207  DisplayListManager* GetDisplayListManager() const;
208  void DisplayTrapezoid() const;
209  void DisplayTriangleAroundLeft(const Vec3f& I) const;
210  void DisplayTriangleAroundRight(const Vec3f& I) const;
211  void DisplaySectionInput() const;
212  void DisplayGateFit(const GateFit& gateFit) const;
213 
214 public:
215  ChannelBorderSimplifier m_simplifier;
216  Database* m_database;
217  Channel* m_channel;
218 
219  // config
220  ChannelComputerConfig m_channelConfig;
221  KyFloat32 m_margin;
222  const KyFloat32 m_maxShrinkY; // 10 cm
223  const KyFloat32 m_forceDeltaX; // 20 cm
224 
225  // input start
226  KyUInt32 m_sectionIndex; // only for debugging
227  WidenInput m_startInput;
228  Vec2f m_startGateLeftPos; // m_startGlobal.L
229  Vec2f m_startGateRightPos; // m_startGlobal.R
230  NavTrianglePtr m_startNavTriangle;
231 
232  // input end
233  WidenInput m_endInput;
234  Vec3f m_endGateFixedPos; // not relevant for endGate
235 
236  // working members
237 
238  struct Trapezoid { Vec3f SL; Vec3f SR; Vec3f EL; Vec3f ER; };
239  Trapezoid m_trapezoid;
240 
241  // 1. Init in m_startLeftLocal = Vec2f(extremities.m_startX, extremities.m_startY);
242  // 2. changed in makes gates
243  // 3. Channel.LastGate.L = GlobalFromLocal(m_startLeftLocal)
244  Vec2f m_startLeftLocal;
245  Vec2f m_startRightLocal;
246  Vec2f m_endLeftLocal;
247  Vec2f m_endRightLocal;
248 
249  // instead of m_startLeftLocal, m_startRightLocal, m_endLeftLocal, m_endRightLocal we may have
250  // GateCandidate m_startLocal; GateCandidate m_endLocal;
251  // -or- m_startInput.localL m_startInput.localR...
252 
253  KyArray<GateCandidate> m_gates;
254 
255  KyArray<Vec2f> m_left;
256  KyArray<Vec2f> m_right;
257 
258  // // +--------------------------+ //
259  KyFloat32 m_gateMinX; // /|m_gateMinX m_gateMaxX|\ //
260  KyFloat32 m_gateMaxX; // +------------------------------+ //
261 
262  GateCandidate m_currGate;
263  const Vec2f* m_leftIt;
264  const Vec2f* m_rightIt;
265 
266  // debug
267  FullDebug m_fullDebug;
268 };
269 
270 template<class TLogic>
271 inline KyResult ChannelSectionWidener::WidenSection(WorkingMemory* workingMem, void* traverseLogicUserData, QueryDynamicOutput* queryDynamicOutput, WidenSide widenSide)
272 {
273  // Run PolylineCast to collect the borders
274  PolylineCastIntersector intersector;
275  ConfigureIntersector(intersector);
276  KyResult rc = PolylineCastHelper::RunPolylineCast<TLogic>(workingMem, m_database, traverseLogicUserData, queryDynamicOutput, intersector);
277 
278  if (rc == KY_SUCCESS)
279  rc = SimplifyPolylinesAndMakeGates(workingMem, intersector, widenSide);
280 
281  if (m_fullDebug.Has(FullDebug::ChannelSectionWidener))
282  GetDisplayListManager()->NewFrame(); // one frame per section
283 
284  return rc;
285 }
286 
287 } // namespace Kaim
288 
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
Indicates the Gate is a right turn end.
Definition: channel.h:35
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 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
Navigation return code class.
Definition: types.h:108
The Autodesk Navigation namespace.
Definition: gamekitcrowddispersion.cpp:17
float KyFloat32
float
Definition: types.h:32