gwnavgeneration/generator/generatorreport.h Source File

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