Arma Reforger Explorer  1.1.0.42
Arma Reforger Code Explorer by Zeroy - Thanks to MisterOutofTime
SCR_EditorImageGeneratorEntity.c
Go to the documentation of this file.
1 [EntityEditorProps(category: "GameScripted/Editor", description: "Manager of image generators", color: "255 0 0 255", dynamicBox: true)]
2 class SCR_EditorImageGeneratorEntityClass: GenericEntityClass
3 {
4 };
5 
13 {
14  [Attribute("800")]
15  protected int m_iImageWidth;
16 
17  [Attribute("600")]
18  protected int m_iImageHeight;
19 
20  [Attribute(desc: "When enabled, the system will not iterate through prefabs on its own.\nInstead, you'll have to press 'Space' to continue to next prefab.")]
21  protected bool m_bManualProgress;
22 
23  [Attribute(desc: "When enabled, the system will not check for correct viewport resolution and screenshot format upon start, and not capture any screenshots.\nFOR DEBUGGING ONLY!")]
24  protected bool m_bDebugMode;
25 
26 #ifdef WORKBENCH
27  protected int m_iInit = 0;
28  protected ref SCR_SortedArray<SCR_EditorImagePositionEntity> m_aPositions = new SCR_SortedArray<SCR_EditorImagePositionEntity>();
29  protected ref array<ref SCR_EditorImageGeneratorPrefab> m_aSelectedPrefabs = {};
30  protected int m_iSelectedPrefabsCount;
31  protected static ref array<vector> s_aSelectedPositions = {};
32  protected float m_fTime;
33  protected float m_fTimeNext = -1;
34  protected float m_fTimeRemaining;
35  protected int m_iPrefabIndex = -1;
36  protected SCR_EditorImageGeneratorPrefab m_CurrentPrefab;
37  protected bool m_bIsScreenshotMade;
38 
40  {
41  return SCR_EditorImageGeneratorEntity.Cast(GetGame().FindEntity("SCR_EditorImageGeneratorEntity"));
42  }
43 
44  SCR_EditorImagePositionEntity FindSuitablePosition(array<EEditableEntityLabel> labels)
45  {
47  for (int i = m_aPositions.Count() - 1; i >= 0; i--)
48  {
49  position = m_aPositions.GetValue(i);
50  if (position.IsSuitable(labels) && IsPositionSelected(position))
51  return position;
52  }
53  return null;
54  }
55  protected bool IsPositionSelected(SCR_EditorImagePositionEntity position)
56  {
57  if (s_aSelectedPositions.IsEmpty())
58  return true;
59 
60  for (int i = 0, count = s_aSelectedPositions.Count(); i < count; i++)
61  {
62  if (vector.DistanceSq(position.GetOrigin(), s_aSelectedPositions[i]) < 1)
63  return true;
64  }
65  return false;
66  }
67 
68  void AddPosition(SCR_EditorImagePositionEntity position)
69  {
70  m_aPositions.Insert(position.GetPriority(), position);
71  }
72  static void AddSelectedPosition(SCR_EditorImagePositionEntity position)
73  {
74  s_aSelectedPositions.Insert(position.GetOrigin());
75  }
76  protected void AddSelectedPrefab(ResourceName prefab, string filePath)
77  {
78  string ext;
79  FilePath.StripExtension(prefab, ext);
80  if (ext != "et")
81  return;
82 
83  Resource res = Resource.Load(prefab);
84  if (!res || !res.IsValid())
85  return;
86 
87  IEntityComponentSource editableEntitySource = SCR_EditableEntityComponentClass.GetEditableEntitySource(res);
88  if (!editableEntitySource)
89  return;
90 
92  if (!info)
93  {
94  Print(string.Format("Prefab @\"%1\" does not have UI info defined in SCR_EditableEntityComponent!", prefab.GetPath()), LogLevel.WARNING);
95  return;
96  }
97 
98  ResourceName imagePath = info.GetImage();
99  if (imagePath.IsEmpty())
100  {
101  Print(string.Format("Prefab @\"%1\" does not have image path defined in UI info of SCR_EditableEntityComponent!", prefab.GetPath()), LogLevel.WARNING);
102  return;
103  }
104 
105  array<EEditableEntityLabel> labels = {};
106  info.GetEntityLabels(labels);
107  SCR_EditorImagePositionEntity position = FindSuitablePosition(labels);
108  if (!position)
109  {
110  if (s_aSelectedPositions.IsEmpty())
111  {
112  string labelsLine;
113  foreach (int i, EEditableEntityLabel label: labels)
114  {
115  if (i > 0)
116  labelsLine += ", ";
117 
118  labelsLine += typename.EnumToString(EEditableEntityLabel, label);
119  }
120  Print(string.Format("No suitable position found for @\"%1\" with labels %2!", prefab, labelsLine), LogLevel.WARNING);
121  }
122  return;
123  }
124 
125  imagePath = FilePath.StripExtension(imagePath.GetPath());
126  m_aSelectedPrefabs.Insert(new SCR_EditorImageGeneratorPrefab(prefab, imagePath, position));
127  }
128  protected void RequestClose()
129  {
130  GetGame().RequestClose();
131  }
132  protected bool Init()
133  {
134  if (m_iInit <= 1 && !SCR_Global.IsEditMode(this))
135  {
136  if (m_iInit == 1)
137  {
138  //--- Validate screen size
139  if (!m_bDebugMode)
140  {
141  float screenW = GetGame().GetWorkspace().GetWidth();
142  float screenH = GetGame().GetWorkspace().GetHeight();
143  if (screenW != m_iImageWidth || screenH != m_iImageHeight)
144  {
145  Debug.Error2(Type().ToString(), string.Format("Cannot generate images! Current resolution is %1x%2, expected %3x%4!\n", screenW, screenH, m_iImageWidth, m_iImageHeight));
146  GetGame().GetCallqueue().CallLater(RequestClose, false, 1);
147  }
148  }
149 
150  //--- Validate selected prefabs
151  WorldEditor worldEditor = Workbench.GetModule(WorldEditor);
152  worldEditor.GetResourceBrowserSelection(AddSelectedPrefab, true);
153  if (m_aSelectedPrefabs.IsEmpty())
154  {
155  Debug.Error2(Type().ToString(), "No suitable prefabs selected!\n");
156  GetGame().GetCallqueue().CallLater(RequestClose, false, 1);
157  }
158  m_iSelectedPrefabsCount = m_aSelectedPrefabs.Count();
159 
160 
161  //--- Set initial delay
162  m_fTimeNext = m_fTime + 1;
163 
164  if (s_aSelectedPositions.IsEmpty())
165  Print(string.Format("Initiating image generation for %1 prefab(s).", m_iSelectedPrefabsCount), LogLevel.DEBUG);
166  else
167  Print(string.Format("Initiating image generation for %1 prefab(s) on %2 pre-selected position(s).", m_iSelectedPrefabsCount, s_aSelectedPositions.Count()), LogLevel.DEBUG);
168  }
169  m_iInit++; //--- Wait one frame before evaluating screen dimensions, otherwise they will still be default 128x128
170  }
171  return m_iInit > 1;
172  }
173  override void EOnFrame(IEntity owner, float timeSlice)
174  {
175  if (!Init())
176  return;
177 
178  bool canContinue;
179  if (m_fTimeNext != -1 || !m_CurrentPrefab)
180  {
181  canContinue = m_fTime > m_fTimeNext;
182  }
183  else if (Debug.KeyState(KeyCode.KC_SPACE))
184  {
185  Debug.ClearKey(KeyCode.KC_SPACE);
186  canContinue = true;
187  }
188 
189  if (canContinue)
190  {
191  //--- Take a screenshot of existing prefab
192  if (m_CurrentPrefab && !m_bIsScreenshotMade)
193  {
194  m_bIsScreenshotMade = true;
195  if (!m_bDebugMode)
196  {
197  string addonName = SCR_AddonTool.GetResourceLastAddon(m_CurrentPrefab.m_Prefab);
198  addonName = SCR_AddonTool.ToFileSystem(addonName);
199  System.MakeScreenshot(addonName + m_CurrentPrefab.m_ImagePath);
200  Print(string.Format("Image of prefab '%1' at position '%2' saved to @\"%3.png\"", FilePath.StripPath(m_CurrentPrefab.m_Prefab), m_CurrentPrefab.m_Position.GetName(), m_CurrentPrefab.m_ImagePath), LogLevel.DEBUG);
201  return; //--- Wait until next frame to give MakeScreenshot function enough time to actually capture the screen
202  }
203  else
204  {
205  Print(string.Format("SIMULATION: Image of prefab '%1' at position '%2' would be saved to @\"%3.png\"", FilePath.StripPath(m_CurrentPrefab.m_Prefab), m_CurrentPrefab.m_Position.GetName(), m_CurrentPrefab.m_ImagePath), LogLevel.VERBOSE);
206  }
207  }
208 
209  //--- Next prefab
210  m_iPrefabIndex++;
211  if (m_iPrefabIndex >= m_iSelectedPrefabsCount)
212  {
213  GetGame().GetCallqueue().CallLater(RequestClose, false, 1);
214  return;
215  }
216 
217  //--- Delete existing prefab
218  if (m_CurrentPrefab)
219  m_CurrentPrefab.m_Position.DeactivatePosition();
220 
221  //--- Create a new prefab
222  m_bIsScreenshotMade = false;
223  SCR_EditorImageGeneratorPrefab currentPrefab = m_aSelectedPrefabs[m_iPrefabIndex];
224  if (currentPrefab.m_Position.ActivatePosition(currentPrefab.m_Prefab))
225  {
226  m_CurrentPrefab = currentPrefab;
227 
228  if (m_bManualProgress)
229  m_fTimeNext = -1;
230  else
231  m_fTimeNext = m_fTime + currentPrefab.m_Position.GetDelay();
232  }
233  else
234  {
235  m_fTimeNext = 0;
236  }
237 
238  m_fTimeRemaining = 0;
239  for (int i = m_iPrefabIndex, count = m_aSelectedPrefabs.Count(); i < count; i++)
240  {
241  m_fTimeRemaining += m_aSelectedPrefabs[i].m_Position.GetDelay();
242  }
243  }
244 
245  //--- Show progress
246  DbgUI.Begin("SCR_EditorImageGeneratorEntity");
247  if (m_CurrentPrefab)
248  {
249  DbgUI.Text(string.Format("%1\n\n", m_CurrentPrefab.m_Prefab.GetPath()));
250  DbgUI.Text(string.Format("Progress: %1 of %2", m_iPrefabIndex, m_iSelectedPrefabsCount));
251 
252  if (m_fTimeNext == -1)
253  DbgUI.Text("Press 'Space' to take screenshot and continue to next prefab\n\n");
254  else
255  DbgUI.Text(string.Format("Estimated remaining time: %1", SCR_FormatHelper.GetTimeFormatting(m_fTimeRemaining, ETimeFormatParam.DAYS | ETimeFormatParam.HOURS)));
256  }
257  else
258  {
259  DbgUI.Text("Initializing...");
260  }
261  DbgUI.End();
262 
263  m_fTime += timeSlice;
264  m_fTimeRemaining -= timeSlice;
265  }
266  void SCR_EditorImageGeneratorEntity(IEntitySource src, IEntity parent)
267  {
268  SetName("SCR_EditorImageGeneratorEntity");
269  SetEventMask(EntityEvent.FRAME);
270 
271  if (SCR_Global.IsEditMode(this))
272  s_aSelectedPositions.Clear();
273  }
274  override void _WB_AfterWorldUpdate(float timeSlice)
275  {
276  WorldEditorAPI api = _WB_GetEditorAPI();
277  if (!api.IsEntitySelected(api.EntityToSource(this)))
278  return;
279 
280  int screenW = api.GetScreenWidth();
281  int screenH = api.GetScreenHeight();
282 
283  string textCurrent = string.Format("Current resolution: %1x%2", screenW, screenH);
284  string textTarget = string.Format("Target resolution: %1x%2", m_iImageWidth, m_iImageHeight);
285 
286  int color = Color.RED;
287  if (screenW == m_iImageWidth && screenH == m_iImageHeight)
288  color = Color.GREEN;
289  else if (screenW == m_iImageWidth || screenH == m_iImageHeight)
290  color = Color.ORANGE;
291 
292  DebugTextScreenSpace.Create(GetWorld(), textCurrent, DebugTextFlags.ONCE, 0, 0, 18, color, Color.BLACK);
293  DebugTextScreenSpace.Create(GetWorld(), textTarget, DebugTextFlags.ONCE, 0, 18, 18, Color.WHITE, Color.BLACK);
294  }
295  override void _WB_GetBoundBox(inout vector min, inout vector max, IEntitySource src)
296  {
297  GetWorld().GetBoundBox(min, max);
298  }
299 
300  //------------------------------------------------------------------------------------------------
303  /*
304  protected void CreatePreviewImageFile()
305  {
306  string sourceFile = FilePath.ReplaceExtension(FilePath.StripPath(targetPath), m_sImagePlaceholderExt);
307  if (sourceFile.IsEmpty() || m_sImagePlaceholderSource.IsEmpty())
308  return;
309 
310  //--- Read source meta file
311  string placeholderPath = m_ImagePlaceholder.GetPath();
312  string absolutePath;
313  Workbench.GetAbsolutePath(placeholderPath, absolutePath);
314 
315  //--- Create directory
316  string imageDirectoryPath = FilePath.StripFileName(targetPath);
317  if (!config.CreateDirectoryFor(imageDirectoryPath, addonName))
318  return;
319 
320  //--- Copy texture source
321  FileIO.CopyFile(m_sImagePlaceholderPath + m_sImagePlaceholderSource, addonName + FilePath.StripFileName(targetPath) + sourceFile);
322 
323  //--- Register the file
324  Workbench.GetAbsolutePath(addonName + FilePath.StripFileName(targetPath) + sourceFile, absolutePath, false);
325  MetaFile metaContainer = m_ResourceManager.RegisterResourceFile(absolutePath);
326  if (metaContainer)
327  {
328  //--- Update meta file
329  targetPath = metaContainer.GetResourceID();
330  BaseContainerList configurations = metaContainer.GetObjectArray("Configurations");
331  if (configurations)
332  {
333  configurations.Get(0).Set("ColorSpace", "ToSRGB"); //--- Assume PC is the first
334  metaContainer.Save();
335  Print(string.Format("Editable entity preview image ADDED: @\"%1\"", targetPath), LogLevel.DEBUG);
336  return;
337  }
338  }
339  }
340  */
341 #endif
342 };
343 
345 {
346  ResourceName m_Prefab;
347  string m_ImagePath;
349 
350  void SCR_EditorImageGeneratorPrefab(ResourceName prefab, string imagePath, SCR_EditorImagePositionEntity position)
351  {
352  m_Prefab = prefab;
353  m_ImagePath = imagePath;
355  }
356 };
EEditableEntityLabel
EEditableEntityLabel
Definition: EEditableEntityLabel.c:1
m_Position
private vector m_Position
Definition: UnitDisplayComponent.c:17
EntityEditorProps
enum EQueryType EntityEditorProps(category:"GameScripted/Sound", description:"THIS IS THE SCRIPT DESCRIPTION.", color:"0 0 255 255")
Definition: SCR_AmbientSoundsComponent.c:12
SCR_FormatHelper
Definition: SCR_FormatHelper.c:1
SCR_EditorImageGeneratorPrefab
Definition: SCR_EditorImageGeneratorEntity.c:344
GetInstance
SCR_TextsTaskManagerComponentClass ScriptComponentClass GetInstance()
Definition: SCR_TextsTaskManagerComponent.c:50
GetGame
ArmaReforgerScripted GetGame()
Definition: game.c:1424
EOnFrame
override void EOnFrame(IEntity owner, float timeSlice)
Definition: SCR_PlayerProfileManagerComponent.c:199
SCR_EditableEntityUIInfo
Definition: SCR_EditableEntityUIInfo.c:2
desc
UI Textures DeployMenu Briefing conflict_HintBanner_1_UI desc
Definition: SCR_RespawnBriefingComponent.c:17
GenericEntity
SCR_GenericBoxEntityClass GenericEntity
Init
void Init(IEntity entity=null, vector worldPos=vector.Zero, float timestamp=0.0, EAITargetInfoCategory category=0)
Definition: SCR_AITargetInfo.c:27
Attribute
typedef Attribute
Post-process effect of scripted camera.
ETimeFormatParam
ETimeFormatParam
Definition: ETimeFormatParam.c:4
m_fTime
float m_fTime
Definition: SCR_CharacterCommandSwim.c:221
SCR_EditorImageGeneratorEntity
Definition: SCR_EditorImageGeneratorEntity.c:12
SCR_EditorImageGeneratorEntityClass
Definition: SCR_EditorImageGeneratorEntity.c:2
SCR_EditorImagePositionEntity
Definition: SCR_EditorImagePositionEntity.c:12
SCR_Global
Definition: Functions.c:6
m_Prefab
ResourceName m_Prefab
Definition: ForestGeneratorObjects.c:48
SCR_EditableEntityComponentClass
Definition: SCR_EditableEntityComponentClass.c:2
position
vector position
Definition: SCR_DestructibleTreeV2.c:30
category
params category
Definition: SCR_VehicleDamageManagerComponent.c:180