Arma Reforger Explorer 1.7.0.54
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
Loading...
Searching...
No Matches
Screenshot_Autotest.c
Go to the documentation of this file.
5
6[EntityEditorProps(category: "GameLib/Scripted/Autotest", description:"Screenshot_autotest", dynamicBox: true)]
7class Screenshot_AutotestClass: GenericEntityClass
8{
9}
10
11[EntityEditorProps(category: "GameLib/Scripted/Autotest", description:"Screenshot_waypoint", dynamicBox: true)]
12class Screenshot_WaypointClass: GenericEntityClass
13{
14}
15
16//----------------------------------------------
17
26class Screenshot_Autotest: GenericEntity
27{
28 [Attribute("1980", UIWidgets.SpinBox, "Year", "1900 2100 1")]
29 private int m_defaultYear;
30
31 [Attribute("8", UIWidgets.SpinBox, "Month", "1 12 1")]
32 private int m_defaultMonth;
34 [Attribute("20", UIWidgets.SpinBox, "Day", "1 31 1")]
35 private int m_defaultDay;
36
37 [Attribute("12.0", UIWidgets.Slider, "Default Time of the Day", "0 24 0.01")]
38 private float m_defaultTimeOfTheDay;
39
40 [Attribute("Clear", UIWidgets.EditBox, "Default Weather State", "")]
41 private string m_defaultWeatherState;
42
43
44 [Attribute("Camera1", UIWidgets.EditBox, "Name of camera entity", "")]
45 private string m_cameraEntityName; //< name of camera entity which will be used to take screenshots
46 [Attribute("", UIWidgets.EditBox, "Autotest description", "")]
47 private string m_description; //< description of the autotest
48
49 [Attribute("1", UIWidgets.Slider, "Wait time in the waypoint before taking screenshot", "0 20 0.1")]
50 private float m_stepWaitTime; //< this time is waited before taking screenshot
51 [Attribute("2", UIWidgets.Slider, "Wait time in the waypoint after preload", "0 5 0.1")]
52 private float m_WaitTimeAfterPreload; //< this time is waited after preload
53 [Attribute("1", UIWidgets.Slider, "Wait time for the screenshot to be made", "0 20 0.1")]
54 private float m_screenshotWaitTime; //< this time is waited for the screenshot to be captured and saved on disk
55 [Attribute("60", UIWidgets.Slider, "Which FPS is considered as minimal", "0 240 1")]
56 private float m_FPSLimit; //< this time is waited for the screenshot to be captured and saved on disk
57 [Attribute("true", UIWidgets.CheckBox, "Generate summary file")]
58 private bool m_summary;
59
60 protected float m_timer;
61 protected float m_timeFromStart;
62 protected float m_timerAfterPreload;
63
64 private IEntity m_camera;
65 private Screenshot_Waypoint m_waypoint;
66 private float m_timeFromScreenshot;
67 private string m_directory;
68 private bool m_initialized;
69
70 private TextWidget m_FPSWidget;
71
72 void Screenshot_Autotest(IEntitySource src, IEntity parent)
73 {
75
76 System.GetCLIParam("autotest-output-dir", m_directory);
77
78 if (m_directory.Length() == 0)
79 {
80 m_directory = "$logs:" + GetName();
81 }
82 }
83
85 {
86 delete m_FPSWidget;
87 }
88
89 float GetDefaultTimeOfTheDay()
90 {
91 return m_defaultTimeOfTheDay;
92 }
93
94 int GetDefaultYear()
95 {
96 return m_defaultYear;
97 }
98
99 int GetDefaultMonth()
100 {
101 return m_defaultMonth;
102 }
103
104 int GetDefaultDay()
105 {
106 return m_defaultDay;
107 }
108
109 string GetDefaultWeatherState()
110 {
111 return m_defaultWeatherState;
112 }
113
114 override void EOnInit(IEntity owner)
115 {
116 m_camera = g_Game.FindEntity(m_cameraEntityName);
117 m_waypoint = Screenshot_Waypoint.Cast(GetChildren());
118
119 if (!m_camera)
120 {
121 Print("Camera not found!", LogLevel.ERROR);
122 }
123
124 if (!m_waypoint)
125 {
126 Print("No waypoints for screenshots!", LogLevel.WARNING);
127 }
128
129 //Can't preload during EOnInit we need to wait until start preloading first waypoint
130 //TransformCameraToWaypoint();
131
132 m_FPSWidget = TextWidget.Cast(g_Game.GetWorkspace().CreateWidgetInWorkspace(WidgetType.TextWidgetTypeID, 16, 16, 512, 128, WidgetFlags.VISIBLE, new Color(0.0, 0.0, 0.0, 1.0), 1024));
133 m_FPSWidget.SetExactFontSize(64);
134 }
135
136 override void EOnFrame(IEntity owner, float timeSlice)
137 {
138 g_Game.GetInputManager().ActivateContext("BlockInputContext");
139
140 if (!m_camera)
141 {
142 Print("Exiting the game", LogLevel.WARNING);
144 }
145
146 if (!m_waypoint)
147 {
148 Print("No waypoints for next screenshot");
149 if (m_summary)
150 {
151 string summaryFilename = string.Format("%1/%2", m_directory, "summary.txt");
152 MakeSummaryFile(summaryFilename);
153 summaryFilename = string.Format("%1/%2", m_directory, "summary.csv");
154 MakeCSVSummaryFile(summaryFilename);
155 }
157 }
158
159 if (!m_initialized)
160 {
161 TransformCameraToWaypoint();
162 m_initialized = true;
163 }
164
166 {
168 m_FPSWidget.SetColor(new Color(1.0, 1.0, 1.0, 1.0));
169 m_FPSWidget.SetText("Preloading");
170 return;
171 }
172
173 if (m_timerAfterPreload < m_WaitTimeAfterPreload)
174 {
175 m_timerAfterPreload += timeSlice;
176 m_FPSWidget.SetColor(new Color(1.0, 1.0, 1.0, 1.0));
177 m_FPSWidget.SetText("Waiting after preload...");
178 return;
179 }
180
181 int fps = System.GetFPS();
182 m_FPSWidget.SetText("FPS " + fps);
183 if (fps < m_FPSLimit)
184 m_FPSWidget.SetColor(new Color(1.0, 0.0, 0.0, 1.0));
185 else
186 m_FPSWidget.SetColor(new Color(0.0, 1.0, 0.0, 1.0));
187
188 if (m_timer > m_stepWaitTime && m_timeFromScreenshot == 0)
189 {
190 m_timer = 0;
191
192 string screenshotFilename = string.Format("%1/%2.bmp", m_directory, m_waypoint.GetName());
193 string metadataFilename = screenshotFilename + ".txt";
194 string summaryFilename = string.Format("%1/%2", m_directory, "summary_locations.csv");
195
196 m_timeFromScreenshot = m_timeFromStart;
197
198 FileIO.MakeDirectory(m_directory); // no need to create it for every screenshot, but better then have it in constructor or in init, because directory would be created when placing entity into the world in editor which might not be intended
199 MakeLocationsCSVSummaryFile(summaryFilename);
200 MakeScreenshotMetafile(metadataFilename);
201 System.MakeScreenshot(screenshotFilename);
202 }
203
204 if (m_timeFromScreenshot == 0)
205 {
206 m_timer += timeSlice; // increment timer only when we are not taking screenshots
207 }
208 else if (m_timeFromScreenshot + m_screenshotWaitTime < m_timeFromStart)
209 {
210 m_timeFromScreenshot = 0; // screenshot wait time is up, go to the next waypoint
211 if(m_waypoint) m_waypoint.EOnExit();
212 m_waypoint = Screenshot_Waypoint.Cast(m_waypoint.GetSibling());
213 TransformCameraToWaypoint();
214 }
215
216 m_timeFromStart += timeSlice;
217 }
218
219 private void MakeSummaryFile(string filename)
220 {
221 FileHandle descrFile = FileIO.OpenFile(filename, FileMode.WRITE);
222
223 if(descrFile)
224 {
225 if (m_description.Length() > 0)
226 descrFile.WriteLine(string.Format("%1", m_description));
227 int sizeX = g_Game.GetWorkspace().GetWidth();
228 int sizeY = g_Game.GetWorkspace().GetHeight();
229
230 descrFile.WriteLine(string.Format("Resolution (px): %1x%2", sizeX, sizeY));
231#ifdef WORKBENCH
232 descrFile.WriteLine(string.Format("Entering playmode time (s): %1", g_Game.GetLoadTime() / 1000));
233#else
234 descrFile.WriteLine(string.Format("Load time (s): %1", g_Game.GetLoadTime() / 1000));
235#endif
236 descrFile.WriteLine(string.Format("Memory (MB): %1", System.MemoryAllocationKB() / 1024));
237 descrFile.WriteLine(string.Format("Allocations: %1", System.MemoryAllocationCount()));
238 descrFile.WriteLine(string.Format("Duration (s): %1", m_timeFromStart));
239 descrFile.Close();
240 Print("Summary file successfully saved into " + filename);
241 }
242 }
243
244 private void MakeCSVSummaryFile(string filename)
245 {
246 FileHandle descrFile = FileIO.OpenFile(filename, FileMode.WRITE);
247
248 if(descrFile)
249 {
250 int sizeX = g_Game.GetWorkspace().GetWidth();
251 int sizeY = g_Game.GetWorkspace().GetHeight();
252
253 descrFile.WriteLine("Resolution (px),Load time (s),Memory (MB),Allocations,Duration (s),Timestamp");
254 descrFile.WriteLine(string.Format("%1x%2,%3,%4,%5,%6,%7",
255 sizeX, sizeY,
256 g_Game.GetLoadTime() / 1000,
257 System.MemoryAllocationKB() / 1024,
258 System.MemoryAllocationCount(),
260 GetCurrentTimestamp()
261 ));
262
263 descrFile.Close();
264 Print("Summary file successfully saved into " + filename);
265 }
266 }
267
268 private void MakeLocationsCSVSummaryFile(string filename)
269 {
270 FileHandle descrFile;
271
272 if(!FileIO.FileExists(filename))
273 {
274 descrFile = FileIO.OpenFile(filename, FileMode.WRITE);
275
276 if(descrFile)
277 {
278 descrFile.WriteLine("Scene name,FPS,Frame time (ms),Timestamp");
279
280 descrFile.Close();
281 Print("Headers successfully saved into " + filename);
282 }
283 }
284
285 descrFile = FileIO.OpenFile(filename, FileMode.APPEND);
286
287 if(descrFile)
288 {
289 descrFile.WriteLine(string.Format("%1,%2,%3,%4",
290 m_waypoint.GetName(),
291 System.GetFPS(),
292 1000.0 * System.GetFrameTimeS(),
293 GetCurrentTimestamp()
294 ));
295
296 descrFile.Close();
297 Print("Scene data successfully saved into " + filename);
298 }
299 }
300
301 private string GetCurrentTimestamp()
302 {
303 int year, month, day;
304 System.GetYearMonthDay(year, month, day);
305 return string.Format("%1-%2-%3", year.ToString(4), month.ToString(2), day.ToString(2));
306 }
307
308 private void MakeScreenshotMetafile(string filename)
309 {
310 FileHandle descrFile = FileIO.OpenFile(filename, FileMode.WRITE);
311
312 vector position = m_camera.GetOrigin();
313 vector orientation = m_camera.GetYawPitchRoll();
314
315 if(descrFile)
316 {
317 string description = m_waypoint.GetDescription();
318 if (description.Length() > 0)
319 descrFile.WriteLine(string.Format("%1", description));
320 descrFile.WriteLine(string.Format("FPS: %1", System.GetFPS()));
321 descrFile.WriteLine(string.Format("Frame time (ms): %1", 1000.0 * System.GetFrameTimeS()));
322 descrFile.WriteLine(string.Format("Position: [%1, %2, %3]", position[0], position[1], position[2]));
323 descrFile.WriteLine(string.Format("XYZ Rotation: [%1, %2, %3]", orientation[1], orientation[0], orientation[2]));
324
325 string link = string.Format("enfusion://WorldEditor/%1;%2,%3,%4;%5,%6,%7", g_Game.GetWorldFile(), position[0], position[1], position[2], orientation[1], orientation[0], orientation[2]);
326 float normalizedTime;
327 int year;
328 int month;
329 int day;
330
331 if (GetTimeAndDate(normalizedTime, year, month, day))
333 descrFile.WriteLine(string.Format("Time: %1", normalizedTime));
334 descrFile.WriteLine(string.Format("Date: %1/%2/%3", year, month, day));
335 link += string.Format(",%1,%2,%3,%4", normalizedTime, year, month, day);
336 }
337
338 descrFile.WriteLine(string.Format("<a href=\"%1\">Link to World Editor</a>", link));
339
340 descrFile.Close();
341 Print("Screenshot metafile successfully saved into " + filename);
342 }
343 }
344
345 private void TransformCameraToWaypoint()
346 {
347 if (m_waypoint && m_camera)
348 {
349 vector mat[4];
350 m_waypoint.GetTransform(mat);
351 m_camera.SetTransform(mat);
352 m_waypoint.EOnEnter();
354 float cameraFarPlane = GetWorld().GetCameraFarPlane(GetWorld().GetCurrentCameraId());
355
356 g_Game.BeginPreload(GetWorld(), mat[3], cameraFarPlane);
357 }
358 }
359
360 protected bool GetTimeAndDate(out float normTime, out int year, out int month, out int day)
361 {
362 BaseWorld world = GetWorld();
363
364 if(world)
365 {
366 BaseWeatherManagerEntity weatherEntity = BaseWeatherManagerEntity.Cast(WeatherManager.GetRegisteredWeatherManagerEntity(world));
367
368 if(weatherEntity)
369 {
370 normTime = weatherEntity.GetTimeOfTheDay() / 24.0;
371 year = weatherEntity.GetYear();
372 month = weatherEntity.GetMonth();
373 day = weatherEntity.GetDay();
374 return true;
375 }
376 }
377
378 return false;
379 }
380
381 bool SetTimeAndDate(float timeOfTheDay24h, int year, int month, int day)
382 {
383 BaseWorld world = GetWorld();
384
385
386 if(world)
387 {
388 BaseWeatherManagerEntity weatherEntity = BaseWeatherManagerEntity.Cast(WeatherManager.GetRegisteredWeatherManagerEntity(world));
389
390 if (weatherEntity)
391 {
392 weatherEntity.SetDate(year, month, day, true);
393 weatherEntity.SetTimeOfTheDay(timeOfTheDay24h);
394 return true;
395 }
396 }
397
398 return false;
399 }
400
401 bool SetWeatherState(string state)
402 {
403 BaseWorld world = GetWorld();
404
405 if(world)
406 {
407 BaseWeatherManagerEntity weatherEntity = BaseWeatherManagerEntity.Cast(WeatherManager.GetRegisteredWeatherManagerEntity(world));
408
409 if (weatherEntity)
410 {
411 BaseWeatherStateTransitionManager transManager = weatherEntity.GetTransitionManager();
412
413 if(transManager)
414 {
415 WeatherStateTransitionNode node = transManager.CreateStateTransition(state, 0.1, 0.1);
416 if(node)
417 {
418 transManager.EnqueueStateTransition(node, false);
419 transManager.RequestStateTransitionImmediately(node);
420 }
421 }
422
423 return true;
424 }
425 }
426
427 return false;
428 }
429}
430
431//----------------------------------------------
432
433class Screenshot_Waypoint: GenericEntity
434{
435 [Attribute("", UIWidgets.EditBox, "Waypoint description", "")]
436 private string m_description; //< description of the autotest
437
438 [Attribute("", UIWidgets.EditBox, "Weather state", "")]
439 private string m_weatherState;
440
441 [Attribute("-1", UIWidgets.Slider, "Time of the day", "-1 24 0.01")]
442 private float m_timeOfTheDay;
443
444 [Attribute("-1", UIWidgets.SpinBox, "Year", "")]
445 private int m_year;
446
447 [Attribute("-1", UIWidgets.SpinBox, "Month", "")]
448 private int m_month;
449
450 [Attribute("-1", UIWidgets.SpinBox, "Day", "")]
451 private int m_day;
452
453
454 void Screenshot_Waypoint(IEntitySource src, IEntity parent)
455 {
456 if (parent)
457 {
458 SetFlags(EntityFlags.ACTIVE, true);
459
460 vector position;
461 vector angles;
462 vector rotation; // we cannot supply array as a out param, so we need the floats and then assign them to vector
463 src.Get("coords", position);
464 src.Get("angles", angles);
465
466 rotation[1] = angles[0];
467 rotation[0] = angles[1];
468 rotation[2] = angles[2];
469
470 vector mat[4];
471 Math3D.AnglesToMatrix(rotation, mat);
472
473 mat[3] = position;
474
475 SetTransform(mat); // needs to be done because addchild is counting with the transform of parent which was already applied so we need to set local position and transform
476
477 parent.AddChild(this, -1);
478 }
479 }
480
481 void ~Screenshot_Waypoint()
482 {
483
484 }
485
489 event void EOnEnter()
490 {
491 Screenshot_Autotest parent = Screenshot_Autotest.Cast(GetParent());
492
493 if(parent)
494 {
495 float time = parent.GetDefaultTimeOfTheDay();
496 int year = parent.GetDefaultYear();
497 int month = parent.GetDefaultMonth();
498 int day = parent.GetDefaultDay();
499 string state = parent.GetDefaultWeatherState();
500
501 if(m_timeOfTheDay >= 0)
502 {
503 time = m_timeOfTheDay;
504 }
505
506 if(m_year >= 1900 && m_year <= 2100)
507 {
508 year = m_year;
509 }
510 if(m_month >= 1 && m_month <= 12)
511 {
512 month = m_month;
513 }
514 if(m_day >= 1 && m_day <= 31)
515 {
516 day = m_day;
517 }
518
519 if(m_weatherState.Length() > 0)
520 {
521 state = m_weatherState;
522 }
523
524 parent.SetTimeAndDate(time, year, month, day);
525 parent.SetWeatherState(state);
526 }
527 }
528
529 event void EOnExit()
530 {
531 }
532
533 string GetDescription()
534 {
535 return m_description;
536 }
537}
538
ref array< string > angles
vector position
enum EVehicleType IEntity
proto external void RequestClose()
Setting request flag for engine to exit the game.
proto external bool IsPreloadFinished()
If preload (started with BeginPreload method) is finished, returns true.
proto external int GetLoadTime()
Returns load time in milliseconds for the lastly loaded world.
sealed InputManager GetInputManager()
Definition Game.c:14
proto external IEntity FindEntity(string name)
sealed WorkspaceWidget GetWorkspace()
Definition Game.c:16
proto external string GetWorldFile()
Returns path of world file loaded.
void IEntity(IEntitySource src, IEntity parent)
protected script Constructor
proto external EntityEvent SetEventMask(EntityEvent e)
proto external int AddChild(notnull IEntity child, TNodeId pivot, EAddChildFlags flags=EAddChildFlags.AUTO_TRANSFORM)
Add Entity to hierarchy. Pivot is pivot index, or -1 for center of parent.
proto external IEntity GetChildren()
proto external BaseWorld GetWorld()
proto external bool SetTransform(vector mat[4])
proto external EntityFlags SetFlags(EntityFlags flags, bool recursively=false)
proto external IEntity GetParent()
proto external string GetName()
bool SetTimeAndDate(float timeOfTheDay24h, int year, int month, int day)
bool SetWeatherState(string state)
bool GetTimeAndDate(out float normTime, out int year, out int month, out int day)
Game g_Game
Game singleton instance.
Definition gameLib.c:13
proto void Print(void var, LogLevel level=LogLevel.NORMAL)
Prints content of variable to console/log.
LogLevel
Enum with severity of the logging message.
Definition LogLevel.c:14
SCR_FieldOfViewSettings Attribute
EntityEvent
Various entity events.
Definition EntityEvent.c:14
EntityFlags
Various entity flags.
Definition EntityFlags.c:14
RespawnSystemComponentClass GameComponentClass vector vector rotation
Screenshot_AutotestClass GenericEntityClass EntityEditorProps(category:"GameLib/Scripted/Autotest", description:"Screenshot_waypoint", dynamicBox:true)
FileMode
Mode for opening file. See FileSystem::Open.
Definition FileMode.c:14
WidgetFlags
Widget flags. See enf::Widget::SetFlags().
Definition WidgetFlags.c:14
TypeID WidgetType
Definition EnWidgets.c:6