24 class ChannelComputerConfig;
26 struct GateSide {
enum Enum { Left, Right }; };
36 enum Type { Start, Mid, End };
38 GateCandidate(
KyFloat32 x = 0.0f) : type(Mid), L(x, 0.0f), O(x, 0.0f), R(x, 0.0f), LCanMove(true), RCanMove(true) {}
40 bool IsStart()
const {
return type == Start; }
41 bool IsEnd()
const {
return type == End; }
43 KyFloat32 MinX()
const {
return Kaim::Min(L.x, R.x); }
44 KyFloat32 MaxX()
const {
return Kaim::Max(L.x, R.x); }
54 struct GateFitConstraint
56 enum Type { PerfectFit_ = 0, ShrinkFit_, CollapseFit_, NoFit_ };
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_) {}
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_); }
67 bool HasFit()
const {
return fitType != NoFit_; }
69 bool IsLessConstraining(
const GateFitConstraint& other)
const
71 if (fitType < other.fitType)
return true;
72 if (fitType > other.fitType)
return false;
73 return shrinkY < other.shrinkY;
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; }
90 GateCandidate m_currGate;
91 GateCandidate m_nextGate;
92 GateFitConstraint m_constraint;
97 enum Mode { Mid_Constrain, Mid_No_Constrain, End };
98 NextGateX(
KyFloat32 x_, Mode mode_) : x(x_), mode(mode_) {}
106 WidenInput(
const Vec3f pos_,
const Vec2f left_dir_,
GateType type_) : O(pos_), left_dir(left_dir_), type(type_) {}
112 class ChannelSectionWidener
115 ChannelSectionWidener();
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);
122 enum WidenSide { WidenLeft = 1, WidenRight = 2, WidenLeftRight = WidenLeft | WidenRight };
124 template<
class TLogic>
125 KyResult WidenSection(WorkingMemory* workingMem,
void* traverseLogicUserData, QueryDynamicOutput* queryDynamicOutput, WidenSide widenSide);
128 void ConfigureIntersector(PolylineCastIntersector& intersector);
129 KyResult SimplifyPolylinesAndMakeGates(WorkingMemory* workingMem, PolylineCastIntersector& intersector, WidenSide widenSide);
131 void FillExtremityContext(PolylineExtremityContext& context,
bool isOnLeft);
133 void ComputeTrapezoid();
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; }
140 void CollapseSimplifiedPolyline_Left();
141 void CollapseSimplifiedPolyline_Right();
143 void InitLeftAndRightArrays(WidenSide widenSide);
146 KyResult MakeChannelGates(WorkingMemory* workingMemory, WidenSide widenSide);
147 void ShrinkStartChannelGate(WidenSide widenSide);
148 void AddEndChannelGate(WidenSide widenSide);
150 NextGateX ComputeNextGateX();
153 KyResult MakeGates_Triangle(WidenSide widenSide);
155 void MakeGates_Mid_No_Constraint(
KyFloat32 x);
159 bool IsGoodFit(
const GateFit& gateFit);
160 bool IsBetterFit(
const GateFit& a,
const GateFit& b);
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;
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;
170 void InitGateFit_Mid(GateFit& gateFit,
KyFloat32 nextX)
const;
171 void InitGateFit_End(GateFit& gateFit)
const;
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);
178 void UpdateEndLocal(
const GateCandidate& endGate);
180 void InitGateCandidate_Start(GateCandidate& gateCandidate)
const;
181 void InitGateCandidate_End(GateCandidate& gateCandidate)
const;
183 void PushGateCandidate(
const GateCandidate& gateCandidate);
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; }
190 KyFloat32 MinDeltaX()
const {
return m_channelConfig.m_advancedConfig.m_minDistBetweenIntermediaryGates; }
191 KyFloat32 MaxDeltaX()
const {
return m_channelConfig.m_advancedConfig.m_maxDistBetweenIntermediaryGates; }
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; }
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(); }
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;
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;
215 ChannelBorderSimplifier m_simplifier;
216 Database* m_database;
220 ChannelComputerConfig m_channelConfig;
227 WidenInput m_startInput;
228 Vec2f m_startGateLeftPos;
229 Vec2f m_startGateRightPos;
230 NavTrianglePtr m_startNavTriangle;
233 WidenInput m_endInput;
234 Vec3f m_endGateFixedPos;
238 struct Trapezoid { Vec3f SL; Vec3f SR; Vec3f EL; Vec3f ER; };
239 Trapezoid m_trapezoid;
244 Vec2f m_startLeftLocal;
245 Vec2f m_startRightLocal;
246 Vec2f m_endLeftLocal;
247 Vec2f m_endRightLocal;
253 KyArray<GateCandidate> m_gates;
255 KyArray<Vec2f> m_left;
256 KyArray<Vec2f> m_right;
262 GateCandidate m_currGate;
263 const Vec2f* m_leftIt;
264 const Vec2f* m_rightIt;
267 FullDebug m_fullDebug;
270 template<
class TLogic>
271 inline KyResult ChannelSectionWidener::WidenSection(WorkingMemory* workingMem,
void* traverseLogicUserData, QueryDynamicOutput* queryDynamicOutput, WidenSide widenSide)
274 PolylineCastIntersector intersector;
275 ConfigureIntersector(intersector);
276 KyResult rc = PolylineCastHelper::RunPolylineCast<TLogic>(workingMem, m_database, traverseLogicUserData, queryDynamicOutput, intersector);
278 if (rc == KY_SUCCESS)
279 rc = SimplifyPolylinesAndMakeGates(workingMem, intersector, widenSide);
281 if (m_fullDebug.Has(FullDebug::ChannelSectionWidener))
282 GetDisplayListManager()->NewFrame();
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