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.")]
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!")]
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 = {};
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;
40 static SCR_EditorImageGeneratorEntity GetInstance()
42 return SCR_EditorImageGeneratorEntity.Cast(
GetGame().FindEntity(
"SCR_EditorImageGeneratorEntity"));
46 SCR_EditorImagePositionEntity FindSuitablePosition(array<EEditableEntityLabel> labels)
48 SCR_EditorImagePositionEntity
position;
49 for (
int i = m_aPositions.Count() - 1; i >= 0; i--)
59 protected bool IsPositionSelected(SCR_EditorImagePositionEntity
position)
61 if (s_aSelectedPositions.IsEmpty())
64 for (
int i = 0, count = s_aSelectedPositions.Count(); i < count; i++)
66 if (vector.DistanceSq(
position.GetOrigin(), s_aSelectedPositions[i]) < 1)
73 void AddPosition(SCR_EditorImagePositionEntity
position)
79 static void AddSelectedPosition(SCR_EditorImagePositionEntity
position)
81 s_aSelectedPositions.Insert(
position.GetOrigin());
90 protected void AddSelectedPrefab(ResourceName prefab,
string filePath)
93 FilePath.StripExtension(prefab, ext);
97 Resource res = Resource.Load(prefab);
98 if (!res || !res.IsValid())
101 IEntityComponentSource editableEntitySource = SCR_EditableEntityComponentClass.GetEditableEntitySource(res);
102 if (!editableEntitySource)
105 SCR_EditableEntityUIInfo info = SCR_EditableEntityComponentClass.GetInfo(editableEntitySource);
108 Print(
string.Format(
"Prefab @\"%1\" does not have UI info defined in SCR_EditableEntityComponent!", prefab.GetPath()),
LogLevel.WARNING);
112 ResourceName imagePath = info.
GetImage();
113 if (imagePath.IsEmpty())
115 Print(
string.Format(
"Prefab @\"%1\" does not have image path defined in UI info of SCR_EditableEntityComponent!", prefab.GetPath()),
LogLevel.WARNING);
119 array<EEditableEntityLabel> labels = {};
121 SCR_EditorImagePositionEntity
position = FindSuitablePosition(labels);
124 if (s_aSelectedPositions.IsEmpty())
134 Print(
string.Format(
"No suitable position found for @\"%1\" with labels %2!", prefab, labelsLine),
LogLevel.WARNING);
139 imagePath = FilePath.StripExtension(imagePath.GetPath());
140 m_aSelectedPrefabs.Insert(
new SCR_EditorImageGeneratorPrefab(prefab, imagePath,
position));
144 protected void RequestClose()
150 protected bool Init()
152 if (m_iInit <= 1 && !SCR_Global.IsEditMode(
this))
159 float screenW =
GetGame().GetWorkspace().GetWidth();
160 float screenH =
GetGame().GetWorkspace().GetHeight();
164 GetGame().GetCallqueue().CallLater(RequestClose,
false, 1);
169 WorldEditor worldEditor = Workbench.GetModule(WorldEditor);
170 worldEditor.GetResourceBrowserSelection(AddSelectedPrefab,
true);
171 if (m_aSelectedPrefabs.IsEmpty())
174 GetGame().GetCallqueue().CallLater(RequestClose,
false, 1);
176 m_iSelectedPrefabsCount = m_aSelectedPrefabs.Count();
182 if (s_aSelectedPositions.IsEmpty())
183 Print(
string.Format(
"Initiating image generation for %1 prefab(s).", m_iSelectedPrefabsCount),
LogLevel.DEBUG);
185 Print(
string.Format(
"Initiating image generation for %1 prefab(s) on %2 pre-selected position(s).", m_iSelectedPrefabsCount, s_aSelectedPositions.Count()),
LogLevel.DEBUG);
199 if (m_fTimeNext != -1 || !m_CurrentPrefab)
201 canContinue =
m_fTime > m_fTimeNext;
212 if (m_CurrentPrefab && !m_bIsScreenshotMade)
214 m_bIsScreenshotMade =
true;
217 string addonName = SCR_AddonTool.GetResourceLastAddon(m_CurrentPrefab.m_Prefab);
218 addonName = SCR_AddonTool.ToFileSystem(addonName);
219 System.MakeScreenshot(addonName + m_CurrentPrefab.m_ImagePath);
220 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);
225 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);
231 if (m_iPrefabIndex >= m_iSelectedPrefabsCount)
233 GetGame().GetCallqueue().CallLater(RequestClose,
false, 1);
239 m_CurrentPrefab.m_Position.DeactivatePosition();
242 m_bIsScreenshotMade =
false;
243 SCR_EditorImageGeneratorPrefab currentPrefab = m_aSelectedPrefabs[m_iPrefabIndex];
244 if (currentPrefab.m_Position.ActivatePosition(currentPrefab.m_Prefab))
246 m_CurrentPrefab = currentPrefab;
251 m_fTimeNext =
m_fTime + currentPrefab.m_Position.GetDelay();
258 m_fTimeRemaining = 0;
259 for (
int i = m_iPrefabIndex, count = m_aSelectedPrefabs.Count(); i < count; i++)
261 m_fTimeRemaining += m_aSelectedPrefabs[i].m_Position.GetDelay();
266 DbgUI.Begin(
"SCR_EditorImageGeneratorEntity");
269 DbgUI.Text(
string.Format(
"%1\n\n", m_CurrentPrefab.m_Prefab.GetPath()));
270 DbgUI.Text(
string.Format(
"Progress: %1 of %2", m_iPrefabIndex, m_iSelectedPrefabsCount));
272 if (m_fTimeNext == -1)
273 DbgUI.Text(
"Press 'Space' to take screenshot and continue to next prefab\n\n");
275 DbgUI.Text(
string.Format(
"Estimated remaining time: %1", SCR_FormatHelper.GetTimeFormatting(m_fTimeRemaining,
ETimeFormatParam.DAYS |
ETimeFormatParam.HOURS)));
279 DbgUI.Text(
"Initializing...");
284 m_fTimeRemaining -= timeSlice;
288 void SCR_EditorImageGeneratorEntity(IEntitySource src,
IEntity parent)
290 SetName(
"SCR_EditorImageGeneratorEntity");
293 if (SCR_Global.IsEditMode(
this))
294 s_aSelectedPositions.Clear();
300 return EEntityFrameUpdateSpecs.CALL_ALWAYS;
307 if (!api.IsEntitySelected(api.EntityToSource(
this)))
310 int screenW = api.GetScreenWidth();
311 int screenH = api.GetScreenHeight();
313 string textCurrent =
string.Format(
"Current resolution: %1x%2", screenW, screenH);
316 int color = Color.RED;
320 color = Color.ORANGE;
323 DebugTextScreenSpace.Create(
GetWorld(), textTarget,
DebugTextFlags.ONCE, 0, 18, 18, Color.WHITE, Color.BLACK);
327 override void _WB_GetBoundBox(inout vector min, inout vector max, IEntitySource src)
336 protected void CreatePreviewImageFile()
338 string sourceFile = FilePath.ReplaceExtension(FilePath.StripPath(targetPath), m_sImagePlaceholderExt);
339 if (sourceFile.IsEmpty() || m_sImagePlaceholderSource.IsEmpty())
342 //--- Read source meta file
343 string placeholderPath = m_ImagePlaceholder.GetPath();
345 Workbench.GetAbsolutePath(placeholderPath, absolutePath);
347 //--- Create directory
348 string imageDirectoryPath = FilePath.StripFileName(targetPath);
349 if (!config.CreateDirectoryFor(imageDirectoryPath, addonName))
352 //--- Copy texture source
353 FileIO.CopyFile(m_sImagePlaceholderPath + m_sImagePlaceholderSource, addonName + FilePath.StripFileName(targetPath) + sourceFile);
355 //--- Register the file
356 Workbench.GetAbsolutePath(addonName + FilePath.StripFileName(targetPath) + sourceFile, absolutePath, false);
357 MetaFile metaContainer = m_ResourceManager.RegisterResourceFile(absolutePath);
360 //--- Update meta file
361 targetPath = metaContainer.GetResourceID();
362 BaseContainerList configurations = metaContainer.GetObjectArray("Configurations");
365 configurations.Get(0).Set("ColorSpace", "ToSRGB"); //--- Assume PC is the first
366 metaContainer.Save();
367 Print(string.Format("Editable entity preview image ADDED: @\"%1\"", targetPath), LogLevel.DEBUG);