21 #include "CoreMinimal.h"
23 #include "Engine/AssetManager.h"
25 #include "Engine/SkeletalMesh.h"
27 #include "Engine/StaticMesh.h"
29 #include "Engine/StreamableManager.h"
31 #include "Materials/Material.h"
33 #include "PhysicalMaterials/PhysicalMaterial.h"
35 #include "PhysicsEngine/BodySetup.h"
37 #include "Templates/UniquePtr.h"
57 #include "RRGameSingleton.generated.h"
65 template<const ERRResourceDataType InDataType>
73 typename TChooseClass<
79 typename TChooseClass<
85 typename TChooseClass<
91 typename TChooseClass<
97 typename TChooseClass<
103 typename TChooseClass<
109 typename TChooseClass<
117 Result>::Result>::Result>::Result>::Result>::Result>::Result>::Result>::Result;
162 virtual void PrintSimConfig()
const;
175 bool BSIM_PROFILING =
false;
197 bool InitializeResources(
bool bInRequestResourceLoading =
false);
209 void FinalizeResources();
220 FString FOLDER_PATH_ASSET_PAKS = TEXT(
"Paks");
227 TObjectPtr<URRPakLoader> PakLoader =
nullptr;
236 bool bPakLoaderInitialized =
false;
250 bool CollateEntityAssetsInfoFromPAK(
const TArray<FString>& InEntityModelNameList,
bool bInForceReload =
false);
266 static constexpr
const TCHAR* ASSETS_ROOT_PATH = TEXT(
"/");
268 static constexpr
const TCHAR* ASSETS_PROJECT_BASE_MODULE_NAME = TEXT(
"Game");
270 static constexpr
const TCHAR* ASSETS_PROJECT_MODULE_NAME = TEXT(
"Game/RapyutaContents");
279 FIntPoint ASSETS_THUMBNAIL_SIZE = {512, 512};
290 FString ASSETS_RUNTIME_BP_SAVE_BASE_PATH = TEXT(
"/Game/RapyutaContents/Blueprints");
312 return FString(ASSETS_RUNTIME_BP_SAVE_BASE_PATH) / InBPAssetName;
350 return TEXT(
"SKEL_");
356 return TEXT(
"PHYS_");
416 return FString(ASSETS_ROOT_PATH) / InModuleName;
444 return FOLDER_PATH_ASSET_PAKS;
450 return FOLDER_PATH_ASSET_STATIC_MESHES;
456 return FOLDER_PATH_ASSET_SKELETAL_MESHES;
462 return FOLDER_PATH_ASSET_SKELETONS;
468 return FOLDER_PATH_PHYSICS_ASSETS;
476 return FOLDER_PATH_ASSET_MATERIALS;
482 return FOLDER_PATH_ASSET_TEXTURES;
488 return FOLDER_PATH_ASSET_DATA_TABLES;
502 static constexpr
const TCHAR* DYNAMIC_CONTENTS_FOLDER_NAME = TEXT(
"DynamicContents");
520 return GetAssetsBasePath(InModuleName) / DYNAMIC_CONTENTS_FOLDER_NAME;
542 const FString& InAssetName,
544 const TCHAR* InModuleName)
548 return GetDynamicAssetsBasePath(InModuleName) / GetAssetsFolderName(InDataType) / InAssetName;
572 static TArray<FString> dynamicAssetsBasePathList = [InDataType]()
576 TArray<FString> basePaths;
578 for (
const auto& moduleName : SASSET_OWNING_MODULE_NAMES[InDataType])
582 basePaths.Emplace(GetDynamicAssetsBasePath(moduleName));
590 return dynamicAssetsBasePathList;
608 template<ERRResourceDataType InDataType>
614 return CollateAssetsInfo<URRAssetObject<InDataType>>(InDataType, GetAssetsFolderName(InDataType));
644 TArray<FAssetData> totalAssetDataList;
646 for (
const auto& assetsBasePath : GetDynamicAssetsBasePathList(InDataType))
650 TArray<FAssetData> assetDataList;
652 URRAssetUtils::LoadAssetDataList<T>(assetsBasePath / InAssetRelativeFolderPath, assetDataList);
654 totalAssetDataList.Append(assetDataList);
660 for (
const auto& asset : totalAssetDataList)
664 #if RAPYUTA_SIM_DEBUG
666 UE_LOG_WITH_INFO_SHORT(LogTemp,
670 TEXT(
"[%s] ASSET [%s] [%s] [%s]"),
672 *asset.AssetName.ToString(),
674 *asset.PackagePath.ToString(),
676 *asset.GetFullName(),
678 *asset.ToSoftObjectPath().ToString());
682 outResourceInfo.
AddResource(asset.AssetName.ToString(), asset.ToSoftObjectPath().ToString(),
nullptr);
686 return totalAssetDataList.Num();
702 CollateAssetsInfo<ERRResourceDataType::UE_STATIC_MESH>();
704 CollateAssetsInfo<ERRResourceDataType::UE_SKELETAL_MESH>();
706 CollateAssetsInfo<ERRResourceDataType::UE_SKELETON>();
708 CollateAssetsInfo<ERRResourceDataType::UE_PHYSICS_ASSET>();
710 CollateAssetsInfo<ERRResourceDataType::UE_MATERIAL>();
712 CollateAssetsInfo<ERRResourceDataType::UE_PHYSICAL_MATERIAL>();
714 CollateAssetsInfo<ERRResourceDataType::UE_TEXTURE>();
738 bool HaveAllResourcesBeenLoaded(
bool bIsLogged =
false)
const;
756 template<ERRResourceDataType InDataType>
768 UE_LOG_WITH_INFO(LogTemp, Warning, TEXT(
"All resources have been loaded. No need to request their loading again."));
800 #if RAPYUTA_SIM_VERBOSE
802 UE_LOG_WITH_INFO(LogRapyutaCore,
806 TEXT(
"[%s] TO BE LOADED NUM: %d"),
816 UAssetManager* assetManager = UAssetManager::GetIfValid();
822 for (
const auto& resourceMetaData : resourceInfo.
Data)
830 FSoftObjectPath resourceSoftObjPath(resourceMetaData.Value.GetAssetPath());
832 assetManager->GetStreamableManager().RequestAsyncLoad(
836 FStreamableDelegate::CreateUObject(
this,
844 resourceMetaData.Value.UniqueName));
856 UE_LOG_WITH_INFO(LogTemp, Error, TEXT(
"UNABLE TO GET ASSET MANAGER!"))
872 check(IsInGameThread());
882 ProcessAsyncLoadedResource<UStaticMesh>(InDataType, InResourcePath, InResourceUniqueName);
890 ProcessAsyncLoadedResource<USkeletalMesh>(InDataType, InResourcePath, InResourceUniqueName);
898 ProcessAsyncLoadedResource<USkeleton>(InDataType, InResourcePath, InResourceUniqueName);
906 ProcessAsyncLoadedResource<UPhysicsAsset>(InDataType, InResourcePath, InResourceUniqueName);
914 ProcessAsyncLoadedResource<UMaterialInterface>(InDataType, InResourcePath, InResourceUniqueName);
922 ProcessAsyncLoadedResource<UPhysicalMaterial>(InDataType, InResourcePath, InResourceUniqueName);
930 ProcessAsyncLoadedResource<UTexture>(InDataType, InResourcePath, InResourceUniqueName);
938 ProcessAsyncLoadedResource<UDataTable>(InDataType, InResourcePath, InResourceUniqueName);
980 template<
typename TResource>
984 const FSoftObjectPath& InResourcePath,
986 const FString& InResourceUniqueName)
990 verify(IsInGameThread());
992 TResource* resource = Cast<TResource>(InResourcePath.ResolveObject());
1004 resourceInfo.
AddResource(InResourceUniqueName, InResourcePath, resource);
1008 #if RAPYUTA_SIM_DEBUG
1010 UE_LOG_WITH_INFO(LogTemp,
1014 TEXT(
"%d [%s] [%s:%s] RESOURCE LOADED %u"),
1020 *InResourceUniqueName,
1022 *InResourcePath.ToString(),
1044 ResourceStore.AddUnique(Cast<UObject>(resource));
1074 template<
typename TResource>
1078 TResource* InResourceObject,
1080 const FString& InResourceUniqueName,
1082 const FString& InResourceAssetPath =
EMPTY_STR)
1096 InResourceAssetPath.IsEmpty() ? FSoftObjectPath(InResourceObject) : InResourceAssetPath,
1104 #if RAPYUTA_SIM_DEBUG
1106 UE_LOG_WITH_INFO(LogTemp,
1110 TEXT(
"[%s] [%s] DYNAMIC RUNTIME RESOURCE ADDED %s"),
1114 *InResourceUniqueName,
1116 *InResourceObject->GetName());
1128 if (IsValid(InResourceObject))
1132 ResourceStore.AddUnique(Cast<UObject>(InResourceObject));
1158 template<
typename TResource>
1162 const FString& InResourceUniqueName,
1164 bool bIsStaticResource =
true)
1168 if (
false == ResourceMap.Contains(InDataType))
1172 UE_LOG_WITH_INFO_SHORT(LogTemp,
1176 TEXT(
"It seems [ResourceMap][%s] has not yet been fully initialized! Make sure GameMode class "
1178 "is child of RRGameMode."),
1186 FRRResource resourceInfo = GetSimResourceInfo(InDataType).Data.FindRef(InResourceUniqueName);
1188 const FString resourceAssetPath = resourceInfo.
GetAssetPath();
1190 auto& resourceAssetData = resourceInfo.
AssetData;
1194 bool bNewlyLoaded =
false;
1198 if (
false == IsValid(resourceAssetData))
1202 if (IsInGameThread())
1208 resourceAssetData = resourceAssetPath.IsEmpty()
1212 : URRAssetUtils::LoadObjFromAssetPath<TResource>((UObject*)
this, resourceAssetPath);
1214 if (resourceAssetData)
1218 bNewlyLoaded =
true;
1230 if (bIsStaticResource)
1236 UE_LOG_WITH_INFO_SHORT(LogTemp,
1240 TEXT(
"[%s] [Unique Name: %s] INVALID STATIC RESOURCE PATH [%s]!"),
1244 *InResourceUniqueName,
1246 *resourceAssetPath);
1250 UE_LOG_WITH_INFO_SHORT(LogTemp,
1254 TEXT(
"[%s] [Unique Name: %s] INVALID STATIC RESOURCE PATH [%s]!\n"
1256 "Please consider adding its containing folder asset path (Eg: "
1258 "'/RapyutaSimulationPlugins/DynamicContents') to "
1260 "[DirectoriesToAlwaysCook] in DefaultGame.ini"),
1264 *InResourceUniqueName,
1266 *resourceAssetPath);
1282 UE_LOG_WITH_INFO_SHORT(LogTemp,
1286 TEXT(
"[%s] [Unique Name: %s] RESOURCE SHOULD HAVE BEEN LOADED EARLIER IN GAMETHREAD [%s]!"),
1290 *InResourceUniqueName,
1292 *resourceAssetPath);
1304 TResource* resourceAsset = Cast<TResource>(resourceAssetData);
1310 if (resourceAsset->IsValidLowLevelFast())
1320 AddDynamicResource<TResource>(InDataType, resourceAsset, InResourceUniqueName, resourceAssetPath);
1330 UE_LOG_WITH_INFO_SHORT(LogTemp,
1334 TEXT(
"[%s] [Unique Name: %s] INVALID-AT-LOW-LEVEL RESOURCE %u!"),
1338 *InResourceUniqueName,
1348 return resourceAsset;
1374 return GetSimResourceInfo(InDataType).Data.Contains(InResourceUniqueName);
1396 verifyf(ResourceMap.Contains(InDataType),
1398 TEXT(
"It seems [ResourceMap][%s] not yet fully initialized!"),
1402 return GetSimResourceInfo(InDataType).Data;
1424 verifyf(ResourceMap.Contains(InDataType),
1426 TEXT(
"It seems [ResourceMap][%s] has not yet been fully initialized!"),
1430 return ResourceMap[InDataType];
1452 verifyf(ResourceMap.Contains(InDataType),
1454 TEXT(
"It seems [ResourceMap][%s] has not yet been fully initialized!"),
1458 return ResourceMap[InDataType];
1471 FString FOLDER_PATH_ASSET_STATIC_MESHES = TEXT(
"StaticMeshes");
1479 static constexpr
const TCHAR* SHAPE_NAME_PLANE = TEXT(
"Plane");
1481 static constexpr
const TCHAR* SHAPE_NAME_CUBE = TEXT(
"Cube");
1483 static constexpr
const TCHAR* SHAPE_NAME_CYLINDER = TEXT(
"Cylinder");
1485 static constexpr
const TCHAR* SHAPE_NAME_SPHERE = TEXT(
"Sphere");
1487 static constexpr
const TCHAR* SHAPE_NAME_CAPSULE = TEXT(
"Capsule");
1495 switch (InShapeType)
1501 return SHAPE_NAME_PLANE;
1505 return SHAPE_NAME_CUBE;
1509 return SHAPE_NAME_CYLINDER;
1513 return SHAPE_NAME_SPHERE;
1517 return SHAPE_NAME_CAPSULE;
1565 FORCEINLINE UStaticMesh*
GetStaticMesh(
const FString& InStaticMeshName,
bool bIsStaticResource =
true)
1582 FString FOLDER_PATH_ASSET_SKELETAL_MESHES = TEXT(
"SkeletalMeshes");
1589 FString FOLDER_PATH_ASSET_SKELETONS = TEXT(
"Skeletons");
1596 FString FOLDER_PATH_PHYSICS_ASSETS = TEXT(
"PhysicsAssets");
1612 FORCEINLINE USkeletalMesh*
GetSkeletalMesh(
const FString& InSkeletalMeshName,
bool bIsStaticResource =
true)
1636 FORCEINLINE USkeleton*
GetSkeleton(
const FString& InSkeletonName,
bool bIsStaticResource =
true)
1660 FORCEINLINE UPhysicsAsset*
GetPhysicsAsset(
const FString& InPhysicsAssetName,
bool bIsStaticResource =
true)
1679 FString FOLDER_PATH_ASSET_MATERIALS = TEXT(
"Materials");
1685 static constexpr
const TCHAR* MATERIAL_NAME_ASSET_MASTER = TEXT(
"M_RapyutaAssetMaster");
1687 static constexpr
const TCHAR* MATERIAL_NAME_PROP_MASTER = TEXT(
"M_RapyutaPropMaster");
1689 static constexpr
const TCHAR* MATERIAL_NAME_PHYSICS_WHEEL = TEXT(
"PM_Wheel");
1691 static constexpr
const TCHAR* MATERIAL_NAME_TRANSLUCENCE_MASTER = TEXT(
"M_RapyutaTranslucenceMaster");
1707 FORCEINLINE UMaterialInterface*
GetMaterial(
const FString& InMaterialName)
1748 FString FOLDER_PATH_ASSET_TEXTURES = TEXT(
"Textures");
1752 static constexpr
const TCHAR* TEXTURE_NAME_WHITE_MASK = TEXT(
"T_WhiteMask");
1754 static constexpr
const TCHAR* TEXTURE_NAME_BLACK_MASK = TEXT(
"T_BlackMask");
1770 FORCEINLINE UTexture*
GetTexture(
const FString& InTextureName,
bool bIsStaticResource =
true)
1789 FString FOLDER_PATH_ASSET_DATA_TABLES = TEXT(
"DataTables");
1805 FORCEINLINE UDataTable*
GetDataTable(
const FString& InDataTableName,
bool bIsStaticResource =
true)