RapyutaSimulationPlugins
RRCoreUtils.h
Go to the documentation of this file.
1 
15 #pragma once
16 
17 
18 
19 // Native
20 
21 #include <string>
22 
23 
24 
25 // UE
26 
27 #if WITH_EDITOR
28 
29 #include "ObjectTools.h"
30 
31 #include "Subsystems/UnrealEditorSubsystem.h"
32 
33 #include "UnrealEd.h"
34 
35 #endif
36 
37 #include "Delegates/Delegate.h"
38 
39 #include "Engine/LatentActionManager.h"
40 
41 #include "Engine/LevelStreaming.h"
42 
43 #include "Engine/TextureLightProfile.h"
44 
45 #include "Engine/World.h"
46 
47 #include "HAL/PlatformProcess.h"
48 
49 #include "IImageWrapper.h"
50 
51 #include "IImageWrapperModule.h"
52 
53 #include "ImageUtils.h"
54 
55 #include "Kismet/BlueprintFunctionLibrary.h"
56 
57 #include "Kismet/GameplayStatics.h"
58 
59 #include "Misc/Guid.h"
60 
61 #include "Misc/MonitoredProcess.h"
62 
63 #include "Stats/Stats.h"
64 
65 #include "UObject/Object.h"
66 
67 #include "UObject/ObjectMacros.h"
68 
69 
70 
71 // RapyutaSimulationPlugins
72 
73 #include "Core/RRActorCommon.h"
74 
75 #include "Core/RRGeneralUtils.h"
76 
77 #include "Core/RRTextureData.h"
78 
79 #include "Core/RRTypeUtils.h"
80 
81 
82 
83 #include "RRCoreUtils.generated.h"
84 
85 
86 
87 class ARRGameState;
88 
89 class URRGameInstance;
90 
92 
93 class ARRBaseActor;
94 
95 class UCameraComponent;
96 
97 
98 
112 class RAPYUTASIMULATIONPLUGINS_API URRCoreUtils : public UBlueprintFunctionLibrary
113 
114 {
115 
116 
117 
118 public:
119 
120  // -------------------------------------------------------------------------------------------------------------
121 
122  // GENERAL UTILS ===============================================================================================
123 
124  //
125 
126  template<class T, std::size_t N>
127 
128  constexpr std::size_t static GetArraySize(const T (&)[N])
129 
130  {
131 
132  return N;
133 
134  }
135 
136 
137 
138  template<bool bInBoolPreprocessor>
139 
140  FORCEINLINE static constexpr const TCHAR* GetBoolPreprocessorText()
141 
142  {
143 
144  if constexpr (bInBoolPreprocessor)
145 
146  {
147 
148  return TEXT("TRUE");
149 
150  }
151 
152  else
153 
154  {
155 
156  return TEXT("FALSE");
157 
158  }
159 
160  }
161 
162 
163 
164  // TYPE-RELATED UTILS --
165 
166  //
167 
168  // STRING UTILS --
169 
170  FORCEINLINE static FString GetSanitizedXMLString(const FString& InXMLString)
171 
172  {
173 
174  FString outXMLString = InXMLString;
175 
176  // Remove linebreaks and tabs
177 
178  outXMLString.TrimStartAndEndInline();
179 
180  outXMLString = outXMLString.Replace(TEXT("\n"), URRActorCommon::SPACE_STR);
181 
182  outXMLString = outXMLString.Replace(TEXT("\r"), EMPTY_STR);
183 
184  outXMLString = outXMLString.Replace(TEXT("\t"), URRActorCommon::SPACE_STR);
185 
186  return outXMLString;
187 
188  }
189 
190 
191 
192  FORCEINLINE static FString StdToFString(const std::string& InStdString)
193 
194  {
195 
196  return FString(InStdString.c_str());
197 
198  }
199 
200 
201 
202  FORCEINLINE static std::string FToStdString(const FString& InUEString)
203 
204  {
205 
206  return std::string(TCHAR_TO_UTF8(*InUEString));
207 
208  }
209 
210 
211 
212  // SIM CONSOLE COMMANDS --
213 
214  static constexpr const TCHAR* CMD_SIM_QUIT = TEXT("quit");
215 
216  static constexpr const TCHAR* CMD_STATS_START = TEXT("stat startfile");
217 
218  static constexpr const TCHAR* CMD_STATS_STOP = TEXT("stat stopfile");
219 
220  static constexpr const TCHAR* CMD_MEMORY_REPORT = TEXT("memreport");
221 
222  static constexpr const TCHAR* CMD_MEMORY_REPORT_FULL = TEXT("memreport -full");
223 
224  static constexpr const TCHAR* CMD_GC_DUMP_POOL_STATS = TEXT("gc.DumpPoolStats");
225 
226  static constexpr const TCHAR* CMD_RHI_GPU_CAPTURE_OPTIONS_ENABLE = TEXT("r.RHISetGPUCaptureOptions 1");
227 
228  static constexpr const TCHAR* CMD_RENDER_DOC_CAPTURE_FRAME = TEXT("renderdoc.CaptureFrame");
229 
230  static constexpr const TCHAR* CMD_SHADOW_MAP_CACHING_TURN_OFF = TEXT("r.Shadow.CacheWholeSceneShadows 0");
231 
232  static constexpr const TCHAR* CMD_AO_USE_HISTORY_DISABLE = TEXT("r.AOUseHistory 0");
233 
234  static constexpr const TCHAR* CMD_OCCLUDED_PRIMITIVES_VISUALIZE = TEXT("r.VisualizeOccludedPrimitives 1");
235 
236  static constexpr const TCHAR* CMD_CUSTOM_DEPTH_STENCIL_ENABLE = TEXT("r.CustomDepth 3");
237 
238  // https://docs.unrealengine.com/4.26/en-US/TestingAndOptimization/PerformanceAndProfiling/ForwardRenderer
239 
240  static constexpr const TCHAR* CMD_FORWARD_SHADING_ENABLE = TEXT("r.ForwardShading 1");
241 
242  static constexpr const TCHAR* CMD_HIGHRES_SCREENSHOT_DELAY = TEXT("r.HighResScreenshotDelay");
243 
244  static constexpr const TCHAR* CMD_AUDIO_MIXER_DISABLE = TEXT("au.IsUsingAudioMixer 0");
245 
246 
247 
248  // SIM FILE EXTENSIONS --
249 
250 
251 
253 
254  static constexpr const TCHAR* SimFileExts[] = {
255 
256  TEXT(""), // ERRFileType::NONE
257 
258  // UE & General
259 
260  TEXT(".uasset"), // ERRFileType::UASSET
261 
262  TEXT(".pak"), // ERRFileType::PAK
263 
264  TEXT(".ini"), // ERRFileType::INI
265 
266  TEXT(".yaml"), // ERRFileType::YAML
267 
268  TEXT(".zip"), // ERRFileType::ZIP
269 
270 
271 
272  // Image
273 
274  TEXT(".jpg"), // ERRFileType::IMAGE_JPG
275 
276  TEXT(".jpg"), // ERRFileType::IMAGE_GRAYSCALE_JPG
277 
278  TEXT(".png"), // ERRFileType::IMAGE_PNG
279 
280  TEXT(".tga"), // ERRFileType::IMAGE_TGA
281 
282  TEXT(".exr"), // ERRFileType::IMAGE_EXR
283 
284  TEXT(".hdr"), // ERRFileType::IMAGE_HDR
285 
286 
287 
288  // Light Profile
289 
290  TEXT(".ies"), // ERRFileType::LIGHT_PROFILE_IES
291 
292 
293 
294  // Meta data
295 
296  TEXT(".json"), // ERRFileType::JSON
297 
298 
299 
300  // 3D Description formats
301 
302  TEXT(".urdf"), // ERRFileType::URDF
303 
304  TEXT(".sdf"), // ERRFileType::SDF
305 
306  TEXT(".world"), // ERRFileType::GAZEBO_WORLD
307 
308  TEXT(".mjcf"), // ERRFileType::MJCF
309 
310 
311 
312  // 3D CAD
313 
314  TEXT(".fbx"), // ERRFileType::CAD_FBX
315 
316  TEXT(".obj"), // ERRFileType::CAD_OBJ
317 
318  TEXT(".stl"), // ERRFileType::CAD_STL
319 
320  TEXT(".dae"), // ERRFileType::CAD_DAE
321 
322  };
323 
324 
325 
338  FORCEINLINE static const TCHAR* GetSimFileExt(const ERRFileType InFileType)
339 
340  {
341 
342  const uint8 fileTypeIdx = static_cast<uint8>(InFileType);
343 
344  verify((fileTypeIdx >= static_cast<uint8>(ERRFileType::NONE)) && (fileTypeIdx < static_cast<uint8>(ERRFileType::TOTAL)));
345 
346  return SimFileExts[fileTypeIdx];
347 
348  }
349 
350  static FString GetFileTypeFilter(const ERRFileType InFileType);
351 
352 
353 
354  FORCEINLINE static ERRFileType GetFileType(const FString& InFilePath)
355 
356  {
357 
358  for (uint8 i = 0; i < static_cast<uint8>(ERRFileType::TOTAL); ++i)
359 
360  {
361 
362  const ERRFileType& fileType = static_cast<ERRFileType>(i);
363 
364  if (InFilePath.EndsWith(URRCoreUtils::GetSimFileExt(fileType)))
365 
366  {
367 
368  return fileType;
369 
370  }
371 
372  }
373 
374  return ERRFileType::NONE;
375 
376  }
377 
378 
379 
380  FORCEINLINE static bool IsFileType(const FString& InFilePath, const TArray<ERRFileType>& InFileTypes)
381 
382  {
383 
384  for (const auto& fileType : InFileTypes)
385 
386  {
387 
388  if (InFilePath.EndsWith(URRCoreUtils::GetSimFileExt(fileType)))
389 
390  {
391 
392  return true;
393 
394  }
395 
396  }
397 
398  return false;
399 
400  }
401 
402 
403 
404 // SIM COMMAND LINE EXECUTION --
405 
406 #define CCMDLINE_ARG_FORMAT (TEXT("%s="))
407 
408  template<typename TCmdlet>
409 
411 
412  {
413 
414  return IsRunningCommandlet() && GetRunningCommandletClass()->IsChildOf<TCmdlet>();
415 
416  }
417 
418 
419 
420  static void ExecuteConsoleCommand(const UObject* InContextObject, const FString& InCommandText)
421 
422  {
423 
424  if (IsRunningCommandlet())
425 
426  {
427 
428 #if WITH_EDITOR
429 
430  GEngine->Exec(URRCoreUtils::GetEditorWorld(), *InCommandText);
431 
432 #endif
433 
434  }
435 
436  else
437 
438  {
439 
440  GetPlayerController<APlayerController>(0, InContextObject)->ConsoleCommand(InCommandText);
441 
442  // OR: GEngine->Exec(World, *InCommandText);
443 
444  }
445 
446  }
447 
448 
449 
450  // T must be primitive type only!
451 
452  template<typename T>
453 
454  static FORCEINLINE constexpr bool GetCommandLineArgumentValue(const TCHAR* InArgName, T& OutArgValue, bool bIsLogged = false)
455 
456  {
457 
458  bool bResult = false;
459 
460  if constexpr (TIsSame<T, bool>::Value)
461 
462  {
463 
464  bResult = FParse::Bool(FCommandLine::Get(), *FString::Printf(CCMDLINE_ARG_FORMAT, InArgName), OutArgValue);
465 
466  }
467 
468  else
469 
470  {
471 
472  bResult = FParse::Value(FCommandLine::Get(), *FString::Printf(CCMDLINE_ARG_FORMAT, InArgName), OutArgValue);
473 
474  }
475 
476 
477 
478  if (!bResult && bIsLogged)
479 
480  {
481 
482  UE_LOG_WITH_INFO(LogTemp, Error, TEXT("Command line argument not found under the name [%s]"), InArgName);
483 
484  }
485 
486  return bResult;
487 
488  }
489 
490 
491 
492  template<typename T>
493 
494  static FORCEINLINE constexpr bool ParseCommandLineParams(const FString& InParams,
495 
496  const TCHAR* InArgName,
497 
498  T& OutArgValue,
499 
500  bool bIsLogged = false)
501 
502  {
503 
504  bool bResult = false;
505 
506  if constexpr (TIsSame<T, bool>::Value)
507 
508  {
509 
510  bResult = FParse::Bool(*InParams, *FString::Printf(CCMDLINE_ARG_FORMAT, InArgName), OutArgValue);
511 
512  }
513 
514  else
515 
516  {
517 
518  bResult = FParse::Value(*InParams, *FString::Printf(CCMDLINE_ARG_FORMAT, InArgName), OutArgValue);
519 
520  }
521 
522 
523 
524  if (!bResult && bIsLogged)
525 
526  {
527 
528  UE_LOG_WITH_INFO(LogTemp, Error, TEXT("[%s] does not contain an argument named [%s]"), *InParams, InArgName);
529 
530  }
531 
532  return bResult;
533 
534  }
535 
536 
537 
538  // SIM WORLDS --
539 
540  static constexpr const TCHAR* PIXEL_STREAMER_PLAYER_NAME = TEXT("pixelstreamer");
541 
542  static UWorld* GetEditorWorld()
543 
544  {
545 
546  UWorld* editorWorld = nullptr;
547 
548 #if WITH_EDITOR
549 
550  if (UUnrealEditorSubsystem* UnrealEditorSubsystem = GEditor->GetEditorSubsystem<UUnrealEditorSubsystem>())
551 
552  {
553 
554  // NOTE: This also returns [GEditor->GetEditorWorldContext().World()]
555 
556  editorWorld = UnrealEditorSubsystem->GetEditorWorld();
557 
558  }
559 
560 #endif
561 
562  return editorWorld;
563 
564  }
565 
566 
567 
568  static bool IsPIE()
569 
570  {
571 
572 #if WITH_EDITOR
573 
574  return GEditor && (GEditor->PlayWorld || GIsPlayInEditorWorld);
575 
576 #else
577 
578  return false;
579 
580 #endif
581 
582  }
583 
584 
585 
586  template<typename T>
587 
588  static T* GetGameMode(const UObject* InContextObject = nullptr)
589 
590  {
591 
592  return Cast<T>(InContextObject->GetWorld()->GetAuthGameMode());
593 
594  }
595 
596 
597 
598  template<typename T>
599 
600  static T* GetGameInstance(const UObject* InContextObject = nullptr)
601 
602  {
603 
604  verify(IsInGameThread());
605 
606  return Cast<T>(UGameplayStatics::GetGameInstance(InContextObject));
607 
608  }
609 
610 
611 
612  template<typename T>
613 
614  static T* GetGameState(const UObject* InContextObject = nullptr)
615 
616  {
617 
618  return Cast<T>(InContextObject->GetWorld()->GetGameState());
619 
620  }
621 
622 
623 
624  template<typename T>
625 
626  static T* GetPlayerController(int8 InSceneInstanceId, const UObject* InContextObject = nullptr)
627 
628  {
629 
630  verify(IsInGameThread());
631 
632  return Cast<T>(UGameplayStatics::GetPlayerControllerFromID(InContextObject, InSceneInstanceId));
633 
634  }
635 
636 
637 
638  template<typename T>
639 
640  static void GetPlayerControllerList(TArray<T>& OutPlayerControllerList, const UObject* InContextObject = nullptr)
641 
642  {
643 
644  if (UWorld* World = GEngine->GetWorldFromContextObject(InContextObject, EGetWorldErrorMode::LogAndReturnNull))
645 
646  {
647 
648  for (FConstPlayerControllerIterator Iterator = World->GetPlayerControllerIterator(); Iterator; ++Iterator)
649 
650  {
651 
652  T* playerController = Cast<T>(Iterator->Get());
653 
654  if (playerController)
655 
656  {
657 
658  OutPlayerControllerList.Add(playerController);
659 
660  }
661 
662  }
663 
664  }
665 
666  }
667 
668 
669 
670  template<typename T>
671 
672  static T* CreatePlayerController(int32 ControllerId, const UObject* InContextObject)
673 
674  {
675 
676  return Cast<T>(UGameplayStatics::CreatePlayer(InContextObject, ControllerId, true));
677 
678  }
679 
680 
681 
682  template<typename T>
683 
684  static void CreatePlayerControllerList(TArray<T>& OutPlayerControllerList, int32 InNumOfPlayers, const UObject* InContextObject)
685 
686  {
687 
688  for (int32 i = 0; i < InNumOfPlayers; i++)
689 
690  {
691 
692  T* newPlayer = Cast<T>(UGameplayStatics::CreatePlayer(InContextObject, i, true));
693 
694  verify(newPlayer);
695 
696  OutPlayerControllerList.Add(newPlayer);
697 
698  }
699 
700  }
701 
702  static bool HasPlayerControllerListInitialized(const UObject* InContextObject, bool bIsLogged = false);
703 
704 
705 
707 
708  static int32 GetMaxSplitscreenPlayers(const UObject* InContextObject);
709 
710 
711 
712  template<typename TRRObject>
713 
714  static bool IsDefaultSimSceneInstance(TRRObject* InSimObject)
715 
716  {
717 
718  return (URRActorCommon::DEFAULT_SCENE_INSTANCE_ID == InSimObject->SceneInstanceId);
719 
720  }
721 
722 
723 
724  static FString GetSimDefaultConfigFileName(const UObject* InContextObject)
725 
726  {
727 
728  return InContextObject->GetDefaultConfigFilename();
729 
730  }
731 
732 
733 
734  static FString GetSimConfigFileName(const UObject* InContextObject)
735 
736  {
737 
738  return InContextObject->GetClass()->GetConfigName();
739 
740  }
741 
742 
743 
744  static bool IsSimProfiling();
745 
746 
747 
748  // GameState & PlayerController should be able to be recognized polymorphically!
749 
750 
751 
768  static bool HasSimInitialized(const UObject* InContextObject, bool bIsLogged = false);
769 
770 
771 
786  static URRSceneInstance* GetSceneInstance(const UObject* InContextObject, int8 InSceneInstanceId);
787 
788 
789 
790  static ARRSceneDirector* GetSceneDirector(const UObject* InContextObject, int8 InSceneInstanceId);
791 
792  static FVector GetSceneInstanceLocation(int8 InSceneInstanceId);
793 
794 
795 
796  static bool HasEnoughDiskSpace(const FString& InPath, uint64 InRequiredMemorySizeInBytes);
797 
798 
799 
800  static bool ShutDownSim(const UObject* InContextObject, uint64 InSimCompletionTimeoutInSecs);
801 
802  static void ExecuteSimQuitCommand(const UObject* InContextObject);
803 
804 
805 
806  static uint32 GetNewGuid()
807 
808  {
809 
810  return GetTypeHash(FGuid::NewGuid());
811 
812  }
813 
814 
815 
834  static ULevelStreamingDynamic* CreateStreamingLevel(const UObject* InContextObject, const FRRStreamingLevelInfo& InLevelInfo)
835 
836  {
837 
838  bool bSucceeded = false;
839 
840  ULevelStreamingDynamic* streamLevel =
841 
842  ULevelStreamingDynamic::LoadLevelInstance(InContextObject->GetWorld(),
843 
844  InLevelInfo.AssetPath,
845 
846  InLevelInfo.TargetTransform.GetTranslation(),
847 
848  InLevelInfo.TargetTransform.Rotator(),
849 
850  /*out*/ bSucceeded);
851 
852  UE_LOG_WITH_INFO(LogTemp, Log, TEXT("%d Streaming level creation from path: %s"), bSucceeded, *InLevelInfo.AssetPath);
853 
854  return streamLevel;
855 
856  }
857 
858 
859 
878  static void StreamLevel(const UObject* InContextObject,
879 
880  const FString& InLevelName,
881 
882  UObject* InTargetObject = nullptr,
883 
884  const FName& InExecuteFunctionName = NAME_None)
885 
886  {
887 
888  static int32 sLatentActionUUID = 0;
889 
890  FLatentActionInfo latentActionInfo;
891 
892  latentActionInfo.CallbackTarget = InTargetObject;
893 
894  latentActionInfo.ExecutionFunction = InExecuteFunctionName;
895 
896  latentActionInfo.UUID = ++sLatentActionUUID;
897 
898  latentActionInfo.Linkage = 0;
899 
900  UGameplayStatics::LoadStreamLevel(InContextObject, *InLevelName, true, true, latentActionInfo);
901 
902  }
903 
904 
905 
918  static void UnstreamLevel(const UObject* InContextObject, const FName& InLevelName)
919 
920  {
921 
922  UGameplayStatics::UnloadStreamLevel(InContextObject, InLevelName, FLatentActionInfo(), true);
923 
924  }
925 
926 
927 
928  static void MoveStreamingLevelBetweenSceneInstances(ULevelStreaming* InStreamingLevel,
929 
930  int8 InStartSceneInstanceId,
931 
932  int8 InTargetSceneInstanceId)
933 
934  {
935 
936  if (InStartSceneInstanceId != InTargetSceneInstanceId)
937 
938  {
939 
940  const FVector startSceneInstanceLoc = GetSceneInstanceLocation(InStartSceneInstanceId);
941 
942  const FVector targetSceneInstanceLoc = GetSceneInstanceLocation(InTargetSceneInstanceId);
943 
944  InStreamingLevel->GetLoadedLevel()->ApplyWorldOffset(targetSceneInstanceLoc - startSceneInstanceLoc, false);
945 
946  }
947 
948  }
949 
950 
951 
952  // -------------------------------------------------------------------------------------------------------------------------
953 
954  // FILE/DIR UTILS --
955 
956  //
957 
958  static bool LoadFullFilePaths(const FString& FolderPath,
959 
960  TArray<FString>& OutFilePaths,
961 
962  const TArray<ERRFileType>& InFileTypes,
963 
964  const bool bInRecursive = true);
965 
966 
967 
968  static bool CreateDirectoryIfNotExisting(const FString& DirPath)
969 
970  {
971 
972  FString dirFullPath = FPaths::IsRelative(DirPath) ? FPaths::ConvertRelativePathToFull(DirPath) : DirPath;
973 
974  if (FPaths::DirectoryExists(dirFullPath))
975 
976  {
977 
978  return true;
979 
980  }
981 
982  else
983 
984  {
985 
986  bool res = FPlatformFileManager::Get().GetPlatformFile().CreateDirectoryTree(*dirFullPath);
987 
988  if (!res)
989 
990  {
991 
992  UE_LOG_WITH_INFO(LogTemp, Error, TEXT("Failed to create dir %s"), *dirFullPath)
993 
994  }
995 
996  return res;
997 
998  }
999 
1000  }
1001 
1002 
1003 
1004  static void VerifyDirPathAbsoluteAndExist(const FString& InDirPath)
1005 
1006  {
1007 
1008  if (false == InDirPath.IsEmpty())
1009 
1010  {
1011 
1012  if (FPaths::IsRelative(InDirPath))
1013 
1014  {
1015 
1016  UE_LOG_WITH_INFO(LogTemp, Fatal, TEXT("[%s] directory path is required to be an absolute path."), *InDirPath);
1017 
1018  }
1019 
1020  else if (false == FPaths::DirectoryExists(InDirPath))
1021 
1022  {
1023 
1024  UE_LOG_WITH_INFO(LogTemp, Fatal, TEXT("[%s] directory does not exist."), *InDirPath);
1025 
1026  }
1027 
1028  }
1029 
1030  // else up to various situations, being empty would be acceptable or not.
1031 
1032  }
1033 
1034 
1035 
1036  // -------------------------------------------------------------------------------------------------------------------------
1037 
1038  // TIMER UTILS --
1039 
1040  //
1041 
1042  // SIM TIME --
1043 
1044  FORCEINLINE static float GetSeconds()
1045 
1046  {
1047 
1048  // `GetWorld()->GetTimeSeconds()` relies on a context object's World and thus is less robust.
1049 
1050  // typedef FUnixTime FPlatformTime, used by:
1051 
1052  // + UEngine::UpdateTimeAndHandleMaxTickRate() to set FApp::CurrentTime
1053 
1054  // + UGameplayStatics::GetAccurateRealTime()
1055 
1056  return FPlatformTime::Seconds();
1057 
1058  }
1059 
1060 
1061 
1062  template<typename T, typename = TEnableIf<TIsFloatingPoint<T>::Value>>
1063 
1064  static void MarkCurrentTime(T& OutTimestamp)
1065 
1066  {
1067 
1068  OutTimestamp = GetSeconds();
1069 
1070  }
1071 
1072 
1073 
1074  template<typename T, typename = TEnableIf<TIsFloatingPoint<T>::Value>>
1075 
1076  static T GetElapsedTimeSecs(const T& InLastTimestamp)
1077 
1078  {
1079 
1080  return GetSeconds() - InLastTimestamp;
1081 
1082  }
1083 
1084 
1085 
1108  static bool WaitUntilThenAct(TFunctionRef<bool()> InCond,
1109 
1110  TFunctionRef<void()> InPassedCondAct,
1111 
1112  float InTimeoutInSec,
1113 
1114  float InIntervalTimeInSec = 0.5f);
1115 
1116 
1117 
1138  static bool CheckWithTimeOut(const TFunctionRef<bool()>& InCondition,
1139 
1140  const TFunctionRef<void()>& InActionUponTimeout,
1141 
1142  float InBeginTimeInSec,
1143 
1144  float InTimeoutInSec);
1145 
1146 
1147 
1148  static void StopRegisteredTimer(UWorld* InWorld, FTimerHandle& InTimerHandle)
1149 
1150  {
1151 
1152  check(IsValid(InWorld));
1153 
1154  // Also invalidate the timer here-in!
1155 
1156  InWorld->GetTimerManager().ClearTimer(InTimerHandle);
1157 
1158  }
1159 
1160 
1161 
1162  template<typename T, typename TDelegate>
1163 
1164  FORCEINLINE static FTimerHandle PlanToExecuteOnNextTick(T* InObj, typename TDelegate::template TMethodPtr<T> InMethod)
1165 
1166  {
1167 
1168  check(IsValid(InObj));
1169 
1170  return InObj->GetWorld()->GetTimerManager().SetTimerForNextTick(InObj, InMethod);
1171 
1172  }
1173 
1174 
1175 
1176  FORCEINLINE static FTimerHandle PlanToExecuteOnNextTick(UWorld* InWorld, const FTimerDelegate& InTimerDelegate)
1177 
1178  {
1179 
1180  check(IsValid(InWorld));
1181 
1182  return InWorld->GetTimerManager().SetTimerForNextTick(InTimerDelegate);
1183 
1184  }
1185 
1186 
1187 
1188  FORCEINLINE static FTimerHandle PlanToExecuteOnNextTick(UWorld* InWorld, TFunction<void()> InCallback)
1189 
1190  {
1191 
1192  check(IsValid(InWorld));
1193 
1194  return InWorld->GetTimerManager().SetTimerForNextTick(MoveTemp(InCallback));
1195 
1196  }
1197 
1198 
1199 
1200  template<typename T>
1201 
1202  FORCEINLINE static void RegisterRepeatedExecution(T* InObj,
1203 
1204  FTimerHandle& InTimerHandle,
1205 
1206  typename FTimerDelegate::template TMethodPtr<T>::FMethodPtr InMethod,
1207 
1208  float InRate = 0.5f)
1209 
1210  {
1211 
1212  check(IsValid(InObj));
1213 
1214  InObj->GetWorld()->GetTimerManager().SetTimer(InTimerHandle, InObj, InMethod, InRate, true);
1215 
1216  }
1217 
1218 
1219 
1220  template<typename T>
1221 
1222  FORCEINLINE static void RegisterRepeatedExecution(T* InObj,
1223 
1224  FTimerHandle& InTimerHandle,
1225 
1226  TFunction<void()> Callback,
1227 
1228  float InRate = 0.5f)
1229 
1230  {
1231 
1232  check(IsValid(InObj));
1233 
1234  InObj->GetWorld()->GetTimerManager().SetTimer(InTimerHandle, MoveTemp(Callback), InRate, true);
1235 
1236  }
1237 
1238 
1239 
1240  static void StopRegisteredExecution(UWorld* InWorld, FTimerHandle& InTimerHandle)
1241 
1242  {
1243 
1244  check(IsValid(InWorld));
1245 
1246  // Also invalidate it here-in!
1247 
1248  InWorld->GetTimerManager().ClearTimer(InTimerHandle);
1249 
1250  }
1251 
1252 
1253 
1254  // -------------------------------------------------------------------------------------------------------------------------
1255 
1256  // PROCESS UTILS --
1257 
1258  //
1259 
1260  static int32 RunMonitoredProcess(FMonitoredProcess* InProcess,
1261 
1262  const float InTimeOutSecs,
1263 
1264  const FString& InProcessName = EMPTY_STR)
1265 
1266  {
1267 
1268  // Launch [InProcess]
1269 
1270  if (false == InProcess->Launch())
1271 
1272  {
1273 
1274  UE_LOG_WITH_INFO_SHORT(LogTemp, Error, TEXT("[%s] Process failed being launched"), *InProcessName);
1275 
1276  return -1;
1277 
1278  }
1279 
1280 
1281 
1282  // Wait for it to finish with [InTimeOutSecs]
1283 
1284  const float lastMarkedTime = URRCoreUtils::GetSeconds();
1285 
1286  bool bCancelled = false;
1287 
1288  while (InProcess->Update())
1289 
1290  {
1291 
1292  // Already slept in [Update()]
1293 
1294  if ((!bCancelled) && (URRCoreUtils::GetElapsedTimeSecs(lastMarkedTime) > InTimeOutSecs))
1295 
1296  {
1297 
1298  bCancelled = true;
1299 
1300  UE_LOG_WITH_INFO(LogTemp,
1301 
1302  Error,
1303 
1304  TEXT("[%s] Process is about to be terminated after timeout [%f secs]"),
1305 
1306  *InProcessName,
1307 
1308  InTimeOutSecs);
1309 
1310 
1311 
1312  // NOTE: This would trigger process cancelling, which should be waited for completion before this while loop exits
1313 
1314  InProcess->Cancel();
1315 
1316  }
1317 
1318  }
1319 
1320  return InProcess->GetReturnCode();
1321 
1322  }
1323 
1324 
1325 
1326  // -------------------------------------------------------------------------------------------------------------------------
1327 
1328  // IMAGE UTILS --
1329 
1330  //
1331 
1332  // SIM IMAGE WRAPPERS --
1333 
1334  static constexpr const TCHAR* CIMAGE_WRAPPER_MODULE_NAME = TEXT("ImageWrapper");
1335 
1336  static IImageWrapperModule* SImageWrapperModule;
1337 
1338  static TMap<ERRFileType, TSharedPtr<IImageWrapper>> SImageWrappers;
1339 
1340  static void LoadImageWrapperModule();
1341 
1342 
1343 
1358  static UTexture2D* LoadImageToTexture(const FString& InFullFilePath,
1359 
1360  const FString& InTextureName,
1361 
1362  const bool bInSaveToAsset = false);
1363 
1364 
1365 
1366  static bool LoadImagesFromFolder(const FString& InImageFolderPath,
1367 
1368  const TArray<ERRFileType>& InImageFileTypes,
1369 
1370  TArray<UTexture*>& OutImageTextureList,
1371 
1372  bool bIsLogged = false);
1373 
1374 
1375 
1377 
1378  static UTextureLightProfile* LoadIESProfile(const FString& InFullFilePath, const FString& InLightProfileName);
1379 
1380  static bool LoadIESProfilesFromFolder(const FString& InFolderPath,
1381 
1382  TArray<UTextureLightProfile*>& OutLightProfileList,
1383 
1384  bool bIsLogged = false);
1385 
1386 
1387 
1388  static TFunction<void(uint8*, const FUpdateTextureRegion2D*)> CleanupLightProfileData;
1389 
1390 
1391 
1392  static bool IsValidBitDepth(int32 InBitDepth)
1393 
1394  {
1395 
1396  return (URRActorCommon::IMAGE_BIT_DEPTH_INT8 == InBitDepth) || (URRActorCommon::IMAGE_BIT_DEPTH_FLOAT16 == InBitDepth) ||
1397 
1399 
1400  }
1401 
1402 
1403 
1404  template<int8 InBitDepth>
1405 
1406  FORCEINLINE static void GetCompressedImageData(const ERRFileType InImageFileType,
1407 
1408  const FRRColorArray& InImageData,
1409 
1410  const FIntPoint& ImageSize,
1411 
1412  const int8 BitDepth, // normally 8
1413 
1414  const ERGBFormat RGBFormat,
1415 
1416  TArray64<uint8>& OutCompressedData)
1417 
1418  {
1419 
1420  TSharedPtr<IImageWrapper> imageWrapper = URRCoreUtils::SImageWrappers[InImageFileType];
1421 
1422  verify(imageWrapper.IsValid());
1423 
1424  const auto& bitmap = InImageData.GetImageData<InBitDepth>();
1425 
1426 
1427 
1428  if (ERGBFormat::Gray == RGBFormat)
1429 
1430  {
1431 
1432  // Ref :FLandscapeWeightmapFileFormat_Png::Export
1433 
1434  verify(URRActorCommon::IMAGE_BIT_DEPTH_INT8 == InBitDepth);
1435 
1436  TArray<uint8> grayBitmap;
1437 
1438  for (const auto& color : bitmap)
1439 
1440  {
1441 
1442  grayBitmap.Add(color.R);
1443 
1444  }
1445 
1446  imageWrapper->SetRaw(grayBitmap.GetData(),
1447 
1448  grayBitmap.Num(),
1449 
1450  ImageSize.X,
1451 
1452  ImageSize.Y,
1453 
1454  ERGBFormat::Gray,
1455 
1457 
1458  }
1459 
1460  else
1461 
1462  {
1463 
1464  imageWrapper->SetRaw(
1465 
1466  bitmap.GetData(), bitmap.Num() * bitmap.GetTypeSize(), ImageSize.X, ImageSize.Y, RGBFormat, BitDepth);
1467 
1468  }
1469 
1470 
1471 
1472  // Get compressed data because uncompressed is the same fidelity, but much larger
1473 
1474  // EImageCompressionQuality::Default will make the Quality as 85, which is not optimal
1475 
1476  // Besides, this Quality value only matters to JPG, PNG compression is always lossless
1477 
1478  // Please refer to FJpegImageWrapper, FPngImageWrapper for details
1479 
1480  OutCompressedData = imageWrapper->GetCompressed(
1481 
1482  (ERRFileType::IMAGE_JPG == InImageFileType) ? 100 : static_cast<int32>(EImageCompressionQuality::Default));
1483 
1484  }
1485 
1486 
1487 
1488  // -------------------------------------------------------------------------------------------------------------------------
1489 
1490  // CAMERA UTILS --
1491 
1492  //
1493 
1494  // -------------------------------------------------------------------------------------------------------------------------
1495 
1496  // GRAPHICS UTILS --
1497 
1498  //
1499 
1500 #if WITH_EDITOR
1501 
1520  static bool RenderThumbnail(UObject* InObject,
1521 
1522  uint32 InImageWidth,
1523 
1524  uint32 InImageHeight,
1525 
1526  const ThumbnailTools::EThumbnailTextureFlushMode::Type InFlushMode,
1527 
1528  FObjectThumbnail* OutThumbnail);
1529 
1530 #endif
1531 
1546  static bool GenerateThumbnail(UObject* InObject, uint32 InImageWidth, uint32 InImageHeight, const FString& InSaveImagePath);
1547 
1548 
1549 
1550  FORCEINLINE static bool ScreenMsg(const FColor& InColor, const FString& InMessage, float InTimeToDisplay = 50000.f)
1551 
1552  {
1553 
1554  if (GEngine)
1555 
1556  {
1557 
1558  GEngine->AddOnScreenDebugMessage(-1, InTimeToDisplay, InColor, *InMessage);
1559 
1560  return true;
1561 
1562  }
1563 
1564  return false;
1565 
1566  }
1567 
1568 
1569 
1582  FORCEINLINE static void PrintMessage(const FString& InMessage, bool bInError = false, float InTimeOnScreen = 100.f)
1583 
1584  {
1585 
1586  if (bInError)
1587 
1588  {
1589 
1590  UE_LOG(LogTemp, Error, TEXT("%s"), *InMessage);
1591 
1592  }
1593 
1594  else
1595 
1596  {
1597 
1598  UE_LOG(LogTemp, Log, TEXT("%s"), *InMessage);
1599 
1600  }
1601 
1602  ScreenMsg(bInError ? FColor::Red : FColor::Yellow, InMessage, InTimeOnScreen);
1603 
1604 #if RAPYUTA_SIM_DEBUG
1605 
1606  FPlatformMisc::MessageBoxExt(EAppMsgType::Ok, *InMessage, bInError ? TEXT("Error") : TEXT("Info"));
1607 
1608 #endif
1609 
1610  }
1611 
1612 };
1613 
URRCoreUtils::MarkCurrentTime
static void MarkCurrentTime(T &OutTimestamp)
Definition: RRCoreUtils.h:1064
ERRFileType::NONE
@ NONE
URRCoreUtils::PrintMessage
static FORCEINLINE void PrintMessage(const FString &InMessage, bool bInError=false, float InTimeOnScreen=100.f)
Print message.
Definition: RRCoreUtils.h:1582
URRActorCommon::IMAGE_BIT_DEPTH_FLOAT16
static constexpr int8 IMAGE_BIT_DEPTH_FLOAT16
Definition: RRActorCommon.h:1211
FRRColorArray::GetImageData
const TArray< FRRColor< InBitDepth > > & GetImageData() const
Definition: RRActorCommon.h:725
FRRColorArray
Definition: RRActorCommon.h:693
URRCoreUtils::FToStdString
static FORCEINLINE std::string FToStdString(const FString &InUEString)
Definition: RRCoreUtils.h:202
URRSceneInstance
Scene Instance, Eg: ARRSceneDirector, a scene unit among many residing in the same level.
Definition: RRActorCommon.h:1490
URRCoreUtils::GetCommandLineArgumentValue
static constexpr FORCEINLINE bool GetCommandLineArgumentValue(const TCHAR *InArgName, T &OutArgValue, bool bIsLogged=false)
Definition: RRCoreUtils.h:454
EMPTY_STR
#define EMPTY_STR
Definition: RRGeneralUtils.h:43
URRCoreUtils::GetBoolPreprocessorText
static constexpr const FORCEINLINE TCHAR * GetBoolPreprocessorText()
Definition: RRCoreUtils.h:140
URRCoreUtils::PlanToExecuteOnNextTick
static FORCEINLINE FTimerHandle PlanToExecuteOnNextTick(UWorld *InWorld, TFunction< void()> InCallback)
Definition: RRCoreUtils.h:1188
URRCoreUtils::IsFileType
static FORCEINLINE bool IsFileType(const FString &InFilePath, const TArray< ERRFileType > &InFileTypes)
Definition: RRCoreUtils.h:380
URRCoreUtils::SImageWrapperModule
static IImageWrapperModule * SImageWrapperModule
Definition: RRCoreUtils.h:1336
RRTypeUtils.h
UE type related utils.
URRCoreUtils::PlanToExecuteOnNextTick
static FORCEINLINE FTimerHandle PlanToExecuteOnNextTick(UWorld *InWorld, const FTimerDelegate &InTimerDelegate)
Definition: RRCoreUtils.h:1176
URRActorCommon::DEFAULT_SCENE_INSTANCE_ID
static constexpr int8 DEFAULT_SCENE_INSTANCE_ID
Definition: RRActorCommon.h:1149
FRRLightProfileData
Definition: RRTextureData.h:62
URRCoreUtils::IsRunningSimCommandlet
static bool IsRunningSimCommandlet()
Definition: RRCoreUtils.h:410
URRCoreUtils
Core utils.
Definition: RRCoreUtils.h:112
URRCoreUtils::GetSeconds
static FORCEINLINE float GetSeconds()
Definition: RRCoreUtils.h:1044
URRGameInstance
This is a globally accessible instanced UObject that can store run-time data to be commonly accessed ...
Definition: RRGameInstance.h:54
ARRBaseActor
Base actor class for all Rapyuta Sim actors:
Definition: RRBaseActor.h:70
ARRGameState
Game state which handles multiple URRSceneInstance which spit game in scenes for data gen,...
Definition: RRGameState.h:64
URRActorCommon::IMAGE_BIT_DEPTH_FLOAT32
static constexpr int8 IMAGE_BIT_DEPTH_FLOAT32
Definition: RRActorCommon.h:1213
FRRStreamingLevelInfo
Definition: RRActorCommon.h:98
URRCoreUtils::IsValidBitDepth
static bool IsValidBitDepth(int32 InBitDepth)
Definition: RRCoreUtils.h:1392
URRCoreUtils::GetEditorWorld
static UWorld * GetEditorWorld()
Definition: RRCoreUtils.h:542
URRCoreUtils::CreatePlayerController
static T * CreatePlayerController(int32 ControllerId, const UObject *InContextObject)
Definition: RRCoreUtils.h:672
URRCoreUtils::GetArraySize
constexpr static std::size_t GetArraySize(const T(&)[N])
Definition: RRCoreUtils.h:128
URRCoreUtils::RegisterRepeatedExecution
static FORCEINLINE void RegisterRepeatedExecution(T *InObj, FTimerHandle &InTimerHandle, typename FTimerDelegate::template TMethodPtr< T >::FMethodPtr InMethod, float InRate=0.5f)
Definition: RRCoreUtils.h:1202
URRCoreUtils::StreamLevel
static void StreamLevel(const UObject *InContextObject, const FString &InLevelName, UObject *InTargetObject=nullptr, const FName &InExecuteFunctionName=NAME_None)
LoadStreamLevel.
Definition: RRCoreUtils.h:878
URRCoreUtils::PlanToExecuteOnNextTick
static FORCEINLINE FTimerHandle PlanToExecuteOnNextTick(T *InObj, typename TDelegate::template TMethodPtr< T > InMethod)
Definition: RRCoreUtils.h:1164
URRCoreUtils::CreateDirectoryIfNotExisting
static bool CreateDirectoryIfNotExisting(const FString &DirPath)
Definition: RRCoreUtils.h:968
URRCoreUtils::RunMonitoredProcess
static int32 RunMonitoredProcess(FMonitoredProcess *InProcess, const float InTimeOutSecs, const FString &InProcessName=EMPTY_STR)
Definition: RRCoreUtils.h:1260
URRCoreUtils::GetElapsedTimeSecs
static T GetElapsedTimeSecs(const T &InLastTimestamp)
Definition: RRCoreUtils.h:1076
URRCoreUtils::IsPIE
static bool IsPIE()
Definition: RRCoreUtils.h:568
URRCoreUtils::UnstreamLevel
static void UnstreamLevel(const UObject *InContextObject, const FName &InLevelName)
UnloadStreamLevel.
Definition: RRCoreUtils.h:918
URRCoreUtils::CleanupLightProfileData
static TFunction< void(uint8 *, const FUpdateTextureRegion2D *)> CleanupLightProfileData
Definition: RRCoreUtils.h:1388
ERRFileType::IMAGE_JPG
@ IMAGE_JPG
URRCoreUtils::SLightProfileData
static FRRLightProfileData SLightProfileData
Definition: RRCoreUtils.h:1376
URRCoreUtils::GetFileType
static FORCEINLINE ERRFileType GetFileType(const FString &InFilePath)
Definition: RRCoreUtils.h:354
URRCoreUtils::CreateStreamingLevel
static ULevelStreamingDynamic * CreateStreamingLevel(const UObject *InContextObject, const FRRStreamingLevelInfo &InLevelInfo)
Create a Streaming Level object.
Definition: RRCoreUtils.h:834
ERRFileType::TOTAL
@ TOTAL
URRCoreUtils::StdToFString
static FORCEINLINE FString StdToFString(const std::string &InStdString)
Definition: RRCoreUtils.h:192
URRCoreUtils::GetNewGuid
static uint32 GetNewGuid()
Definition: RRCoreUtils.h:806
URRCoreUtils::ExecuteConsoleCommand
static void ExecuteConsoleCommand(const UObject *InContextObject, const FString &InCommandText)
Definition: RRCoreUtils.h:420
URRCoreUtils::GetGameMode
static T * GetGameMode(const UObject *InContextObject=nullptr)
Definition: RRCoreUtils.h:588
URRCoreUtils::MoveStreamingLevelBetweenSceneInstances
static void MoveStreamingLevelBetweenSceneInstances(ULevelStreaming *InStreamingLevel, int8 InStartSceneInstanceId, int8 InTargetSceneInstanceId)
Definition: RRCoreUtils.h:928
URRActorCommon::SPACE_STR
static constexpr const TCHAR * SPACE_STR
Definition: RRActorCommon.h:1185
URRActorCommon::IMAGE_BIT_DEPTH_INT8
static constexpr int8 IMAGE_BIT_DEPTH_INT8
Definition: RRActorCommon.h:1209
URRCoreUtils::CreatePlayerControllerList
static void CreatePlayerControllerList(TArray< T > &OutPlayerControllerList, int32 InNumOfPlayers, const UObject *InContextObject)
Definition: RRCoreUtils.h:684
URRCoreUtils::GetCompressedImageData
static FORCEINLINE void GetCompressedImageData(const ERRFileType InImageFileType, const FRRColorArray &InImageData, const FIntPoint &ImageSize, const int8 BitDepth, const ERGBFormat RGBFormat, TArray64< uint8 > &OutCompressedData)
Definition: RRCoreUtils.h:1406
URRCoreUtils::ParseCommandLineParams
static constexpr FORCEINLINE bool ParseCommandLineParams(const FString &InParams, const TCHAR *InArgName, T &OutArgValue, bool bIsLogged=false)
Definition: RRCoreUtils.h:494
URRStaticMeshComponent
Component of ARRMeshActor. UStaticMeshComponent with utils.
Definition: RRStaticMeshComponent.h:62
URRCoreUtils::GetSimDefaultConfigFileName
static FString GetSimDefaultConfigFileName(const UObject *InContextObject)
Definition: RRCoreUtils.h:724
URRCoreUtils::ScreenMsg
static FORCEINLINE bool ScreenMsg(const FColor &InColor, const FString &InMessage, float InTimeToDisplay=50000.f)
Definition: RRCoreUtils.h:1550
URRCoreUtils::GetGameInstance
static T * GetGameInstance(const UObject *InContextObject=nullptr)
Definition: RRCoreUtils.h:600
URRCoreUtils::GetGameState
static T * GetGameState(const UObject *InContextObject=nullptr)
Definition: RRCoreUtils.h:614
URRCoreUtils::RegisterRepeatedExecution
static FORCEINLINE void RegisterRepeatedExecution(T *InObj, FTimerHandle &InTimerHandle, TFunction< void()> Callback, float InRate=0.5f)
Definition: RRCoreUtils.h:1222
CCMDLINE_ARG_FORMAT
#define CCMDLINE_ARG_FORMAT
Definition: RRCoreUtils.h:406
RRActorCommon.h
Asset utils.
URRCoreUtils::GetPlayerController
static T * GetPlayerController(int8 InSceneInstanceId, const UObject *InContextObject=nullptr)
Definition: RRCoreUtils.h:626
RRGeneralUtils.h
General utils.
URRCoreUtils::StopRegisteredTimer
static void StopRegisteredTimer(UWorld *InWorld, FTimerHandle &InTimerHandle)
Definition: RRCoreUtils.h:1148
URRCoreUtils::GetSanitizedXMLString
static FORCEINLINE FString GetSanitizedXMLString(const FString &InXMLString)
Definition: RRCoreUtils.h:170
FRRStreamingLevelInfo::TargetTransform
FTransform TargetTransform
Definition: RRActorCommon.h:118
URRCoreUtils::SImageWrappers
static TMap< ERRFileType, TSharedPtr< IImageWrapper > > SImageWrappers
Definition: RRCoreUtils.h:1338
URRCoreUtils::GetPlayerControllerList
static void GetPlayerControllerList(TArray< T > &OutPlayerControllerList, const UObject *InContextObject=nullptr)
Definition: RRCoreUtils.h:640
ERRFileType
ERRFileType
File types.
Definition: RRObjectCommon.h:52
URRCoreUtils::GetSimFileExt
static const FORCEINLINE TCHAR * GetSimFileExt(const ERRFileType InFileType)
Return the file extension for the given file type from SimFileExts.
Definition: RRCoreUtils.h:338
URRCoreUtils::StopRegisteredExecution
static void StopRegisteredExecution(UWorld *InWorld, FTimerHandle &InTimerHandle)
Definition: RRCoreUtils.h:1240
URRCoreUtils::VerifyDirPathAbsoluteAndExist
static void VerifyDirPathAbsoluteAndExist(const FString &InDirPath)
Definition: RRCoreUtils.h:1004
URRCoreUtils::IsDefaultSimSceneInstance
static bool IsDefaultSimSceneInstance(TRRObject *InSimObject)
Definition: RRCoreUtils.h:714
RRTextureData.h
ARRSceneDirector
Execute Init/Run/Continue Sim type-specific operations (Data synthesizer/collection or Robot operatio...
Definition: RRSceneDirector.h:92
URRCoreUtils::GetSimConfigFileName
static FString GetSimConfigFileName(const UObject *InContextObject)
Definition: RRCoreUtils.h:734
FRRStreamingLevelInfo::AssetPath
FString AssetPath
Definition: RRActorCommon.h:109