gwnavgeneration/navraster/navrastercellscanlinepainter.h Source File

navrastercellscanlinepainter.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 
16 namespace Kaim
17 {
18 
19 class DynamicNavRasterCell;
20 class NavRasterPixel;
21 class NavRasterWorkingPixel;
22 class DynamicNavRasterFinalColumn;
23 
24 class NavRasterCellScanlinePainter
25 {
26 public:
27  // Scan Pixel is a NavRasterPixel augmented with its own position and floorIdx (that NavRasterPixel does not have)
28  // It would be much simpler to add m_pos and m_floorIdx to NavRasterPixel and work only with NavRasterPixel...
29  class ScanPixel
30  {
31  public:
32  ScanPixel() : m_navPixel(nullptr), m_pos(KyInt32MAXVAL, KyInt32MAXVAL), m_floorIdx(KyUInt32MAXVAL) {}
33  ScanPixel(NavRasterPixel* navPixel, const PixelPos& pos, KyUInt32 floor) : m_navPixel(navPixel), m_pos(pos), m_floorIdx(floor) {}
34 
35  void Clear()
36  {
37  m_navPixel = nullptr;
38  m_pos.Set(KyInt32MAXVAL, KyInt32MAXVAL);
39  m_floorIdx = KyUInt32MAXVAL;
40  }
41 
42  PixelColor GetFloorColor() const { return m_navPixel->m_floorColor; }
43  void SetFloorColor(PixelColor color) { m_navPixel->m_floorColor = color; }
44 
45  PixelColor GetConnectedComponentIdx() const { return m_navPixel->m_connectedComponentIdx; }
46  void SetConnectedComponentIdx(KyUInt32 idx) { m_navPixel->m_connectedComponentIdx = idx; }
47 
48  // dir could be extracted from neighbor.m_pos and this->m_pos but it's available in call context
49  bool IsConnectedWith(CardinalDir dir, const ScanPixel& neighbor) { return m_navPixel->GetNeighborFloorIndex(dir) == neighbor.m_floorIdx; }
50 
51  public:
52  NavRasterPixel* m_navPixel;
53  PixelPos m_pos;
54  KyUInt32 m_floorIdx;
55  };
56 
57  class ColorData
58  {
59  public:
60  ColorData(PixelColor color = PixelColor_Unset, KyUInt32 connectedComponentIdx = KyUInt32MAXVAL)
61  : m_color(color), m_pixelCount(0), m_connectedComponentIdx(connectedComponentIdx), m_boundaryPixelBorderCount(0), m_indexInBinaryHeap(BinaryHeapInvalidReference)
62  {}
63 
64  void UpdateColorDataFromNewPixel(NavRasterPixel* pixel, const PixelPos& pos);
65 
66  public:
67  PixelColor m_color;
68  PixelBox m_box;
69  KyUInt32 m_pixelCount;
70  KyUInt32 m_connectedComponentIdx;
71  KyUInt32 m_boundaryPixelBorderCount;
72  KyUInt32 m_indexInBinaryHeap;
73  FloorAltitudeRange m_altRange;
74  };
75 
76 public:
77  NavRasterCellScanlinePainter() : m_navRaster(nullptr), m_paintingMs(nullptr) {}
78 
79  void Clear();
80  KyResult Paint();
81 
82  void SetNavRasterCell(DynamicNavRasterCell* cell) { m_navRaster = cell; }
83  void SetConnexIdxToNavTagIdxArray(KyArrayTLS_POD<KyUInt32>* connexIdxToNavTagIdxArray) { m_connexIdxToNavTagIdxArray = connexIdxToNavTagIdxArray; }
84  void SetPaintingMs(KyFloat32* paintingMs) { m_paintingMs = paintingMs; }
85 
86  KyUInt32 GetNbColorsUsed() const { return m_colorCount; }
87 
88 private:
89  void Init(); // step 1
90  void RemoveSmallNavTagArea(); // step 2
91  void ComputeConnectedComponents(); // step 3
92  void ComputeFloorColors(); // step 4
93  void MergeFloorColors(); // step 5
94  void ComputeConnexes(); // step 6
95 
96 private:
97  void PropagateInSouthWestBox();
98  void PropagateInSouthEastBox();
99  void PropagateInNorthWestBox();
100  void PropagateInNorthEastBox();
101 
102  void PropagateFromCornerColumn(const PixelBox& paintBox, const PixelPos& cornerPos, CardinalDir expandLineDir, CardinalDir lineMoveDir);
103  void PropagateFromCornerPixel(const PixelBox& paintBox, const ScanPixel& seedPixel, CardinalDir expandLineDir, CardinalDir lineMoveDir);
104  PixelBox ComputeLocalPaintBoxForCorner(const PixelBox& paintBox, const ScanPixel& corner, CardinalDir expandLineDir, CardinalDir lineMoveDir);
105 
106  void PropagateFromBoxBorder(const PixelBox& paintBox, const PixelPos& startPos, CardinalDir expandLineDir, CardinalDir lineMoveDir);
107  void PropagateFromBorderPixel(const PixelBox& paintBox, const ScanPixel& seedPixel, CardinalDir expandLineDir, CardinalDir lineMoveDir);
108  PixelBox ComputeLocalPaintBoxForBorder(const PixelBox& paintBox, const ScanPixel& seedPixel, CardinalDir expandLineDir, CardinalDir lineMoveDir);
109 
110  void DisconnectOutsidePixelsAtBoxBounds(const PixelBox& paintBox, const ScanPixel& corner, CardinalDir dirAlongBorder, CardinalDir dirToOutside, PixelColor color);
111 
112  void PropagateFromAllRemainingUncoloredPixels();
113  void PropagateFromUncoloredNonBorderPixel(const ScanPixel& startPixel);
114 
115  void ColorCellBoundaryPixelLineInBox(const PixelBox& localPaintBox, const ScanPixel& startPixel, PixelColor color, CardinalDir expandDir, CardinalDir borderDir,
116  ScanPixel& lastPixelOnLine);
117 
118  bool TwoNeighborPixelHaveSameColor(const ScanPixel& pixel1, const ScanPixel& pixel2, CardinalDir dir, PixelColor currentColor);
119  bool CanPropagateToPixel(PixelPos& pixelPos, KyUInt32 currentFloorIdx, KyUInt32 propagationIdx);
120 
121  void FindLowerConnectedPixel(const ScanPixel& startPixel, ScanPixel& lowerPixel);
122  void CastPixelUntillBoundary(const ScanPixel& startScanPixel, CardinalDir castDir);
123 
124  PixelPos CastCellBoundaryPixel(const PixelBox& bbox, const ScanPixel& borderPixel, CardinalDir borderDir, CardinalDir outsideDir);
125  void CastPixelCheckingColor(const ScanPixel& scanLine, PixelColor color, const PixelBox& bbox, CardinalDir castdir);
126  void PaintLastPixelCastResultAndOutsideNeighbors(PixelColor color, CardinalDir borderDir);
127 
128  bool GetNeighbor_InsideNavPixelBox(const ScanPixel& pixel, CardinalDir dir, ScanPixel& neighborPixel); // uses m_navRaster->m_navPixelBox
129  bool GetNeighbor(const PixelBox& box, const ScanPixel& pixel, CardinalDir dir, ScanPixel& neighborPixel);
130 
131  PixelColor GetNewFloorColor(KyUInt32 connectedComponentIdx);
132  void SetFloorColor(const ScanPixel& pixel, PixelColor color); // takes a const ScanPixel& because const does not propagate to ScanPixel::m_navPixel* m_navPixel
133  void SetOutsideFloorColor(const ScanPixel& pixel, PixelColor color); // takes a const ScanPixel& because const does not propagate to ScanPixel::m_navPixel* m_navPixel
134 
135  bool CanSetColorToPixel(const PixelPos& pixelPos, KyUInt32 floorIdx, PixelColor newColor);
136 
137  bool CanPaintNeighborLine(const ScanPixel& startScanPixel, const ScanPixel& endScanPixel, PixelColor color, const PixelBox& bbox, CardinalDir lineDir, CardinalDir expandDir,
138  ScanPixel& borderLineStartScanPixel, ScanPixel& borderLineEndScanPixel, KyUInt32& neighborLineCount, KyFloat32& altRangeDiffWithNeighborLine);
139 
140  void DetectForbiddenColorMergeAndConnectedColors();
141  void ComputeMergedColors();
142  void ApplyFinalColorToPixels();
143 
144  struct ScanPixelSorterByAlt
145  {
146  bool operator()(const ScanPixel& pixel1, const ScanPixel& pixel2) const { return pixel1.m_navPixel->m_altitude < pixel2.m_navPixel->m_altitude; }
147  };
148 
149  void ChangeNavTagOfSmallNavTagConnectedComponent(const PixelBox& safenavTagRemovalBox, const ScanPixel& startPixel, KyUInt32 connectedComponentIdx, KyUInt32 minPixelCount);
150  void PropagateConnectedComponent(const ScanPixel& startPixel, KyUInt32 connectedComponentIdx);
151 
152  void PropagateConnex_FromColumn(const Box2i& box, const PixelPos& pos, KyUInt32& connexIdx);
153  void PropagateConnex_FromPixel(const Box2i& box, const ScanPixel& startPixel, KyUInt32 connexIdx);
154 
155  bool IsOutsideBorder(const ScanPixel& pixel);
156 
157 private:
158  DynamicNavRasterCell* m_navRaster;
159  PixelBox m_navPixelBox;
160  PixelBox m_exclusivePixelBox;
161  KyFloat32* m_paintingMs;
162  KyUInt32 m_colorCount;
163  KyArrayTLS<ScanPixel> m_propagationStack; // cache the array between floodFills to avoid multiple resizes
164  KyArrayTLS_POD<ScanPixel> m_navTagArea;
165  KyArrayTLS_POD<ScanPixel> m_navTagAreaNeighbors;
166  KyArrayTLS<ColorData> m_colorData;
167 
168  BitFieldTLS m_forbiddenColorMerge;
169  BitFieldTLS m_connectedColors;
170  KyArrayTLS_POD<PixelColor> m_finalColor; // m_finalColor[color] = finalColor after merge !
171 
172  KyArrayTLS<ScanPixel> m_castForwardResult;
173  KyArrayTLS<ScanPixel> m_castBackwardResult;
174  KyArrayTLS<ScanPixel> m_onePixelPerFinalColor;
175 
176  BinaryHeapTls<ScanPixel, ScanPixelSorterByAlt> m_orderedPixels;
177  KyArrayTLS_POD<KyUInt32>* m_connexIdxToNavTagIdxArray;
178 
179  PixelPos m_midPos;
180  KyUInt32 m_currentPropagationId;
181 };
182 
183 inline PixelColor NavRasterCellScanlinePainter::GetNewFloorColor(KyUInt32 connectedComponentIdx)
184 {
185  PixelColor color = m_colorData.GetCount();
186  m_colorData.PushBack(ColorData(color, connectedComponentIdx));
187  return color;
188 }
189 
190 inline void NavRasterCellScanlinePainter::SetFloorColor(const ScanPixel& pixel, PixelColor color)
191 {
192  KY_ASSERT(pixel.m_navPixel != nullptr);
193  KY_ASSERT(pixel.m_navPixel->m_floorColor == PixelColor_Unset);
194  KY_ASSERT(color < m_colorData.GetCount());
195  KY_ASSERT(m_navPixelBox.DoesContain(pixel.m_pos));
196 
197  pixel.m_navPixel->m_floorColor = color;
198  m_colorData[color].UpdateColorDataFromNewPixel(pixel.m_navPixel, pixel.m_pos);
199 }
200 
201 inline void NavRasterCellScanlinePainter::SetOutsideFloorColor(const ScanPixel& pixel, PixelColor color)
202 {
203  KY_ASSERT(pixel.m_navPixel != nullptr);
204  KY_ASSERT(IsOutsideBorder(pixel));
205 
206  pixel.m_navPixel->m_floorColor = color;
207  // We do not call m_colorData[color].UpdateColorDataFromNewPixel(pixel.m_navPixel, pixel.m_pos); on purpose !
208  // We do not want the outside pixels to change the color properties(pixelCount, bbox, ...)
209 }
210 
211 inline void NavRasterCellScanlinePainter::ColorData::UpdateColorDataFromNewPixel(NavRasterPixel* currentPixel, const PixelPos& pos)
212 {
213  KY_LOG_ERROR_IF(currentPixel->m_floorColor != m_color, ("Wrong color data for this pixel"));
214  ++m_pixelCount;
215  m_altRange.Update(currentPixel->m_altitude);
216  m_box.ExpandByPos(pos);
217  for (KyUInt32 i = 0; i < 4; ++i)
218  {
219  if (currentPixel->m_neighborFloorIdx[i] == NavRasterFloorIdx_Invalid)
220  ++m_boundaryPixelBorderCount;
221  }
222 }
223 
224 inline bool NavRasterCellScanlinePainter::IsOutsideBorder(const ScanPixel& pixel)
225 {
226  return !m_exclusivePixelBox.DoesContain(pixel.m_pos) && m_navPixelBox.DoesContain(pixel.m_pos);
227 }
228 
229 }
230 
std::uint32_t KyUInt32
uint32_t
Definition: types.h:29
KyUInt32 CardinalDir
Defines a type that refers to one of the cardinal points on the compass:
Definition: cardinaldir.h:15
#define KyInt32MAXVAL
KyInt32 max value
Definition: types.h:60
Navigation return code class.
Definition: types.h:108
The Autodesk Navigation namespace.
Definition: gamekitcrowddispersion.cpp:17
#define KyUInt32MAXVAL
KyUInt32 max value
Definition: types.h:68
float KyFloat32
float
Definition: types.h:32