gwnavgeneration/generator/generatorreport.h Source File

generatorreport.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 
8 #pragma once
9 
16 
17 namespace Kaim
18 {
19 
20 inline String GeneratorReportGetNoneIfEmpty(const String& str) { return str == "" ? "--NONE--" : str; }
21 
22 template <class OSTREAM>
23 inline OSTREAM& operator<<(OSTREAM& os, const GeneratorSectorReport& sectorReport)
24 {
25  FloatFormatter fmt2f("%.2f");
26  const char* prefix = sectorReport.m_logPrefix.ToCStr();
27 
28  const char* isPatchString = sectorReport.m_isPatch ? "PATCH" : "REGULAR";
29  os << KY_LOG_SMALL_TITLE_BEGIN(prefix, isPatchString << " sector " << sectorReport.m_sectorName << " " << sectorReport.m_guid);
30 
31  if (sectorReport.m_clientInputLoaded)
32  {
33  os << prefix << "INPUT: LOADED FROM CLIENTINPUT" << Endl;
34  os << prefix << prefix << "Loaded: " << sectorReport.m_loadedClientInputAbsoluteFileName << Endl;
35  os << prefix << prefix << "Input Consume time : " << fmt2f(sectorReport.m_sectorInputConsumptionDuration) << " seconds" << Endl;
36  os << prefix << prefix << "InputTriangle Count: " << sectorReport.m_consumedTriangleCount << " triangles" << Endl;
37  }
38 
39  if (sectorReport.m_sectorInputProduced)
40  {
41  os << prefix << "INPUT: GENERATED FROM INPUTPRODUCER"<< Endl;
42  os << prefix << prefix << "Input Consume time: " << fmt2f(sectorReport.m_sectorInputConsumptionDuration) << " seconds" << Endl;
43  os << prefix << prefix << "InputTriangle Count: " << sectorReport.m_consumedTriangleCount << Endl;
44  os << prefix << prefix << "Saved: " << GeneratorReportGetNoneIfEmpty(sectorReport.m_savedClientInputAbsoluteFileName) << Endl;
45  }
46 
47 
48  if (sectorReport.m_navDataGenerated)
49  {
50  os << prefix << "GENERATED NAVDATA: REGULAR" << Endl;
51  os << prefix << prefix << "Generation Time: " << fmt2f(sectorReport.m_sectorRawNavMeshTime) << " seconds" << Endl;
52  os << prefix << prefix << "NavData Size : " << fmt2f(sectorReport.m_navDataSizeInBytes / 1024.0f) << " kilobytes" << Endl;
53  os << prefix << prefix << "NavData File: " << GeneratorReportGetNoneIfEmpty(sectorReport.m_savedNavDataAbsoluteFileName) << Endl;
54  }
55 
56  if (sectorReport.m_navDataPatchGenerated)
57  {
58  os << prefix << "GENERATED NAVDATA: PATCH" << Endl;
59  os << prefix << prefix << "Generation Time : " << fmt2f(sectorReport.m_sectorRawNavMeshTime) << " seconds" << Endl;
60  os << prefix << prefix << "NavDataPatch Size: " << fmt2f(sectorReport.m_navDataPatchSizeInBytes / 1024.0f) << " kilobytes" << Endl;
61  os << prefix << prefix << "NavDataPatch File: " << GeneratorReportGetNoneIfEmpty(sectorReport.m_savedNavDataPatchAbsoluteFileName) << Endl;
62 
63  }
64 
65  if (sectorReport.SomethingHappenedForThisSector() == false)
66  {
67  os << prefix << "Nothing loaded or generated" << Endl;
68  }
69 
70  // ---------------------------------------- Details ----------------------------------------
71  if (sectorReport.m_doLogDetails)
72  {
73  const Box3f& box = sectorReport.m_inputBoundingBox;
74 
75  KyFloat32 extentX = box.m_max.x - box.m_min.x;
76  KyFloat32 extentY = box.m_max.y - box.m_min.y;
77  if (extentX > 0.0f && extentY > 0.0f)
78  {
79  os << prefix << "Input geometry BBOX Min: (" << fmt2f(box.m_min.x) << "," << fmt2f(box.m_min.y) << "," << fmt2f(box.m_min.z) << ")" << Endl;
80  os << prefix << "Input geometry BBOX Max: (" << fmt2f(box.m_max.x) << "," << fmt2f(box.m_max.y) << "," << fmt2f(box.m_max.z) << ")" << Endl;
81  os << prefix << "Input geometry BBOX Extent: " << fmt2f(extentX * 0.0001f) << " Km by " << fmt2f(extentY * 0.0001f) << " Km" << Endl;
82  }
83 
84  os << prefix << "Nb Input cells: " << sectorReport.m_inputCellsCount << Endl;
85  os << prefix << "Nb NavData cells: " << sectorReport.m_generatedTotalNavCellsCount << Endl;
86  os << prefix << "Nb Main cells: " << sectorReport.m_generatedMainNavCellsCount << Endl;
87  os << prefix << "Nb Overlap cells: " << sectorReport.m_generatedOverlapNavCellsCount << Endl;
88  os << prefix << "Nb NavData Element: " << sectorReport.m_navdataElementsCount << Endl;
89  os << prefix << "NavMesh size: " << sectorReport.m_totalNavmeshSizeInBytes << " bytes" << Endl;
90  os << prefix << "Overlap size: " << sectorReport.m_overlapDataSizeInBytes << " bytes" << Endl;
91  }
92 
93  os << KY_LOG_SMALL_TITLE_END(prefix, "sector " << sectorReport.m_sectorName);
94 
95  return os;
96 }
97 
98 
107 {
108  KY_DEFINE_NEW_DELETE_OPERATORS(Stat_Default_Mem)
109 
110 public:
113  m_doLogTitle(true),
114  m_doLogDetails(true),
115  m_doLogPerSectorReport(true),
130  {
131  m_logPrefix = " ";
132  }
133 
134  void AddSectorStats(const GeneratorSectorReport& sectorStats)
135  {
136  m_sectorStatistics.PushBack(sectorStats);
137 
138  if (sectorStats.m_isPatch)
140  else
142 
143  if (sectorStats.m_sectorInputProduced)
145 
146  if (sectorStats.m_clientInputLoaded)
148 
149  if (sectorStats.m_savedClientInputAbsoluteFileName != "")
151 
152  if (sectorStats.m_navDataGenerated)
154 
155  if (sectorStats.m_navDataPatchGenerated)
157 
158  // m_rawNavMeshGenerationSeconds was timed globally, we have to subtract the time taken in each sector LoadInputTile
161  }
162 
163 public:
164  bool m_doLogTitle;
165  bool m_doLogDetails;
166  bool m_doLogPerSectorReport;
167  String m_logPrefix;
168 
176 
184 
186  AbstractDataGenerationReport m_abstractDataReport;
187 
188  String m_absoluteGeneratorInputOuputSaveFileName;
189 };
190 
191 
192 template <class OSTREAM>
193 inline void LogGenerationTime(OSTREAM& os, const char* prefix, const char* title, KyFloat32 seconds, KyFloat32 minSecondsToLog)
194 {
195  FloatFormatter fmt2f("%.2f");
196  if (seconds >= minSecondsToLog)
197  os << prefix << title << fmt2f(seconds) << " seconds" << Endl;
198 }
199 
200 
201 template <class OSTREAM>
202 inline void LogGenerationCount(OSTREAM& os, const char* prefix, const char* title, KyUInt32 count, KyFloat32 minCountToLog)
203 {
204  if (count >= minCountToLog)
205  os << prefix << title << count << Endl;
206 }
207 
208 template <class OSTREAM>
209 inline OSTREAM& LogTimes(OSTREAM& os, const GeneratorReport& report)
210 {
211  FloatFormatter fmt2f("%.2f");
212  const char* prefix = report.m_logPrefix.ToCStr();
213  LogGenerationTime(os, prefix, "Input Consumption time: ", report.m_inputConsumptionSeconds , 0.05f);
214  LogGenerationTime(os, prefix, "Load InputTiles time: ", report.m_loadInputTilesSeconds , 0.05f);
215  LogGenerationTime(os, prefix, "Raw NavMesh Generation time: ", report.m_rawNavMeshGenerationSeconds, 0.05f);
216  LogGenerationTime(os, prefix, "TagVolume Integration time: ", report.m_tagVolumeIntegrationSeconds, 0.05f);
217  LogGenerationTime(os, prefix, "NavMesh Filtering time: ", report.m_navMeshFilteringSeconds , 0.05f);
218  LogGenerationTime(os, prefix, "Aggregate NavData time: ", report.m_aggregateNavDataSeconds , 0.05f);
219  LogGenerationTime(os, prefix, "Total Generation time: ", report.m_totalGenerationSeconds , 0.0f);
220  return os;
221 }
222 
223 template <class OSTREAM>
224 inline OSTREAM& operator<<(OSTREAM& os, const GeneratorReport& report)
225 {
226  FloatFormatter fmt2f("%.2f");
227  const char* prefix = report.m_logPrefix.ToCStr();
228 
229  if (report.m_doLogTitle)
230  os << KY_LOG_BIG_TITLE_BEGIN(prefix, "GENERATION REPORT");
231 
232  os << prefix << "Saved GenIO File: " << GeneratorReportGetNoneIfEmpty(report.m_absoluteGeneratorInputOuputSaveFileName) << Endl;
233 
234  LogTimes(os, report);
235 
236  LogGenerationCount(os, prefix, "REGULAR Sector count: ", report.m_regularSectorCount , 1);
237  LogGenerationCount(os, prefix, "PATCH Sector count: ", report.m_patchSectorCount , 1);
238  LogGenerationCount(os, prefix, "ClientInput Loaded count: ", report.m_clientInputLoadedCount , 1);
239  LogGenerationCount(os, prefix, "Sector InputProduced count: ", report.m_sectorInputProduceCount , 1);
240  LogGenerationCount(os, prefix, "ClientInput Saved count: ", report.m_clientInputSavedCount , 1);
241  LogGenerationCount(os, prefix, "Generated NavData Patch count: ", report.m_navDataPatchGeneratedCount , 1);
242  LogGenerationCount(os, prefix, "Generated NavData count: ", report.m_navDataGeneratedCount , 1);
243  os << Endl;
244 
245  if (report.m_doLogPerSectorReport)
246  {
247  // report sectors for which *something* happened (and count sectorForWhichSomethingHappened)
248  KyUInt32 sectorsForWhichSomethingHappened = 0;
249  for (KyUInt32 i = 0; i < report.m_sectorStatistics.GetCount(); ++i)
250  {
251  const GeneratorSectorReport& stats = report.m_sectorStatistics[i];
252  if (stats.SomethingHappenedForThisSector() == true)
253  {
254  stats.m_doLogDetails = report.m_doLogDetails;
255  os << stats;
256  }
257  else
258  {
259  ++sectorsForWhichSomethingHappened ;
260  }
261  }
262 
263  // report sectors for which *nothing* happened
264  if (sectorsForWhichSomethingHappened > 0)
265  {
266  os << KY_LOG_SMALL_TITLE_BEGIN(prefix, sectorsForWhichSomethingHappened << " Sectors for which nothing happened");
267  for (KyUInt32 i = 0; i < report.m_sectorStatistics.GetCount(); ++i)
268  {
269  const GeneratorSectorReport& stats = report.m_sectorStatistics[i];
270  if (stats.SomethingHappenedForThisSector() == false)
271  {
272  const char* isPatchString = stats.m_isPatch ? "PATCH " : "REGULAR";
273  os << prefix << isPatchString << " sector " << stats.m_guid << " " << stats.m_sectorName << Endl;
274  }
275  }
276  os << KY_LOG_SMALL_TITLE_END(prefix, "Sectors for which nothing happened");
277  }
278  }
279 
280  if (report.m_doLogTitle)
281  os << KY_LOG_BIG_TITLE_END(prefix, "GENERATION REPORT");
282 
283 
284  // log AbstractData generation if any
285  os << report.m_abstractDataReport;
286 
287  return os;
288 }
289 
290 
291 }
292 
293 
294 
KyFloat32 m_sectorLoadInputTileTime
Maintains the time taken to load the InputTile for the sector.
Definition: generatorsectorreport.h:89
The GeneratorReport class encapsulates a detailed report of all activities carried out during a call ...
Definition: generatorreport.h:106
std::uint32_t KyUInt32
uint32_t
Definition: types.h:29
KyFloat32 m_loadInputTilesSeconds
The time taken to load of InputTile files, in seconds. Relevant when runOptions.m_doEnableLimitedMemo...
Definition: generatorreport.h:171
KyUInt32 m_clientInputLoadedCount
The number of sectors for which LoadClientInput() was called.
Definition: generatorreport.h:180
bool m_clientInputLoaded
Indicates if the client input loaded for this sector.
Definition: generatorsectorreport.h:66
General purpose array for movable objects that require explicit construction/destruction.
Definition: kyarray.h:162
KyArray< GeneratorSectorReport > m_sectorStatistics
Maintains an array of objects that contain detailed statistics about the sectors for which NavData wa...
Definition: generatorreport.h:185
KyFloat32 m_navMeshFilteringSeconds
The time taken to remove not reachable parts of the NavMesh, in seconds.
Definition: generatorreport.h:174
The SectorStatistics class encapsulates a detailed set of statistics about a single sector treated by...
Definition: generatorsectorreport.h:19
#define KY_DEFINE_NEW_DELETE_OPERATORS(MemStat)
This macro defines new and delete operators.
Definition: memory.h:132
KyUInt32 m_patchSectorCount
The number of patch sector.
Definition: generatorreport.h:178
KyUInt32 m_sectorInputProduceCount
The number of sectors for which ProduceInputs() was called.
Definition: generatorreport.h:179
KyUInt32 m_regularSectorCount
The number of sector.
Definition: generatorreport.h:177
KyFloat32 m_totalGenerationSeconds
The total time taken by the NavData generation process, in seconds.
Definition: generatorreport.h:169
KyUInt32 m_navDataPatchGeneratedCount
The number of generated Patch NavData.
Definition: generatorreport.h:183
The Autodesk Navigation namespace.
Definition: gamekitcrowddispersion.cpp:17
KyUInt32 m_clientInputSavedCount
The number of sectors for which SaveClientInput() was called.
Definition: generatorreport.h:181
KyFloat32 m_aggregateNavDataSeconds
The time taken to aggregate the generated NavCells into NavData buffer (and optionnaly ...
Definition: generatorreport.h:175
bool m_navDataGenerated
Indicates if the NavData was generated for this sector.
Definition: generatorsectorreport.h:68
KyUInt32 m_navDataGeneratedCount
The number of sectors for generated Regular NavData.
Definition: generatorreport.h:182
bool m_sectorInputProduced
Indicates if the InputProducer was called for this sector.
Definition: generatorsectorreport.h:67
KyFloat32 m_inputConsumptionSeconds
The time taken to consume the input geometry, in seconds.
Definition: generatorreport.h:170
KyFloat32 m_tagVolumeIntegrationSeconds
The time taken to integrate the generation TagVolumes, in seconds.
Definition: generatorreport.h:173
bool m_navDataPatchGenerated
Indicates if the Patch.X.NavData was generated for this sector.
Definition: generatorsectorreport.h:69
GeneratorReport()
For internal use: constructs a new GeneratorReport.
Definition: generatorreport.h:112
KyFloat32 m_rawNavMeshGenerationSeconds
The time taken to generate the RawNavMesh, in seconds. Does not include m_loadInputTilesSeconds.
Definition: generatorreport.h:172
float KyFloat32
float
Definition: types.h:32