RapyutaSimulationPlugins
RRGameSingleton.h
Go to the documentation of this file.
1 
15 #pragma once
16 
17 
18 
19 // UE
20 
21 #include "CoreMinimal.h"
22 
23 #include "Engine/AssetManager.h"
24 
25 #include "Engine/SkeletalMesh.h"
26 
27 #include "Engine/StaticMesh.h"
28 
29 #include "Engine/StreamableManager.h"
30 
31 #include "Materials/Material.h"
32 
33 #include "PhysicalMaterials/PhysicalMaterial.h"
34 
35 #include "PhysicsEngine/BodySetup.h"
36 
37 #include "Templates/UniquePtr.h"
38 
39 
40 
41 // RapyutaSimulationPlugins
42 
43 #include "Core/RRActorCommon.h"
44 
45 #include "Core/RRAssetUtils.h"
46 
47 #include "Core/RRGeneralUtils.h"
48 
49 #include "Core/RRObjectCommon.h"
50 
51 #include "Core/RRTypeUtils.h"
52 
54 
55 
56 
57 #include "RRGameSingleton.generated.h"
58 
59 
60 
61 class URRPakLoader;
62 
63 
64 
65 template<const ERRResourceDataType InDataType>
66 
67 using URRAssetObject = typename TChooseClass<
68 
70 
71  UStaticMesh,
72 
73  typename TChooseClass<
74 
76 
77  USkeletalMesh,
78 
79  typename TChooseClass<
80 
81  (ERRResourceDataType::UE_SKELETON == InDataType),
82 
83  USkeleton,
84 
85  typename TChooseClass<
86 
88 
89  UPhysicsAsset,
90 
91  typename TChooseClass<
92 
93  (ERRResourceDataType::UE_MATERIAL == InDataType),
94 
95  UMaterialInterface,
96 
97  typename TChooseClass<
98 
100 
101  UPhysicalMaterial,
102 
103  typename TChooseClass<
104 
105  (ERRResourceDataType::UE_TEXTURE == InDataType),
106 
107  UTexture,
108 
109  typename TChooseClass<
110 
111  (ERRResourceDataType::UE_DATA_TABLE == InDataType),
112 
113  UDataTable,
114 
115  typename TChooseClass<(ERRResourceDataType::UE_BODY_SETUP == InDataType), UBodySetup, UObject>::
116 
117  Result>::Result>::Result>::Result>::Result>::Result>::Result>::Result>::Result;
118 
119 
120 
144 class RAPYUTASIMULATIONPLUGINS_API URRGameSingleton : public UObject
145 
146 {
147 
148 protected:
149 
151 
152 
153 
154 public:
155 
156  static URRGameSingleton* Get();
157 
158  virtual ~URRGameSingleton();
159 
160 
161 
162  virtual void PrintSimConfig() const;
163 
164 
165 
166  // SIM GLOBAL PROPERTIES --
167 
168  //
169 
170 
175  bool BSIM_PROFILING = false;
176 
177 
178 
179  // SIM RESOURCES ==
180 
181  //
182 
197  bool InitializeResources(bool bInRequestResourceLoading = false);
198 
199 
200 
209  void FinalizeResources();
210 
211 
212 
213  // PAKS --
214 
215 
220  FString FOLDER_PATH_ASSET_PAKS = TEXT("Paks");
221 
222 
227  TObjectPtr<URRPakLoader> PakLoader = nullptr;
228 
230 
231 
236  bool bPakLoaderInitialized = false;
237 
250  bool CollateEntityAssetsInfoFromPAK(const TArray<FString>& InEntityModelNameList, bool bInForceReload = false);
251 
252 
253 
254  // ASSETS --
255 
257 
258  static TMap<ERRResourceDataType, TArray<const TCHAR*>> SASSET_OWNING_MODULE_NAMES;
259 
260 
261 
263 
265 
266  static constexpr const TCHAR* ASSETS_ROOT_PATH = TEXT("/");
267 
268  static constexpr const TCHAR* ASSETS_PROJECT_BASE_MODULE_NAME = TEXT("Game");
269 
270  static constexpr const TCHAR* ASSETS_PROJECT_MODULE_NAME = TEXT("Game/RapyutaContents");
271 
272 
273 
274 
279  FIntPoint ASSETS_THUMBNAIL_SIZE = {512, 512};
280 
281 
282 
284 
285 
290  FString ASSETS_RUNTIME_BP_SAVE_BASE_PATH = TEXT("/Game/RapyutaContents/Blueprints");
291 
292 
293 
308  FString GetDynamicBPAssetPath(const FString& InBPAssetName)
309 
310  {
311 
312  return FString(ASSETS_RUNTIME_BP_SAVE_BASE_PATH) / InBPAssetName;
313 
314  }
315 
316 
317 
328  FORCEINLINE static constexpr const TCHAR* GetAssetNamePrefix(const ERRResourceDataType InDataType)
329 
330  {
331 
332  switch (InDataType)
333 
334  {
335 
337 
338  return TEXT("SM_");
339 
340 
341 
343 
344  return TEXT("SK_");
345 
346 
347 
349 
350  return TEXT("SKEL_");
351 
352 
353 
355 
356  return TEXT("PHYS_");
357 
358 
359 
361 
362  return TEXT("M_");
363 
365 
366  return TEXT("PM_");
367 
368 
369 
371 
372  return TEXT("T_");
373 
374 
375 
377 
378  return TEXT("DT_");
379 
380 
381 
383 
384  return TEXT("BS_");
385 
386 
387 
388  default:
389 
390  return EMPTY_STR;
391 
392  }
393 
394  }
395 
396 
397 
412  FORCEINLINE static FString GetAssetsBasePath(const TCHAR* InModuleName)
413 
414  {
415 
416  return FString(ASSETS_ROOT_PATH) / InModuleName;
417 
418  }
419 
420 
421 
434  FORCEINLINE FString GetAssetsFolderName(const ERRResourceDataType InDataType)
435 
436  {
437 
438  switch (InDataType)
439 
440  {
441 
443 
444  return FOLDER_PATH_ASSET_PAKS;
445 
446 
447 
449 
450  return FOLDER_PATH_ASSET_STATIC_MESHES;
451 
452 
453 
455 
456  return FOLDER_PATH_ASSET_SKELETAL_MESHES;
457 
458 
459 
461 
462  return FOLDER_PATH_ASSET_SKELETONS;
463 
464 
465 
467 
468  return FOLDER_PATH_PHYSICS_ASSETS;
469 
470 
471 
473 
475 
476  return FOLDER_PATH_ASSET_MATERIALS;
477 
478 
479 
481 
482  return FOLDER_PATH_ASSET_TEXTURES;
483 
484 
485 
487 
488  return FOLDER_PATH_ASSET_DATA_TABLES;
489 
490 
491 
492  default:
493 
494  return EMPTY_STR;
495 
496  }
497 
498  }
499 
500 
501 
502  static constexpr const TCHAR* DYNAMIC_CONTENTS_FOLDER_NAME = TEXT("DynamicContents");
503 
504 
505 
516  FORCEINLINE static FString GetDynamicAssetsBasePath(const TCHAR* InModuleName)
517 
518  {
519 
520  return GetAssetsBasePath(InModuleName) / DYNAMIC_CONTENTS_FOLDER_NAME;
521 
522  }
523 
524 
525 
540  FORCEINLINE FString GetDynamicAssetPath(const ERRResourceDataType InDataType,
541 
542  const FString& InAssetName,
543 
544  const TCHAR* InModuleName)
545 
546  {
547 
548  return GetDynamicAssetsBasePath(InModuleName) / GetAssetsFolderName(InDataType) / InAssetName;
549 
550  }
551 
552 
553 
568  FORCEINLINE static TArray<FString> GetDynamicAssetsBasePathList(const ERRResourceDataType InDataType)
569 
570  {
571 
572  static TArray<FString> dynamicAssetsBasePathList = [InDataType]()
573 
574  {
575 
576  TArray<FString> basePaths;
577 
578  for (const auto& moduleName : SASSET_OWNING_MODULE_NAMES[InDataType])
579 
580  {
581 
582  basePaths.Emplace(GetDynamicAssetsBasePath(moduleName));
583 
584  }
585 
586  return basePaths;
587 
588  }();
589 
590  return dynamicAssetsBasePathList;
591 
592  }
593 
594 
595 
608  template<ERRResourceDataType InDataType>
609 
611 
612  {
613 
614  return CollateAssetsInfo<URRAssetObject<InDataType>>(InDataType, GetAssetsFolderName(InDataType));
615 
616  }
617 
618 
619 
634  template<typename T>
635 
636  int32 CollateAssetsInfo(const ERRResourceDataType InDataType, const FString& InAssetRelativeFolderPath)
637 
638  {
639 
640  FRRResourceInfo& outResourceInfo = GetSimResourceInfo(InDataType);
641 
642 
643 
644  TArray<FAssetData> totalAssetDataList;
645 
646  for (const auto& assetsBasePath : GetDynamicAssetsBasePathList(InDataType))
647 
648  {
649 
650  TArray<FAssetData> assetDataList;
651 
652  URRAssetUtils::LoadAssetDataList<T>(assetsBasePath / InAssetRelativeFolderPath, assetDataList);
653 
654  totalAssetDataList.Append(assetDataList);
655 
656  }
657 
658 
659 
660  for (const auto& asset : totalAssetDataList)
661 
662  {
663 
664 #if RAPYUTA_SIM_DEBUG
665 
666  UE_LOG_WITH_INFO_SHORT(LogTemp,
667 
668  Warning,
669 
670  TEXT("[%s] ASSET [%s] [%s] [%s]"),
671 
672  *asset.AssetName.ToString(),
673 
674  *asset.PackagePath.ToString(),
675 
676  *asset.GetFullName(),
677 
678  *asset.ToSoftObjectPath().ToString());
679 
680 #endif
681 
682  outResourceInfo.AddResource(asset.AssetName.ToString(), asset.ToSoftObjectPath().ToString(), nullptr);
683 
684  }
685 
686  return totalAssetDataList.Num();
687 
688  }
689 
690 
691 
699 
700  {
701 
702  CollateAssetsInfo<ERRResourceDataType::UE_STATIC_MESH>();
703 
704  CollateAssetsInfo<ERRResourceDataType::UE_SKELETAL_MESH>();
705 
706  CollateAssetsInfo<ERRResourceDataType::UE_SKELETON>();
707 
708  CollateAssetsInfo<ERRResourceDataType::UE_PHYSICS_ASSET>();
709 
710  CollateAssetsInfo<ERRResourceDataType::UE_MATERIAL>();
711 
712  CollateAssetsInfo<ERRResourceDataType::UE_PHYSICAL_MATERIAL>();
713 
714  CollateAssetsInfo<ERRResourceDataType::UE_TEXTURE>();
715 
716  }
717 
718 
719 
720  // RESOURCE STORE --
721 
722  //
723 
738  bool HaveAllResourcesBeenLoaded(bool bIsLogged = false) const;
739 
740 
741 
756  template<ERRResourceDataType InDataType>
757 
759 
760  {
761 
762  FRRResourceInfo& resourceInfo = GetSimResourceInfo(InDataType);
763 
764  if (resourceInfo.bHasBeenAllLoaded)
765 
766  {
767 
768  UE_LOG_WITH_INFO(LogTemp, Warning, TEXT("All resources have been loaded. No need to request their loading again."));
769 
770  return true;
771 
772  }
773 
774 
775 
776  // 1- COLLATE ALL ASSETS INFO
777 
778  if (0 == CollateAssetsInfo<URRAssetObject<InDataType>>(InDataType, GetAssetsFolderName(InDataType)))
779 
780  {
781 
782  resourceInfo.bHasBeenAllLoaded = true;
783 
784  UE_LOG_WITH_INFO(
785 
786  LogTemp, Warning, TEXT("THERE IS NO [%s] TO BE LOADED"), *URRTypeUtils::GetERRResourceDataTypeAsString(InDataType));
787 
788  return true;
789 
790  }
791 
792 
793 
794  // 2- REQUEST FOR LOADING THE RESOURCES ASYNCHRONOUSLY
795 
796  resourceInfo.ToBeAsyncLoadedResourceNum = resourceInfo.Data.Num();
797 
798  resourceInfo.bHasBeenAllLoaded = false;
799 
800 #if RAPYUTA_SIM_VERBOSE
801 
802  UE_LOG_WITH_INFO(LogRapyutaCore,
803 
804  Warning,
805 
806  TEXT("[%s] TO BE LOADED NUM: %d"),
807 
809 
810  resourceInfo.ToBeAsyncLoadedResourceNum);
811 
812 #endif
813 
814 
815 
816  UAssetManager* assetManager = UAssetManager::GetIfValid();
817 
818  if (assetManager)
819 
820  {
821 
822  for (const auto& resourceMetaData : resourceInfo.Data)
823 
824  {
825 
826  // https://docs.unrealengine.com/en-US/Resources/SampleGames/ARPG/BalancingBlueprintAndCPP/index.html
827 
828  // "Avoid Referencing Assets by String"
829 
830  FSoftObjectPath resourceSoftObjPath(resourceMetaData.Value.GetAssetPath());
831 
832  assetManager->GetStreamableManager().RequestAsyncLoad(
833 
834  resourceSoftObjPath,
835 
836  FStreamableDelegate::CreateUObject(this,
837 
839 
840  InDataType,
841 
842  resourceSoftObjPath,
843 
844  resourceMetaData.Value.UniqueName));
845 
846  }
847 
848  return true;
849 
850  }
851 
852  else
853 
854  {
855 
856  UE_LOG_WITH_INFO(LogTemp, Error, TEXT("UNABLE TO GET ASSET MANAGER!"))
857 
858  return false;
859 
860  }
861 
862  }
863 
864 
865 
867 
868  FORCEINLINE void OnResourceLoaded(ERRResourceDataType InDataType, FSoftObjectPath InResourcePath, FString InResourceUniqueName)
869 
870  {
871 
872  check(IsInGameThread());
873 
874 
875 
876  switch (InDataType)
877 
878  {
879 
881 
882  ProcessAsyncLoadedResource<UStaticMesh>(InDataType, InResourcePath, InResourceUniqueName);
883 
884  break;
885 
886 
887 
889 
890  ProcessAsyncLoadedResource<USkeletalMesh>(InDataType, InResourcePath, InResourceUniqueName);
891 
892  break;
893 
894 
895 
897 
898  ProcessAsyncLoadedResource<USkeleton>(InDataType, InResourcePath, InResourceUniqueName);
899 
900  break;
901 
902 
903 
905 
906  ProcessAsyncLoadedResource<UPhysicsAsset>(InDataType, InResourcePath, InResourceUniqueName);
907 
908  break;
909 
910 
911 
913 
914  ProcessAsyncLoadedResource<UMaterialInterface>(InDataType, InResourcePath, InResourceUniqueName);
915 
916  break;
917 
918 
919 
921 
922  ProcessAsyncLoadedResource<UPhysicalMaterial>(InDataType, InResourcePath, InResourceUniqueName);
923 
924  break;
925 
926 
927 
929 
930  ProcessAsyncLoadedResource<UTexture>(InDataType, InResourcePath, InResourceUniqueName);
931 
932  break;
933 
934 
935 
937 
938  ProcessAsyncLoadedResource<UDataTable>(InDataType, InResourcePath, InResourceUniqueName);
939 
940  break;
941 
942 
943 
944  default:
945 
946  break;
947 
948  }
949 
950  }
951 
952 
953 
980  template<typename TResource>
981 
982  FORCEINLINE bool ProcessAsyncLoadedResource(const ERRResourceDataType InDataType,
983 
984  const FSoftObjectPath& InResourcePath,
985 
986  const FString& InResourceUniqueName)
987 
988  {
989 
990  verify(IsInGameThread());
991 
992  TResource* resource = Cast<TResource>(InResourcePath.ResolveObject());
993 
994 
995 
996  if (resource)
997 
998  {
999 
1000  // Update [ResourceMap] with the newly loaded resource --
1001 
1002  FRRResourceInfo& resourceInfo = GetSimResourceInfo(InDataType);
1003 
1004  resourceInfo.AddResource(InResourceUniqueName, InResourcePath, resource);
1005 
1006  resourceInfo.ToBeAsyncLoadedResourceNum--;
1007 
1008 #if RAPYUTA_SIM_DEBUG
1009 
1010  UE_LOG_WITH_INFO(LogTemp,
1011 
1012  Warning,
1013 
1014  TEXT("%d [%s] [%s:%s] RESOURCE LOADED %u"),
1015 
1016  resourceInfo.ToBeAsyncLoadedResourceNum,
1017 
1019 
1020  *InResourceUniqueName,
1021 
1022  *InResourcePath.ToString(),
1023 
1024  resource);
1025 
1026 #endif
1027 
1028  if (resourceInfo.ToBeAsyncLoadedResourceNum == 0)
1029 
1030  {
1031 
1032  resourceInfo.bHasBeenAllLoaded = true;
1033 
1034  }
1035 
1036 
1037 
1038  // Resource Data --
1039 
1040  // Still need to store resource handle in a direct UPROPERTY() child TArray of this GameSingleton to bypass
1041 
1042  // early GC
1043 
1044  ResourceStore.AddUnique(Cast<UObject>(resource));
1045 
1046  return true;
1047 
1048  }
1049 
1050  return false;
1051 
1052  }
1053 
1054 
1055 
1074  template<typename TResource>
1075 
1076  FORCEINLINE void AddDynamicResource(const ERRResourceDataType InDataType,
1077 
1078  TResource* InResourceObject,
1079 
1080  const FString& InResourceUniqueName,
1081 
1082  const FString& InResourceAssetPath = EMPTY_STR)
1083 
1084  {
1085 
1086  // Update [ResourceMap] with dynamically runtime-generated [InResourceObject]
1087 
1088  // of which soft object path is also created on the fly.
1089 
1090  FRRResourceInfo& resourceInfo = GetSimResourceInfo(InDataType);
1091 
1092  // (Note) FSoftObjectPath only accepts legit package names, not [InResourceUniqueName] like an arbitrary one
1093 
1094  resourceInfo.AddResource(InResourceUniqueName,
1095 
1096  InResourceAssetPath.IsEmpty() ? FSoftObjectPath(InResourceObject) : InResourceAssetPath,
1097 
1098  InResourceObject);
1099 
1100  resourceInfo.bHasBeenAllLoaded = true;
1101 
1102 
1103 
1104 #if RAPYUTA_SIM_DEBUG
1105 
1106  UE_LOG_WITH_INFO(LogTemp,
1107 
1108  Warning,
1109 
1110  TEXT("[%s] [%s] DYNAMIC RUNTIME RESOURCE ADDED %s"),
1111 
1113 
1114  *InResourceUniqueName,
1115 
1116  *InResourceObject->GetName());
1117 
1118 #endif
1119 
1120 
1121 
1122  // Resource Data
1123 
1124  // Still need to store resource handle in a direct UPROPERTY() child TArray of this GameSingleton to bypass
1125 
1126  // early GC
1127 
1128  if (IsValid(InResourceObject))
1129 
1130  {
1131 
1132  ResourceStore.AddUnique(Cast<UObject>(InResourceObject));
1133 
1134  }
1135 
1136  }
1137 
1138 
1139 
1158  template<typename TResource>
1159 
1160  TResource* GetSimResource(const ERRResourceDataType InDataType,
1161 
1162  const FString& InResourceUniqueName,
1163 
1164  bool bIsStaticResource = true)
1165 
1166  {
1167 
1168  if (false == ResourceMap.Contains(InDataType))
1169 
1170  {
1171 
1172  UE_LOG_WITH_INFO_SHORT(LogTemp,
1173 
1174  Error,
1175 
1176  TEXT("It seems [ResourceMap][%s] has not yet been fully initialized! Make sure GameMode class "
1177 
1178  "is child of RRGameMode."),
1179 
1181 
1182  return nullptr;
1183 
1184  }
1185 
1186  FRRResource resourceInfo = GetSimResourceInfo(InDataType).Data.FindRef(InResourceUniqueName);
1187 
1188  const FString resourceAssetPath = resourceInfo.GetAssetPath();
1189 
1190  auto& resourceAssetData = resourceInfo.AssetData;
1191 
1192 
1193 
1194  bool bNewlyLoaded = false;
1195 
1196  // NOTE: Null [resourceAssetData] either means it is a not-yet-created dynamic resource Or a not-yet-loaded-from-disk static resource (uasset)
1197 
1198  if (false == IsValid(resourceAssetData))
1199 
1200  {
1201 
1202  if (IsInGameThread())
1203 
1204  {
1205 
1206  // NOTE: Empty [resourceAssetPath] should only mean a dynamic resource. Otherwise, the static resource asset path must not have been properly collated!
1207 
1208  resourceAssetData = resourceAssetPath.IsEmpty()
1209 
1210  ? nullptr
1211 
1212  : URRAssetUtils::LoadObjFromAssetPath<TResource>((UObject*)this, resourceAssetPath);
1213 
1214  if (resourceAssetData)
1215 
1216  {
1217 
1218  bNewlyLoaded = true;
1219 
1220  }
1221 
1222  else
1223 
1224  {
1225 
1226  // NOTE: For dynamically-created resources, 1st time querying (due to empty [resourceAssetPath]) always yields null [resourceAssetData] due to no [resourceAssetPath] determined yet,
1227 
1228  // in which case no error log should be printed
1229 
1230  if (bIsStaticResource)
1231 
1232  {
1233 
1234 #if WITH_EDITOR
1235 
1236  UE_LOG_WITH_INFO_SHORT(LogTemp,
1237 
1238  Error,
1239 
1240  TEXT("[%s] [Unique Name: %s] INVALID STATIC RESOURCE PATH [%s]!"),
1241 
1243 
1244  *InResourceUniqueName,
1245 
1246  *resourceAssetPath);
1247 
1248 #else
1249 
1250  UE_LOG_WITH_INFO_SHORT(LogTemp,
1251 
1252  Error,
1253 
1254  TEXT("[%s] [Unique Name: %s] INVALID STATIC RESOURCE PATH [%s]!\n"
1255 
1256  "Please consider adding its containing folder asset path (Eg: "
1257 
1258  "'/RapyutaSimulationPlugins/DynamicContents') to "
1259 
1260  "[DirectoriesToAlwaysCook] in DefaultGame.ini"),
1261 
1263 
1264  *InResourceUniqueName,
1265 
1266  *resourceAssetPath);
1267 
1268 #endif
1269 
1270  }
1271 
1272  return nullptr;
1273 
1274  }
1275 
1276  }
1277 
1278  else
1279 
1280  {
1281 
1282  UE_LOG_WITH_INFO_SHORT(LogTemp,
1283 
1284  Error,
1285 
1286  TEXT("[%s] [Unique Name: %s] RESOURCE SHOULD HAVE BEEN LOADED EARLIER IN GAMETHREAD [%s]!"),
1287 
1289 
1290  *InResourceUniqueName,
1291 
1292  *resourceAssetPath);
1293 
1294  return nullptr;
1295 
1296  }
1297 
1298  }
1299 
1300 
1301 
1302  // Verify resource asset's in-memory validity
1303 
1304  TResource* resourceAsset = Cast<TResource>(resourceAssetData);
1305 
1306  if (resourceAsset)
1307 
1308  {
1309 
1310  if (resourceAsset->IsValidLowLevelFast())
1311 
1312  {
1313 
1314  // Add into resource store if newly loaded above
1315 
1316  if (bNewlyLoaded)
1317 
1318  {
1319 
1320  AddDynamicResource<TResource>(InDataType, resourceAsset, InResourceUniqueName, resourceAssetPath);
1321 
1322  }
1323 
1324  }
1325 
1326  else
1327 
1328  {
1329 
1330  UE_LOG_WITH_INFO_SHORT(LogTemp,
1331 
1332  Error,
1333 
1334  TEXT("[%s] [Unique Name: %s] INVALID-AT-LOW-LEVEL RESOURCE %u!"),
1335 
1337 
1338  *InResourceUniqueName,
1339 
1340  resourceAsset)
1341 
1342  return nullptr;
1343 
1344  }
1345 
1346  }
1347 
1348  return resourceAsset;
1349 
1350  }
1351 
1352 
1353 
1370  bool HasSimResource(const ERRResourceDataType InDataType, const FString& InResourceUniqueName) const
1371 
1372  {
1373 
1374  return GetSimResourceInfo(InDataType).Data.Contains(InResourceUniqueName);
1375 
1376  }
1377 
1378 
1379 
1392  const TMap<FString, FRRResource>& GetSimResourceList(const ERRResourceDataType InDataType) const
1393 
1394  {
1395 
1396  verifyf(ResourceMap.Contains(InDataType),
1397 
1398  TEXT("It seems [ResourceMap][%s] not yet fully initialized!"),
1399 
1401 
1402  return GetSimResourceInfo(InDataType).Data;
1403 
1404  }
1405 
1406 
1407 
1421 
1422  {
1423 
1424  verifyf(ResourceMap.Contains(InDataType),
1425 
1426  TEXT("It seems [ResourceMap][%s] has not yet been fully initialized!"),
1427 
1429 
1430  return ResourceMap[InDataType];
1431 
1432  }
1433 
1434 
1435 
1449 
1450  {
1451 
1452  verifyf(ResourceMap.Contains(InDataType),
1453 
1454  TEXT("It seems [ResourceMap][%s] has not yet been fully initialized!"),
1455 
1457 
1458  return ResourceMap[InDataType];
1459 
1460  }
1461 
1462 
1463 
1464  // STATIC MESHES --
1465 
1466 
1471  FString FOLDER_PATH_ASSET_STATIC_MESHES = TEXT("StaticMeshes");
1472 
1473 
1474 
1475  // These names must match ones defined in [StaticMeshShapesInfoFileName] file
1476 
1477  // Here we only define specially used shapes for some specific purpose!
1478 
1479  static constexpr const TCHAR* SHAPE_NAME_PLANE = TEXT("Plane");
1480 
1481  static constexpr const TCHAR* SHAPE_NAME_CUBE = TEXT("Cube");
1482 
1483  static constexpr const TCHAR* SHAPE_NAME_CYLINDER = TEXT("Cylinder");
1484 
1485  static constexpr const TCHAR* SHAPE_NAME_SPHERE = TEXT("Sphere");
1486 
1487  static constexpr const TCHAR* SHAPE_NAME_CAPSULE = TEXT("Capsule");
1488 
1489 
1490 
1491  static const FString GetMeshNameFromShapeType(const ERRShapeType InShapeType)
1492 
1493  {
1494 
1495  switch (InShapeType)
1496 
1497  {
1498 
1499  case ERRShapeType::PLANE:
1500 
1501  return SHAPE_NAME_PLANE;
1502 
1503  case ERRShapeType::BOX:
1504 
1505  return SHAPE_NAME_CUBE;
1506 
1508 
1509  return SHAPE_NAME_CYLINDER;
1510 
1511  case ERRShapeType::SPHERE:
1512 
1513  return SHAPE_NAME_SPHERE;
1514 
1515  case ERRShapeType::CAPSULE:
1516 
1517  return SHAPE_NAME_CAPSULE;
1518 
1519  default:
1520 
1521  return EMPTY_STR;
1522 
1523  }
1524 
1525  }
1526 
1527 
1528 
1529  static ERRShapeType GetShapeTypeFromMeshName(const FString& InMeshName)
1530 
1531  {
1532 
1533  return InMeshName.Equals(SHAPE_NAME_PLANE) ? ERRShapeType::PLANE
1534 
1535  : InMeshName.Equals(SHAPE_NAME_CUBE) ? ERRShapeType::BOX
1536 
1537  : InMeshName.Equals(SHAPE_NAME_CYLINDER) ? ERRShapeType::CYLINDER
1538 
1539  : InMeshName.Equals(SHAPE_NAME_SPHERE) ? ERRShapeType::SPHERE
1540 
1541  : InMeshName.Equals(SHAPE_NAME_CAPSULE) ? ERRShapeType::CAPSULE
1542 
1544 
1545  }
1546 
1547 
1548 
1565  FORCEINLINE UStaticMesh* GetStaticMesh(const FString& InStaticMeshName, bool bIsStaticResource = true)
1566 
1567  {
1568 
1569  return GetSimResource<UStaticMesh>(ERRResourceDataType::UE_STATIC_MESH, InStaticMeshName, bIsStaticResource);
1570 
1571  }
1572 
1573 
1574 
1575  // SKELETAL ASSETS --
1576 
1577 
1582  FString FOLDER_PATH_ASSET_SKELETAL_MESHES = TEXT("SkeletalMeshes");
1583 
1584 
1589  FString FOLDER_PATH_ASSET_SKELETONS = TEXT("Skeletons");
1590 
1591 
1596  FString FOLDER_PATH_PHYSICS_ASSETS = TEXT("PhysicsAssets");
1597 
1612  FORCEINLINE USkeletalMesh* GetSkeletalMesh(const FString& InSkeletalMeshName, bool bIsStaticResource = true)
1613 
1614  {
1615 
1616  return GetSimResource<USkeletalMesh>(ERRResourceDataType::UE_SKELETAL_MESH, InSkeletalMeshName, bIsStaticResource);
1617 
1618  }
1619 
1620 
1621 
1636  FORCEINLINE USkeleton* GetSkeleton(const FString& InSkeletonName, bool bIsStaticResource = true)
1637 
1638  {
1639 
1640  return GetSimResource<USkeleton>(ERRResourceDataType::UE_SKELETON, InSkeletonName, bIsStaticResource);
1641 
1642  }
1643 
1644 
1645 
1660  FORCEINLINE UPhysicsAsset* GetPhysicsAsset(const FString& InPhysicsAssetName, bool bIsStaticResource = true)
1661 
1662  {
1663 
1664  return GetSimResource<UPhysicsAsset>(ERRResourceDataType::UE_PHYSICS_ASSET, InPhysicsAssetName, bIsStaticResource);
1665 
1666  }
1667 
1668 
1669 
1670  // MATERIALS --
1671 
1673 
1674 
1679  FString FOLDER_PATH_ASSET_MATERIALS = TEXT("Materials");
1680 
1681 
1682 
1683  // Here we only define specially used materials for some specific purpose!
1684 
1685  static constexpr const TCHAR* MATERIAL_NAME_ASSET_MASTER = TEXT("M_RapyutaAssetMaster");
1686 
1687  static constexpr const TCHAR* MATERIAL_NAME_PROP_MASTER = TEXT("M_RapyutaPropMaster");
1688 
1689  static constexpr const TCHAR* MATERIAL_NAME_PHYSICS_WHEEL = TEXT("PM_Wheel");
1690 
1691  static constexpr const TCHAR* MATERIAL_NAME_TRANSLUCENCE_MASTER = TEXT("M_RapyutaTranslucenceMaster");
1692 
1693 
1694 
1707  FORCEINLINE UMaterialInterface* GetMaterial(const FString& InMaterialName)
1708 
1709  {
1710 
1711  return GetSimResource<UMaterialInterface>(ERRResourceDataType::UE_MATERIAL, InMaterialName);
1712 
1713  }
1714 
1715 
1716 
1729  FORCEINLINE UPhysicalMaterial* GetPhysicalMaterial(const FString& InPhysicalMaterialName)
1730 
1731  {
1732 
1733  return GetSimResource<UPhysicalMaterial>(ERRResourceDataType::UE_PHYSICAL_MATERIAL, InPhysicalMaterialName);
1734 
1735  }
1736 
1737 
1738 
1739  // TEXTURES --
1740 
1742 
1743 
1748  FString FOLDER_PATH_ASSET_TEXTURES = TEXT("Textures");
1749 
1750 
1751 
1752  static constexpr const TCHAR* TEXTURE_NAME_WHITE_MASK = TEXT("T_WhiteMask");
1753 
1754  static constexpr const TCHAR* TEXTURE_NAME_BLACK_MASK = TEXT("T_BlackMask");
1755 
1756 
1757 
1770  FORCEINLINE UTexture* GetTexture(const FString& InTextureName, bool bIsStaticResource = true)
1771 
1772  {
1773 
1774  return GetSimResource<UTexture>(ERRResourceDataType::UE_TEXTURE, InTextureName, bIsStaticResource);
1775 
1776  }
1777 
1778 
1779 
1780  // DATA TABLES --
1781 
1783 
1784 
1789  FString FOLDER_PATH_ASSET_DATA_TABLES = TEXT("DataTables");
1790 
1791 
1792 
1805  FORCEINLINE UDataTable* GetDataTable(const FString& InDataTableName, bool bIsStaticResource = true)
1806 
1807  {
1808 
1809  return GetSimResource<UDataTable>(ERRResourceDataType::UE_DATA_TABLE, InDataTableName, bIsStaticResource);
1810 
1811  }
1812 
1813 
1814 
1815  // BODY SETUPS --
1816 
1827  FORCEINLINE UBodySetup* GetBodySetup(const FString& InBodySetupName)
1828 
1829  {
1830 
1831  // Body setups are dynamically created, thus not static resources
1832 
1833  return GetSimResource<UBodySetup>(ERRResourceDataType::UE_BODY_SETUP, InBodySetupName, false);
1834 
1835  }
1836 
1837 
1838 
1839 private:
1840 
1842 
1844 
1845  TMap<ERRResourceDataType, FRRResourceInfo> ResourceMap;
1846 
1847 
1848 
1850 
1851 
1856  TArray<TObjectPtr<UObject>> ResourceStore;
1857 
1858 };
1859 
URRGameSingleton::GetSkeletalMesh
FORCEINLINE USkeletalMesh * GetSkeletalMesh(const FString &InSkeletalMeshName, bool bIsStaticResource=true)
Get or load skeletal mesh, GetSimResource with ERRResourceDataType::UE_SKELETAL_MESH.
Definition: RRGameSingleton.h:1612
RapyutaSimulationPlugins.h
Unreal Engine Mudule class.
EMPTY_STR
#define EMPTY_STR
Definition: RRGeneralUtils.h:43
ERRResourceDataType::UE_BODY_SETUP
@ UE_BODY_SETUP
URRGameSingleton::GetPhysicalMaterial
FORCEINLINE UPhysicalMaterial * GetPhysicalMaterial(const FString &InPhysicalMaterialName)
Get or load physical material, calling GetSimResource with ERRResourceDataType::UE_PHYSICAL_MATERIAL.
Definition: RRGameSingleton.h:1729
ERRResourceDataType::UE_PHYSICAL_MATERIAL
@ UE_PHYSICAL_MATERIAL
FRRResource
The atomic Sim resouces(Uassets)
Definition: RRObjectCommon.h:231
URRGameSingleton::GetAssetsFolderName
FORCEINLINE FString GetAssetsFolderName(const ERRResourceDataType InDataType)
Get the leaf relative UE path of a folder housing assets of a particular resource data type.
Definition: RRGameSingleton.h:434
FRRResource::AssetData
UObject * AssetData
Definition: RRObjectCommon.h:320
URRGameSingleton::CollateAssetsInfo
void CollateAssetsInfo()
Collate assets info.
Definition: RRGameSingleton.h:698
RRTypeUtils.h
UE type related utils.
URRGameSingleton::CollateAssetsInfo
int32 CollateAssetsInfo()
Collate assets info for ResourceMap.
Definition: RRGameSingleton.h:610
URRGameSingleton::GetBodySetup
FORCEINLINE UBodySetup * GetBodySetup(const FString &InBodySetupName)
Get or load BodySetup, calling GetSimResource with ERRResourceDataType::UE_BODY_SETUP.
Definition: RRGameSingleton.h:1827
URRGameSingleton::RequestResourcesLoading
bool RequestResourcesLoading()
Collate asset resources info & Async load them by UAssetManager.
Definition: RRGameSingleton.h:758
ERRShapeType::PLANE
@ PLANE
ERRResourceDataType::UE_DATA_TABLE
@ UE_DATA_TABLE
URRGameSingleton::HasSimResource
bool HasSimResource(const ERRResourceDataType InDataType, const FString &InResourceUniqueName) const
Check resource exist with GetSimResourceInfo.
Definition: RRGameSingleton.h:1370
ERRResourceDataType::UE_SKELETON
@ UE_SKELETON
URRGameSingleton::GetSimResourceList
const TMap< FString, FRRResource > & GetSimResourceList(const ERRResourceDataType InDataType) const
Get the Sim Resource List object with GetSimResourceInfo.
Definition: RRGameSingleton.h:1392
FRRResourceInfo::ToBeAsyncLoadedResourceNum
int32 ToBeAsyncLoadedResourceNum
Definition: RRObjectCommon.h:395
URRGameSingleton::CollateAssetsInfo
int32 CollateAssetsInfo(const ERRResourceDataType InDataType, const FString &InAssetRelativeFolderPath)
Collate assets info for ResourceMap.
Definition: RRGameSingleton.h:636
FRRResource::GetAssetPath
FString GetAssetPath() const
Get the Asset Path.
Definition: RRObjectCommon.h:305
ERRShapeType::BOX
@ BOX
URRGameSingleton::GetSimResource
TResource * GetSimResource(const ERRResourceDataType InDataType, const FString &InResourceUniqueName, bool bIsStaticResource=true)
Get the Sim Resource object, loading if required + updating resource store.
Definition: RRGameSingleton.h:1160
ERRResourceDataType::UE_PHYSICS_ASSET
@ UE_PHYSICS_ASSET
FRRResourceInfo
Structure to store resources(Uassets) information.
Definition: RRObjectCommon.h:341
URRGameSingleton::GetDynamicAssetsBasePath
static FORCEINLINE FString GetDynamicAssetsBasePath(const TCHAR *InModuleName)
Get the dynamic Assets Base Path of a module.
Definition: RRGameSingleton.h:516
URRGameSingleton::AddDynamicResource
FORCEINLINE void AddDynamicResource(const ERRResourceDataType InDataType, TResource *InResourceObject, const FString &InResourceUniqueName, const FString &InResourceAssetPath=EMPTY_STR)
Update ResourceMap and ResourceStore with dynamically runtime-generated InResourceObject of which sof...
Definition: RRGameSingleton.h:1076
URRGameSingleton::GetSimResourceInfo
FRRResourceInfo & GetSimResourceInfo(const ERRResourceDataType InDataType)
Get the Sim Resource Info object from ResourceMap.
Definition: RRGameSingleton.h:1420
URRGameSingleton::ProcessAsyncLoadedResource
FORCEINLINE bool ProcessAsyncLoadedResource(const ERRResourceDataType InDataType, const FSoftObjectPath &InResourcePath, const FString &InResourceUniqueName)
Callback to handle an asynchronously loaded resource, which receives a [FSoftObjectPath] that referen...
Definition: RRGameSingleton.h:982
URRGameSingleton::GetDynamicAssetPath
FORCEINLINE FString GetDynamicAssetPath(const ERRResourceDataType InDataType, const FString &InAssetName, const TCHAR *InModuleName)
Get the full UE path of a dynamic asset that is either early loaded at Sim initilization or generated...
Definition: RRGameSingleton.h:540
ERRResourceDataType::UE_STATIC_MESH
@ UE_STATIC_MESH
URRGameSingleton::ResourceStore
TArray< TObjectPtr< UObject > > ResourceStore
We need this to escape UObject-based resource Garbage Collection.
Definition: RRGameSingleton.h:1856
URRGameSingleton::GetAssetNamePrefix
static constexpr const FORCEINLINE TCHAR * GetAssetNamePrefix(const ERRResourceDataType InDataType)
Get name prefix of asset.
Definition: RRGameSingleton.h:328
URRGameSingleton::GetDataTable
FORCEINLINE UDataTable * GetDataTable(const FString &InDataTableName, bool bIsStaticResource=true)
Get or load Data table, calling GetSimResource with ERRResourceDataType::UE_DATA_TABLE.
Definition: RRGameSingleton.h:1805
URRGameSingleton::GetSkeleton
FORCEINLINE USkeleton * GetSkeleton(const FString &InSkeletonName, bool bIsStaticResource=true)
Get or load physics skeleton, GetSimResource with ERRResourceDataType::UE_SKELETON.
Definition: RRGameSingleton.h:1636
URRGameSingleton::GetMaterial
FORCEINLINE UMaterialInterface * GetMaterial(const FString &InMaterialName)
Get or load material, calling GetSimResource with ERRResourceDataType::UE_MATERIAL.
Definition: RRGameSingleton.h:1707
RRAssetUtils.h
Asset utils.
ERRResourceDataType::UE_MATERIAL
@ UE_MATERIAL
URRGameSingleton::GetStaticMesh
FORCEINLINE UStaticMesh * GetStaticMesh(const FString &InStaticMeshName, bool bIsStaticResource=true)
Get or load static mesh, GetSimResource with ERRResourceDataType::UE_STATIC_MESH.
Definition: RRGameSingleton.h:1565
URRGameSingleton::GetShapeTypeFromMeshName
static ERRShapeType GetShapeTypeFromMeshName(const FString &InMeshName)
Definition: RRGameSingleton.h:1529
URRGameSingleton::OnResourceLoaded
FORCEINLINE void OnResourceLoaded(ERRResourceDataType InDataType, FSoftObjectPath InResourcePath, FString InResourceUniqueName)
This is used as param to [FStreamableDelegate::CreateUObject()] thus its params could not be constref...
Definition: RRGameSingleton.h:868
ERRShapeType
ERRShapeType
Shape types.
Definition: RRObjectCommon.h:137
URRTypeUtils::GetERRResourceDataTypeAsString
static FORCEINLINE FString GetERRResourceDataTypeAsString(const ERRResourceDataType InDataType)
Definition: RRTypeUtils.h:272
URRGameSingleton::GetSimResourceInfo
const FRRResourceInfo & GetSimResourceInfo(const ERRResourceDataType InDataType) const
Get the Sim Resource Info object from ResourceMap.
Definition: RRGameSingleton.h:1448
URRGameSingleton::GetTexture
FORCEINLINE UTexture * GetTexture(const FString &InTextureName, bool bIsStaticResource=true)
Get or load texture, calling GetSimResource with ERRResourceDataType::UE_TEXTURE.
Definition: RRGameSingleton.h:1770
FRRResourceInfo::bHasBeenAllLoaded
bool bHasBeenAllLoaded
Definition: RRObjectCommon.h:404
ERRShapeType::CYLINDER
@ CYLINDER
URRPakLoader
Pak loader.
Definition: RRPakLoader.h:52
RRActorCommon.h
Asset utils.
RRGeneralUtils.h
General utils.
FRRResourceInfo::AddResource
void AddResource(const FString &InUniqueName, const FSoftObjectPath &InAssetPath, UObject *InAssetData)
Definition: RRObjectCommon.h:417
URRGameSingleton::GetDynamicAssetsBasePathList
static FORCEINLINE TArray< FString > GetDynamicAssetsBasePathList(const ERRResourceDataType InDataType)
Get the Dynamic Assets Path List object.
Definition: RRGameSingleton.h:568
ERRShapeType::CAPSULE
@ CAPSULE
ERRResourceDataType
ERRResourceDataType
Sim resource(Uassets) data types.
Definition: RRObjectCommon.h:174
URRGameSingleton::GetAssetsBasePath
static FORCEINLINE FString GetAssetsBasePath(const TCHAR *InModuleName)
Get the Assets Base Path object.
Definition: RRGameSingleton.h:412
RRObjectCommon.h
Common objects.
URRGameSingleton::SASSET_OWNING_MODULE_NAMES
static TMap< ERRResourceDataType, TArray< const TCHAR * > > SASSET_OWNING_MODULE_NAMES
This list specifically hosts names of which module houses the UE assets based on their data type.
Definition: RRGameSingleton.h:258
URRGameSingleton::GetPhysicsAsset
FORCEINLINE UPhysicsAsset * GetPhysicsAsset(const FString &InPhysicsAssetName, bool bIsStaticResource=true)
Get or load physics asset, GetSimResource with ERRResourceDataType::UE_PHYSICS_ASSET.
Definition: RRGameSingleton.h:1660
ERRShapeType::MESH
@ MESH
URRGameSingleton
GameSingleton class which handles asset loading.
Definition: RRGameSingleton.h:144
URRGameSingleton::ResourceMap
TMap< ERRResourceDataType, FRRResourceInfo > ResourceMap
Async loaded, thus must be thread safe. A map just helps referencing an item faster,...
Definition: RRGameSingleton.h:1845
ERRShapeType::SPHERE
@ SPHERE
ERRResourceDataType::UE_TEXTURE
@ UE_TEXTURE
ERRResourceDataType::UE_SKELETAL_MESH
@ UE_SKELETAL_MESH
URRGameSingleton::GetMeshNameFromShapeType
static const FString GetMeshNameFromShapeType(const ERRShapeType InShapeType)
Definition: RRGameSingleton.h:1491
ERRResourceDataType::UE_PAK
@ UE_PAK
FRRResourceInfo::Data
TMap< FString, FRRResource > Data
Definition: RRObjectCommon.h:413
URRAssetObject
typename TChooseClass<(ERRResourceDataType::UE_STATIC_MESH==InDataType), UStaticMesh, typename TChooseClass<(ERRResourceDataType::UE_SKELETAL_MESH==InDataType), USkeletalMesh, typename TChooseClass<(ERRResourceDataType::UE_SKELETON==InDataType), USkeleton, typename TChooseClass<(ERRResourceDataType::UE_PHYSICS_ASSET==InDataType), UPhysicsAsset, typename TChooseClass<(ERRResourceDataType::UE_MATERIAL==InDataType), UMaterialInterface, typename TChooseClass<(ERRResourceDataType::UE_PHYSICAL_MATERIAL==InDataType), UPhysicalMaterial, typename TChooseClass<(ERRResourceDataType::UE_TEXTURE==InDataType), UTexture, typename TChooseClass<(ERRResourceDataType::UE_DATA_TABLE==InDataType), UDataTable, typename TChooseClass<(ERRResourceDataType::UE_BODY_SETUP==InDataType), UBodySetup, UObject >::Result >::Result >::Result >::Result >::Result >::Result >::Result >::Result >::Result URRAssetObject
Definition: RRGameSingleton.h:117
URRGameSingleton::GetDynamicBPAssetPath
FString GetDynamicBPAssetPath(const FString &InBPAssetName)
Get UE asset path of a dynamically created BP asset.
Definition: RRGameSingleton.h:308