//创建材质入口
CreateNodeMaterials(Node, Materials, FBXUVs.UVSets, bForSkeletalMesh);
/获取世界 UPackage
World.h
for (TObjectIterator WorldIt; WorldIt; ++WorldIt)
{
UPackage* WorldPackage = WorldIt->GetOutermost();
if (!WorldPackage->HasAnyPackageFlags(PKG_PlayInEditor)
&& !WorldPackage->HasAnyFlags(RF_Transient))
{
if (WorldPackage->IsDirty())
{
// IF the package is dirty and its not a pie package, add the world package to the list of packages to save
OutDirtyPackages.Add(WorldPackage);
}
if (WorldIt->PersistentLevel && WorldIt->PersistentLevel->MapBuildData)
{
UPackage* BuiltDataPackage = WorldIt->PersistentLevel->MapBuildData->GetOutermost();
if (BuiltDataPackage->IsDirty() && BuiltDataPackage != WorldPackage)
{
OutDirtyPackages.Add(BuiltDataPackage);
}
}
}
}
//获取资源 load
UPackage* UUnrealEdEngine::GeneratePackageThumbnailsIfRequired( const TCHAR* Str, FOutputDevice& Ar, TArray& GeneratedThumbNamesList )
{
UPackage* Pkg = NULL;
if( FParse::Command( &Str, TEXT( “SavePackage” ) ) )
{
static TCHAR TempFname[MAX_EDCMD];
if( FParse::Value( Str, TEXT( “FILE=” ), TempFname, 256 ) && ParseObject( Str, TEXT( “Package=” ), Pkg, NULL ) )
{
// Update any thumbnails for objects in this package that were modified or generate
// new thumbnails for objects that don’t have any
bool bSilent = false;
FParse::Bool( Str, TEXT( "SILENT=" ), bSilent );
// Make a list of packages to query (in our case, just the package we're saving)
TArray< UPackage* > Packages;
Packages.Add( Pkg );
// Allocate a new thumbnail map if we need one
if( !Pkg->ThumbnailMap )
{
Pkg->ThumbnailMap = MakeUnique<FThumbnailMap>();
}
// OK, now query all of the browsable objects in the package we're about to save
TArray< UObject* > BrowsableObjectsInPackage;
// Load the asset tools module to get access to thumbnail tools
FAssetToolsModule& AssetToolsModule = FModuleManager::LoadModuleChecked<FAssetToolsModule>(TEXT("AssetTools"));
// NOTE: The package should really be fully loaded before we try to generate thumbnails
PackageTools::GetObjectsInPackages(
&Packages, **重点内容** // Packages to search
BrowsableObjectsInPackage ); // Out: Objects
// Check to see if any of the objects need thumbnails generated
TSet< UObject* > ObjectsMissingThumbnails;
TSet< UObject* > ObjectsWithThumbnails;
for( int32 CurObjectIndex = 0; CurObjectIndex < BrowsableObjectsInPackage.Num(); ++CurObjectIndex )
{
UObject* CurObject = BrowsableObjectsInPackage[ CurObjectIndex ];
check( CurObject != NULL );
bool bUsesGenericThumbnail = AssetToolsModule.Get().AssetUsesGenericThumbnail(FAssetData(CurObject));
// Archetypes always use a shared thumbnail
if( CurObject->HasAllFlags( RF_ArchetypeObject ) )
{
bUsesGenericThumbnail = true;
}
bool bPrintThumbnailDiagnostics = false;
GConfig->GetBool(TEXT("Thumbnails"), TEXT("Debug"), bPrintThumbnailDiagnostics, GEditorPerProjectIni);
const FObjectThumbnail* ExistingThumbnail = ThumbnailTools::FindCachedThumbnail( CurObject->GetFullName() );
if (bPrintThumbnailDiagnostics)
{
UE_LOG(LogUnrealEdSrv, Log, TEXT("Saving Thumb for %s"), *CurObject->GetFullName());
UE_LOG(LogUnrealEdSrv, Log, TEXT(" Thumb existed = %d"), (ExistingThumbnail!=NULL) ? 1: 0);
UE_LOG(LogUnrealEdSrv, Log, TEXT(" Shared Thumb = %d"), (bUsesGenericThumbnail) ? 1: 0);
}
//if it's not generatable, let's make sure it doesn't have a custom thumbnail before saving
if (!ExistingThumbnail && bUsesGenericThumbnail)
{
//let it load the custom icons from disk
// @todo CB: Batch up requests for multiple thumbnails!
TArray< FName > ObjectFullNames;
FName ObjectFullNameFName( *CurObject->GetFullName() );
ObjectFullNames.Add( ObjectFullNameFName );
// Load thumbnails
FThumbnailMap& LoadedThumbnails = Pkg->AccessThumbnailMap();
if( ThumbnailTools::ConditionallyLoadThumbnailsForObjects( ObjectFullNames, LoadedThumbnails ) )
{
//store off the names of the thumbnails that were loaded as part of a save so we can delete them after the save
GeneratedThumbNamesList.Add(ObjectFullNameFName.ToString());
if (bPrintThumbnailDiagnostics)
{
UE_LOG(LogUnrealEdSrv, Log, TEXT(" Unloaded thumb loaded successfully"));
}
ExistingThumbnail = LoadedThumbnails.Find( ObjectFullNameFName );
if (bPrintThumbnailDiagnostics)
{
UE_LOG(LogUnrealEdSrv, Log, TEXT(" Newly loaded thumb exists = %d"), (ExistingThumbnail!=NULL) ? 1: 0);
if (ExistingThumbnail)
{
UE_LOG(LogUnrealEdSrv, Log, TEXT(" Thumb created after proper version = %d"), (ExistingThumbnail->IsCreatedAfterCustomThumbsEnabled()) ? 1: 0);
}
}
if (ExistingThumbnail && !ExistingThumbnail->IsCreatedAfterCustomThumbsEnabled())
{
if (bPrintThumbnailDiagnostics)
{
UE_LOG(LogUnrealEdSrv, Log, TEXT(" WIPING OUT THUMBNAIL!!!!"));
}
//Casting away const to save memory behind the scenes
FObjectThumbnail* ThumbToClear = (FObjectThumbnail*)ExistingThumbnail;
ThumbToClear->SetImageSize(0, 0);
ThumbToClear->AccessImageData().Empty();
}
}
else
{
if (bPrintThumbnailDiagnostics)
{
UE_LOG(LogUnrealEdSrv, Log, TEXT(" Unloaded thumb does not exist"));
}
}
}
if ( bUsesGenericThumbnail )
{
// This is a generic thumbnail object, but it may have a custom thumbnail.
if( ExistingThumbnail != NULL && !ExistingThumbnail->IsEmpty() )
{
ObjectsWithThumbnails.Add( CurObject );
}
}
else
{
// This is not a generic thumbnail object, so if it is dirty or missing we will render it.
if( ExistingThumbnail != NULL && !ExistingThumbnail->IsEmpty() && !ExistingThumbnail->IsDirty() )
{
ObjectsWithThumbnails.Add( CurObject );
}
else
{
ObjectsMissingThumbnails.Add( CurObject );
}
}
}
if( BrowsableObjectsInPackage.Num() > 0 )
{
// Missing some thumbnails, so go ahead and try to generate them now
// Start a busy cursor
const FScopedBusyCursor BusyCursor;
if( !bSilent )
{
const bool bWantProgressMeter = true;
GWarn->BeginSlowTask( NSLOCTEXT("UnrealEd", "SavingPackage_GeneratingThumbnails", "Generating thumbnails..." ), bWantProgressMeter );
}
Ar.Logf( TEXT( "OBJ SavePackage: Generating thumbnails for [%i] asset(s) in package [%s] ([%i] browsable assets)..." ), ObjectsMissingThumbnails.Num(), *Pkg->GetName(), BrowsableObjectsInPackage.Num() );
for( int32 CurObjectIndex = 0; CurObjectIndex < BrowsableObjectsInPackage.Num(); ++CurObjectIndex )
{
UObject* CurObject = BrowsableObjectsInPackage[ CurObjectIndex ];
check( CurObject != NULL );
if( !bSilent )
{
GWarn->UpdateProgress( CurObjectIndex, BrowsableObjectsInPackage.Num() );
}
bool bNeedEmptyThumbnail = false;
if( ObjectsMissingThumbnails.Contains( CurObject ) && !GIsAutomationTesting )
{
// Generate a thumbnail!
FObjectThumbnail* GeneratedThumbnail = ThumbnailTools::GenerateThumbnailForObjectToSaveToDisk( CurObject );
if( GeneratedThumbnail != NULL )
{
Ar.Logf( TEXT( "OBJ SavePackage: Rendered thumbnail for [%s]" ), *CurObject->GetFullName() );
}
else
{
// Couldn't generate a thumb; perhaps this object doesn't support thumbnails?
bNeedEmptyThumbnail = true;
}
}
else if( !ObjectsWithThumbnails.Contains( CurObject ) )
{
// Even though this object uses a shared thumbnail, we'll add a "dummy thumbnail" to
// the package (zero dimension) for all browsable assets so that the Content Browser
// can quickly verify that existence of assets on the fly.
bNeedEmptyThumbnail = true;
}
// Create an empty thumbnail if we need to. All browsable assets need at least a placeholder
// thumbnail so the Content Browser can check for non-existent assets in the background
if( bNeedEmptyThumbnail )
{
UPackage* MyOutermostPackage = CastChecked< UPackage >( CurObject->GetOutermost() );
ThumbnailTools::CacheEmptyThumbnail( CurObject->GetFullName(), MyOutermostPackage );
}
}
Ar.Logf( TEXT( "OBJ SavePackage: Finished generating thumbnails for package [%s]" ), *Pkg->GetName() );
if( !bSilent )
{
GWarn->UpdateProgress( 1, 1 );
GWarn->EndSlowTask();
}
}
}
}
return Pkg;
}
//
//材质编辑面板弹出列表
MaterialEditorUtlities.cpp
void FMaterialEditorUtilities::GetMaterialExpressionActions(FGraphActionMenuBuilder& ActionMenuBuilder, bool bMaterialFunction)