void FPathContextMenu::ExecuteSCCCheckOut()
{
	// Get a list of package names in the selected paths
	TArray<FString> PackageNames;
	GetPackageNamesInSelectedPaths(PackageNames);

	TArray<UPackage*> PackagesToCheckOut;
	for ( auto PackageIt = PackageNames.CreateConstIterator(); PackageIt; ++PackageIt )
	{
		if ( FPackageName::DoesPackageExist(*PackageIt) )
		{
			// Since the file exists, create the package if it isn't loaded or just find the one that is already loaded
			// No need to load unloaded packages. It isn't needed for the checkout process
			UPackage* Package = CreatePackage(NULL, **PackageIt);
			PackagesToCheckOut.Add( CreatePackage(NULL, **PackageIt) );
		}
	}

	if ( PackagesToCheckOut.Num() > 0 )
	{
		// Update the source control status of all potentially relevant packages
		ISourceControlModule::Get().GetProvider().Execute(ISourceControlOperation::Create<FUpdateStatus>(), PackagesToCheckOut);

		// Now check them out
		FEditorFileUtils::CheckoutPackages(PackagesToCheckOut);
	}
}
UObject* USpriterProjectFactory::FactoryCreateText(UClass* InClass, UObject* InParent, FName InName, EObjectFlags Flags, UObject* Context, const TCHAR* Type, const TCHAR*& Buffer, const TCHAR* BufferEnd, FFeedbackContext* Warn)
{
	Flags |= RF_Transactional;
	FEditorDelegates::OnAssetPreImport.Broadcast(this, InClass, InParent, InName, Type);

	const FString filename = UFactory::GetCurrentFilename();
	FString sourcePath;
	FString baseFilename;
	FString extension;
	FPaths::Split(CurrentFilename, sourcePath, baseFilename, extension);

	const FString packagePath = FPackageName::GetLongPackagePath(InParent->GetOutermost()->GetPathName());

	USpriterProject* result = nullptr;
	const FString fileContent(BufferEnd - Buffer, Buffer);

	const FString sanitizedPackageName = PackageTools::SanitizePackageName(packagePath + TEXT("/") + baseFilename);
	FString defaultSuffix;
	FString assetName;
	FString packageName;
	FAssetToolsModule& assetToolsModule = FModuleManager::GetModuleChecked<FAssetToolsModule>("AssetTools");
	assetToolsModule.Get().CreateUniqueAssetName(sanitizedPackageName, defaultSuffix, packageName, assetName);

	UObject *OuterForFrame = CreatePackage(nullptr, *packageName);

	result = NewObject<USpriterProject>(OuterForFrame, *assetName, Flags);
	result->Content = FString(fileContent);

	FAssetRegistryModule::AssetCreated(result);

	FEditorDelegates::OnAssetPostImport.Broadcast(this, result);
	return result;

}
void FAssetTypeActions_EditorUtilityBlueprint::ExecuteNewDerivedBlueprint(TWeakObjectPtr<UEditorUtilityBlueprint> InObject)
{
	if (auto Object = InObject.Get())
	{
		// The menu option should ONLY be available if there is only one blueprint selected, validated by the menu creation code
		UBlueprint* TargetBP = Object;
		UClass* TargetClass = TargetBP->GeneratedClass;

		if (!FKismetEditorUtilities::CanCreateBlueprintOfClass(TargetClass))
		{
			FMessageDialog::Open(EAppMsgType::Ok, LOCTEXT("InvalidClassToMakeBlueprintFrom", "Invalid class with which to make a Blueprint."));
			return;
		}

		FString Name;
		FString PackageName;
		CreateUniqueAssetName(Object->GetOutermost()->GetName(), TEXT("_Child"), PackageName, Name);

		UPackage* Package = CreatePackage(NULL, *PackageName);
		if (ensure(Package))
		{
			// Create and init a new Blueprint
			if (UBlueprint* NewBP = FKismetEditorUtilities::CreateBlueprint(TargetClass, Package, FName(*Name), BPTYPE_Normal, UEditorUtilityBlueprint::StaticClass(), UBlueprintGeneratedClass::StaticClass()))
			{
				FAssetEditorManager::Get().OpenEditorForAsset(NewBP);

				// Notify the asset registry
				FAssetRegistryModule::AssetCreated(NewBP);

				// Mark the package dirty...
				Package->MarkPackageDirty();
			}
		}
	}
}
Beispiel #4
0
// package creation tool main function ----------------------------------------
//
void MAKEPACK_main( int argc, char **argv )
{
	// clear options of main app
	OPT_ClearOptions();

	// register local options
	OPT_RegisterStringOption( "p", "pack", Tm_SetPackageName );
	OPT_RegisterStringOption( "f", "list", Tm_SetListName );

	// exec all registered command line options
	if ( !OPT_ExecRegisteredOptions( argc, argv ) ) {
		Err_Printf( options_invalid );
		Exit( EXIT_FAILURE );
	}

	// package name is mandatory
	if ( arg_package_name[ 0 ] == 0 ) {
		Err_Printf( pack_name_missing );
		Exit( EXIT_FAILURE );
	}

	// list name is optional (use package with different extension by default)
	if ( arg_list_name[ 0 ] == 0 ) {
		strcpy( arg_list_name, arg_package_name );
		StripExtension( arg_list_name );
		strcat( arg_list_name, ".lst" );
	}

	// create package
	CreatePackage( arg_package_name, arg_list_name );

	// end of sub-application
	Exit( EXIT_SUCCESS );
}
		/**
		* Duplicates the asset
		*/
		void DuplicateAsset()
		{
			if (AssetPackage && CreatedAsset)
			{
				const FString NewObjectName = FString::Printf(TEXT("%s_Copy"), *AssetName);
				const FString NewPackageName = FString::Printf(TEXT("%s/%s"), *GetGamePath(), *NewObjectName);

				// Make sure the referenced object is deselected before duplicating it.
				GEditor->GetSelectedObjects()->Deselect(CreatedAsset);

				// Duplicate the asset
				DuplicatedPackage = CreatePackage(NULL, *NewPackageName);
				DuplicatedAsset = StaticDuplicateObject(CreatedAsset, DuplicatedPackage, *NewObjectName);

				if (DuplicatedAsset)
				{
					DuplicatedAsset->MarkPackageDirty();

					// Notify the asset registry
					FAssetRegistryModule::AssetCreated(DuplicatedAsset);

					TestStats->NumDuplicated++;
					UE_LOG(LogEditorAssetAutomationTests, Display, TEXT("Duplicated asset %s to %s (%s)"), *AssetName, *NewObjectName, *Class->GetName());
				}
				else
				{
					UE_LOG(LogEditorAssetAutomationTests, Error, TEXT("Failed to duplicate asset %s (%s)"), *AssetName, *Class->GetName());
				}
			}
		}
Beispiel #6
0
		Package *CreatePackage(PATH_SEGMENT_ITER iterSegBegin, PATH_SEGMENT_ITER iterSegEnd){
			auto ppkgCur = this;
			for(auto iter = iterSegBegin; iter != iterSegEnd; ++iter){
				ppkgCur = ppkgCur->CreatePackage(*iter);
			}
			return ppkgCur;
		}
Beispiel #7
0
		UTF16String *CreateValue(PATH_SEGMENT_ITER iterSegBegin, PATH_SEGMENT_ITER iterSegEnd){
			if(iterSegBegin == iterSegEnd){
				return nullptr;
			}
			auto iterName = iterSegEnd;
			--iterName;
			const auto ppkgParent = CreatePackage(iterSegBegin, iterName);
			return ppkgParent->CreateValue(*iterName);
		}
void FAssetTypeActions_TextureRenderTarget::ExecuteCreateStatic(TArray<TWeakObjectPtr<UTextureRenderTarget>> Objects)
{
	for (auto ObjIt = Objects.CreateConstIterator(); ObjIt; ++ObjIt)
	{
		auto Object = (*ObjIt).Get();
		if ( Object )
		{
			FString Name;
			FString PackageName;
			CreateUniqueAssetName(Object->GetOutermost()->GetName(), TEXT("_Tex"), PackageName, Name);

			UObject* NewObj = NULL;
			UTextureRenderTarget2D* TexRT = Cast<UTextureRenderTarget2D>(Object);
			UTextureRenderTargetCube* TexRTCube = Cast<UTextureRenderTargetCube>(Object);
			if( TexRTCube )
			{
				// create a static cube texture as well as its 6 faces
				NewObj = TexRTCube->ConstructTextureCube( CreatePackage(NULL,*PackageName), Name, Object->GetMaskedFlags() );
			}
			else if( TexRT )
			{
				// create a static 2d texture
				NewObj = TexRT->ConstructTexture2D( CreatePackage(NULL,*PackageName), Name, Object->GetMaskedFlags(), CTF_Default, NULL );
			}

			if( NewObj )
			{
				// package needs saving
				NewObj->MarkPackageDirty();

				// Notify the asset registry
				FAssetRegistryModule::AssetCreated(NewObj);
			}
		}
	}
}
/**
 * Convert a boot-strap registered class into a real one, add to uobject array, etc
 *
 * @param UClassStaticClass Now that it is known, fill in UClass::StaticClass() as the class
 */
void UObjectBase::DeferredRegister(UClass *UClassStaticClass,const TCHAR* PackageName,const TCHAR* InName)
{
	check(Internal::GObjInitialized);
	// Set object properties.
	Outer        = CreatePackage(NULL,PackageName);
	check(Outer);

	check(UClassStaticClass);
	check(!Class);
	Class = UClassStaticClass;

	// Add to the global object table.
	AddObject(FName(InName));

	// Make sure that objects disregarded for GC are part of root set.
	check(!GetUObjectArray().IsDisregardForGC(this) || (GetFlags() & RF_RootSet) );
}
	USoundWave* ImportSoundWave(const FString& InSoundWavePackageName, const FString& InSoundWaveAssetName, const FString& InWavFilename) const
	{
		// Find or create the package to host the sound wave
		UPackage* const SoundWavePackage = CreatePackage(nullptr, *InSoundWavePackageName);
		if (!SoundWavePackage)
		{
			FMessageLog("Import").Error(FText::Format(LOCTEXT("SoundWavePackageError", "Failed to create a sound wave package '{0}'."), FText::FromString(InSoundWavePackageName)));
			return nullptr;
		}

		// Make sure the destination package is loaded
		SoundWavePackage->FullyLoad();

		// We set the correct options in the constructor, so run the import silently
		USoundFactory* SoundWaveFactory = NewObject<USoundFactory>();
		SoundWaveFactory->SuppressImportOverwriteDialog();

		// Perform the actual import
		USoundWave* const SoundWave = ImportObject<USoundWave>(SoundWavePackage, *InSoundWaveAssetName, RF_Public | RF_Standalone, *InWavFilename, nullptr, SoundWaveFactory);
		if (!SoundWave)
		{
			FMessageLog("Import").Error(FText::Format(LOCTEXT("SoundWaveImportError", "Failed to import the sound wave asset '{0}.{1}' from '{2}'"), FText::FromString(InSoundWavePackageName), FText::FromString(InSoundWaveAssetName), FText::FromString(InWavFilename)));
			return nullptr;
		}

		// Compress to whatever formats the active target platforms want prior to saving the asset
		{
			ITargetPlatformManagerModule* TPM = GetTargetPlatformManager();
			if (TPM)
			{
				const TArray<ITargetPlatform*>& Platforms = TPM->GetActiveTargetPlatforms();
				for (ITargetPlatform* Platform : Platforms)
				{
					SoundWave->GetCompressedData(Platform->GetWaveFormat(SoundWave));
				}
			}
		}

		FAssetRegistryModule& AssetRegistry = FModuleManager::Get().LoadModuleChecked<FAssetRegistryModule>("AssetRegistry");
		AssetRegistry.AssetCreated(SoundWave);

		return SoundWave;
	}
UObject* USpriterImporterFactory::CreateNewAsset(UClass* AssetClass, const FString& TargetPath, const FString& DesiredName, EObjectFlags Flags)
{
	FAssetToolsModule& AssetToolsModule = FModuleManager::GetModuleChecked<FAssetToolsModule>("AssetTools");

	// Create a unique package name and asset name for the frame
	const FString TentativePackagePath = PackageTools::SanitizePackageName(TargetPath + TEXT("/") + DesiredName);
	FString DefaultSuffix;
	FString AssetName;
	FString PackageName;
	AssetToolsModule.Get().CreateUniqueAssetName(TentativePackagePath, DefaultSuffix, /*out*/ PackageName, /*out*/ AssetName);

	// Create a package for the asset
	UObject* OuterForAsset = CreatePackage(nullptr, *PackageName);

	// Create a frame in the package
	UObject* NewAsset = NewObject<UObject>(OuterForAsset, AssetClass, *AssetName, Flags);
	FAssetRegistryModule::AssetCreated(NewAsset);

	NewAsset->Modify();
	return NewAsset;
}
UPackage* FHierarchicalLODUtilities::CreateOrRetrieveLevelHLODPackage(ULevel* InLevel)
{
	checkf(InLevel != nullptr, TEXT("Invalid Level supplied"));

	UPackage* HLODPackage = nullptr;
	UPackage* LevelOuterMost = InLevel->GetOutermost();

	const FString PathName = FPackageName::GetLongPackagePath(LevelOuterMost->GetPathName());
	const FString BaseName = FPackageName::GetShortName(LevelOuterMost->GetPathName());
	const FString HLODLevelPackageName = FString::Printf(TEXT("%s/HLOD/%s_HLOD"), *PathName, *BaseName);

	HLODPackage = CreatePackage(NULL, *HLODLevelPackageName);
	HLODPackage->FullyLoad();
	HLODPackage->Modify();
	
	// Target level filename
	const FString HLODLevelFileName = FPackageName::LongPackageNameToFilename(HLODLevelPackageName);
	// This is a hack to avoid save file dialog when we will be saving HLOD map package
	HLODPackage->FileName = FName(*HLODLevelFileName);

	return HLODPackage;	
}
	/**
	* Imports an object using a given factory
	*
	* @param ImportFactory - The factory to use to import the object
	* @param ObjectName - The name of the object to create
	* @param PackagePath - The full path of the package file to create
	* @param ImportPath - The path to the object to import
	*/
	UObject* ImportAssetUsingFactory(UFactory* ImportFactory, const FString& ObjectName, const FString& PackagePath, const FString& ImportPath)
	{
		UObject* ImportedAsset = NULL;

		UPackage* Pkg = CreatePackage(NULL, *PackagePath);
		if (Pkg)
		{
			// Make sure the destination package is loaded
			Pkg->FullyLoad();

			UClass* ImportAssetType = ImportFactory->ResolveSupportedClass();
			bool bDummy = false;

			//If we are a texture factory suppress some warning dialog that we don't want
			if (ImportFactory->IsA(UTextureFactory::StaticClass()))
			{
				UTextureFactory::SuppressImportOverwriteDialog();
			}

			ImportedAsset = UFactory::StaticImportObject(ImportAssetType, Pkg, FName(*ObjectName), RF_Public | RF_Standalone, bDummy, *ImportPath, NULL, ImportFactory, NULL, GWarn, 0);

			if (ImportedAsset)
			{
				UE_LOG(LogAutomationEditorCommon, Display, TEXT("Imported %s"), *ImportPath);
			}
			else
			{
				UE_LOG(LogAutomationEditorCommon, Error, TEXT("Failed to import asset using factory %s!"), *ImportFactory->GetName());
			}
		}
		else
		{
			UE_LOG(LogAutomationEditorCommon, Error, TEXT("Failed to create a package!"));
		}

		return ImportedAsset;
	}
		/**
		* Creates the new item
		*/
		void CreateAsset()
		{
			const FString PackageName = AssetPath + TEXT("/") + AssetName;
			AssetPackage = CreatePackage(NULL, *PackageName);
			EObjectFlags Flags = RF_Public | RF_Standalone;

			CreatedAsset = Factory->FactoryCreateNew(Class, AssetPackage, FName(*AssetName), Flags, NULL, GWarn);

			if (CreatedAsset)
			{
				// Notify the asset registry
				FAssetRegistryModule::AssetCreated(CreatedAsset);

				// Mark the package dirty...
				AssetPackage->MarkPackageDirty();

				TestStats->NumCreated++;
				UE_LOG(LogEditorAssetAutomationTests, Display, TEXT("Created asset %s (%s)"), *AssetName, *Class->GetName());
			}
			else
			{
				UE_LOG(LogEditorAssetAutomationTests, Error, TEXT("Unable to create asset of type %s"), *Class->GetName());
			}
		}
Beispiel #15
0
//
// Find or create the linker for a package.
//
ULinkerLoad* GetPackageLinker
(
	UPackage*		InOuter,
	const TCHAR*	InLongPackageName,
	uint32			LoadFlags,
	UPackageMap*	Sandbox,
	FGuid*			CompatibleGuid
)
{
	// See if there is already a linker for this package.
	ULinkerLoad* Result = ULinkerLoad::FindExistingLinkerForPackage(InOuter);

	// Try to load the linker.
	// See if the linker is already loaded.
	if( Result )
	{
		return Result;
	}

	FString NewFilename;
	if( !InLongPackageName )
	{
		// Resolve filename from package name.
		if( !InOuter )
		{
			// try to recover from this instead of throwing, it seems recoverable just by doing this
			FText ErrorText(LOCTEXT("PackageResolveFailed", "Can't resolve asset name"));
			LogGetPackageLinkerError(Result, InLongPackageName, ErrorText, ErrorText, InOuter, LoadFlags);
			return nullptr;
		}

		if( !FPackageName::DoesPackageExist(InOuter->GetName(), CompatibleGuid, &NewFilename) )
		{
			// Compiled in packages have no linker and this is ok
			if (!(LoadFlags & LOAD_AllowDll) && !(InOuter->PackageFlags & PKG_CompiledIn))
			{
				FFormatNamedArguments Arguments;
				Arguments.Add(TEXT("AssetName"), FText::FromString(InOuter->GetName()));
				Arguments.Add(TEXT("PackageName"), FText::FromString(GSerializedPackageLinker ? *(GSerializedPackageLinker->Filename) : TEXT("NULL")));
				LogGetPackageLinkerError(Result, GSerializedPackageLinker ? *GSerializedPackageLinker->Filename : nullptr,
											FText::Format(LOCTEXT("PackageNotFound", "Can't find file for asset '{AssetName}' while loading {PackageName}."), Arguments),
											LOCTEXT("PackageNotFoundShort", "Can't find file for asset."),
											InOuter,
											LoadFlags);
			}

			return nullptr;
		}
	}
	else
	{
		FString PackageName(InLongPackageName);
		if (!FPackageName::TryConvertFilenameToLongPackageName(InLongPackageName, PackageName))
		{
			// try to recover from this instead of throwing, it seems recoverable just by doing this
			FText ErrorText(LOCTEXT("PackageResolveFailed", "Can't resolve asset name"));
			LogGetPackageLinkerError(Result, InLongPackageName, ErrorText, ErrorText, InOuter, LoadFlags);
			return nullptr;
		}

		if (UPackage* ExistingPackage = FindObject<UPackage>(nullptr, *PackageName))
		{
			if (!ExistingPackage->GetOuter() && (ExistingPackage->PackageFlags & PKG_CompiledIn))
			{
				// this is a compiled in package and so it has no linker and this is ok
				return nullptr;
			}
		}

		// Verify that the file exists.
		if( !FPackageName::DoesPackageExist( PackageName, CompatibleGuid, &NewFilename ) )
		{
			FFormatNamedArguments Arguments;
			Arguments.Add(TEXT("Filename"), FText::FromString(InLongPackageName));

			// try to recover from this instead of throwing, it seems recoverable just by doing this
			LogGetPackageLinkerError(Result, InLongPackageName, FText::Format(LOCTEXT("FileNotFound", "Can't find file '{Filename}'"), Arguments), LOCTEXT("FileNotFoundShort", "Can't find file"), InOuter, LoadFlags);
			return nullptr;
		}

		// Create the package with the provided long package name.
		UPackage* FilenamePkg = CreatePackage(nullptr, *PackageName);
		if (LoadFlags & LOAD_PackageForPIE)
		{
			FilenamePkg->PackageFlags |= PKG_PlayInEditor;
		}

		// If no package specified, use package from file.
		if (!InOuter)
		{
			if( !FilenamePkg )
			{
				FFormatNamedArguments Arguments;
				Arguments.Add(TEXT("Filename"), FText::FromString(InLongPackageName));
				LogGetPackageLinkerError(Result, InLongPackageName, FText::Format(LOCTEXT("FilenameToPackage", "Can't convert filename '{Filename}' to asset name"), Arguments), LOCTEXT("FilenameToPackageShort", "Can't convert filename to asset name"), InOuter, LoadFlags);
				return nullptr;
			}
			InOuter = FilenamePkg;
			Result = ULinkerLoad::FindExistingLinkerForPackage(InOuter);
		}
		else if (InOuter != FilenamePkg) //!!should be tested and validated in new UnrealEd
		{
			// Loading a new file into an existing package, so reset the loader.
			//UE_LOG(LogLinker, Log,  TEXT("New File, Existing Package (%s, %s)"), *InOuter->GetFullName(), *FilenamePkg->GetFullName() );
			ResetLoaders( InOuter );
		}
	}

#if 0
	// Make sure the package is accessible in the sandbox.
	if( Sandbox && !Sandbox->SupportsPackage(InOuter) )
	{
		FFormatNamedArguments Arguments;
		Arguments.Add(TEXT("AssetName"), FText::FromString(InOuter->GetName()));

		LogGetPackageLinkerError(Result, InLongPackageName, FText::Format(LOCTEXT("Sandbox", "Asset '{AssetName}' is not accessible in this sandbox"), Arguments), LOCTEXT("SandboxShort", "Asset is not accessible in this sandbox"), InOuter, LoadFlags);
		return nullptr;
	}
#endif

	// Create new linker.
	if( !Result )
	{
		check(IsLoading());

		// we will already have found the filename above
		check(NewFilename.Len() > 0);

		Result = ULinkerLoad::CreateLinker( InOuter, *NewFilename, LoadFlags );
	}

	// Verify compatibility.
	if( CompatibleGuid && Result->Summary.Guid!=*CompatibleGuid )
	{
		FFormatNamedArguments Arguments;
		Arguments.Add(TEXT("AssetName"), FText::FromString(InOuter->GetName()));

		// This should never fire, because FindPackageFile should never return an incompatible file
		LogGetPackageLinkerError(Result, InLongPackageName, FText::Format(LOCTEXT("PackageVersion", "Asset '{AssetName}' version mismatch"), Arguments), LOCTEXT("PackageVersionShort", "Asset version mismatch"), InOuter, LoadFlags);
		return nullptr;
	}

	return Result;
}
	/**
	 * A utility function for spawning an empty temporary package, meant for test purposes.
	 * 
	 * @param  Name		A suggested string name to get the package (NOTE: it will further be decorated with things like "Temp", etc.) 
	 * @return A newly created package for throwaway use.
	 */
	static UPackage* CreateTempPackage(FString Name)
	{
		FString TempPackageName = FString::Printf(TEXT("/Temp/BpAutomation-%u-%s"), GenTempUid(), *Name);
		return CreatePackage(NULL, *TempPackageName);
	}
bool FPaperJsonSpriteSheetImporter::PerformImport(const FString& LongPackagePath, EObjectFlags Flags, UPaperSpriteSheet* SpriteSheet)
{
	FAssetToolsModule& AssetToolsModule = FModuleManager::GetModuleChecked<FAssetToolsModule>("AssetTools");

	GWarn->BeginSlowTask(NSLOCTEXT("Paper2D", "PaperJsonImporterFactory_ImportingSprites", "Importing Sprite Frame"), true, true);
	for (int32 FrameIndex = 0; FrameIndex < Frames.Num(); ++FrameIndex)
	{
		GWarn->StatusUpdate(FrameIndex, Frames.Num(), NSLOCTEXT("Paper2D", "PaperJsonImporterFactory_ImportingSprites", "Importing Sprite Frames"));

		// Check for user canceling the import
		if (GWarn->ReceivedUserCancel())
		{
			break;
		}

		const FSpriteFrame& Frame = Frames[FrameIndex];

		// Create a package for the frame
		const FString TargetSubPath = LongPackagePath + TEXT("/Frames");

		UObject* OuterForFrame = nullptr; // @TODO: Use this if we don't want them to be individual assets - Flipbook;

		// Create a frame in the package
		UPaperSprite* TargetSprite = nullptr;
		
		if (bIsReimporting)
		{
			TargetSprite = FindExistingSprite(Frame.FrameName.ToString());
		}
		
		if (TargetSprite == nullptr)
		{
			const FString SanitizedFrameName = ObjectTools::SanitizeObjectName(Frame.FrameName.ToString());
			const FString TentativePackagePath = PackageTools::SanitizePackageName(TargetSubPath + TEXT("/") + SanitizedFrameName);
			FString DefaultSuffix;
			FString AssetName;
			FString PackageName;
			AssetToolsModule.Get().CreateUniqueAssetName(TentativePackagePath, DefaultSuffix, /*out*/ PackageName, /*out*/ AssetName);

			// Create a unique package name and asset name for the frame
			if (OuterForFrame == nullptr)
			{
				// Create a package for the frame
				OuterForFrame = CreatePackage(nullptr, *PackageName);
			}

			// Create the asset
			TargetSprite = NewObject<UPaperSprite>(OuterForFrame, *AssetName, Flags);
			FAssetRegistryModule::AssetCreated(TargetSprite);
		}

		TargetSprite->Modify();
		FSpriteAssetInitParameters SpriteInitParams;
		SpriteInitParams.Texture = ImageTexture;

		if (NormalMapTexture != nullptr)
		{
			// Put the normal map into the additional textures array and ask for a lit material instead of unlit
			SpriteInitParams.AdditionalTextures.Add(NormalMapTexture);
		}

		SpriteInitParams.Offset = Frame.SpritePosInSheet;
		SpriteInitParams.Dimension = Frame.SpriteSizeInSheet;

		GetDefault<UPaperImporterSettings>()->ApplySettingsForSpriteInit(/*inout*/ SpriteInitParams, (NormalMapTexture != nullptr) ? ESpriteInitMaterialLightingMode::ForceLit : ESpriteInitMaterialLightingMode::Automatic);

		TargetSprite->InitializeSprite(SpriteInitParams);

		if (Frame.bRotated)
		{
			TargetSprite->SetRotated(true);
		}

		if (Frame.bTrimmed)
		{
			TargetSprite->SetTrim(Frame.bTrimmed, Frame.SpriteSourcePos, Frame.ImageSourceSize);
		}

		// Set up pivot on object based on Texture Packer json
		ESpritePivotMode::Type PivotType = GetBestPivotType(Frame.Pivot);
		FVector2D TextureSpacePivotPoint = FVector2D::ZeroVector;
		if (PivotType == ESpritePivotMode::Custom)
		{
			TextureSpacePivotPoint.X = Frame.SpritePosInSheet.X - Frame.SpriteSourcePos.X + Frame.ImageSourceSize.X * Frame.Pivot.X;
			TextureSpacePivotPoint.Y = Frame.SpritePosInSheet.Y - Frame.SpriteSourcePos.Y + Frame.ImageSourceSize.Y * Frame.Pivot.Y;
		}
		TargetSprite->SetPivotMode(PivotType, TextureSpacePivotPoint);

		// Create the entry in the animation
		SpriteSheet->SpriteNames.Add(Frame.FrameName.ToString());
		SpriteSheet->Sprites.Add(TargetSprite);
		
		TargetSprite->PostEditChange();
	}

	SpriteSheet->TextureName = ImageName;
	SpriteSheet->Texture = ImageTexture;
	SpriteSheet->NormalMapTextureName = ComputedNormalMapName;
	SpriteSheet->NormalMapTexture = NormalMapTexture;

	GWarn->EndSlowTask();
	return true;
}
//------------------------------------------------------------------------------
void FBlueprintNativeCodeGenUtils::GenerateCppCode(UObject* Obj, TSharedPtr<FString> OutHeaderSource, TSharedPtr<FString> OutCppSource)
{
	auto UDEnum = Cast<UUserDefinedEnum>(Obj);
	auto UDStruct = Cast<UUserDefinedStruct>(Obj);
	auto BPGC = Cast<UClass>(Obj);
	auto InBlueprintObj = BPGC ? Cast<UBlueprint>(BPGC->ClassGeneratedBy) : Cast<UBlueprint>(Obj);

	OutHeaderSource->Empty();
	OutCppSource->Empty();

	if (InBlueprintObj)
	{
		if (EBlueprintStatus::BS_Error == InBlueprintObj->Status)
		{
			UE_LOG(LogBlueprintCodeGen, Error, TEXT("Cannot convert \"%s\". It has errors."), *InBlueprintObj->GetPathName());
			return;
		}

		check(InBlueprintObj->GetOutermost() != GetTransientPackage());
		if (!ensureMsgf(InBlueprintObj->GeneratedClass, TEXT("Invalid generated class for %s"), *InBlueprintObj->GetName()))
		{
			return;
		}
		check(OutHeaderSource.IsValid());
		check(OutCppSource.IsValid());

		FDisableGatheringDataOnScope DisableFib;

		const FString TempPackageName = FString::Printf(TEXT("/Temp/__TEMP_BP__/%s"), *InBlueprintObj->GetName());
		UPackage* TempPackage = CreatePackage(nullptr, *TempPackageName);
		check(TempPackage);
		ON_SCOPE_EXIT
		{
			TempPackage->RemoveFromRoot();
			TempPackage->MarkPendingKill();
		};

		UBlueprint* DuplicateBP = nullptr;
		{
			FBlueprintDuplicationScopeFlags BPDuplicationFlags(
				FBlueprintDuplicationScopeFlags::NoExtraCompilation | FBlueprintDuplicationScopeFlags::TheSameTimelineGuid);
			DuplicateBP = DuplicateObject<UBlueprint>(InBlueprintObj, TempPackage, *InBlueprintObj->GetName());
		}
		ensure((nullptr != DuplicateBP->GeneratedClass) && (InBlueprintObj->GeneratedClass != DuplicateBP->GeneratedClass));
		ON_SCOPE_EXIT
		{
			DuplicateBP->RemoveFromRoot();
			DuplicateBP->MarkPendingKill();
		};

		IBlueprintCompilerCppBackendModule& CodeGenBackend = (IBlueprintCompilerCppBackendModule&)IBlueprintCompilerCppBackendModule::Get();
		CodeGenBackend.GetOriginalClassMap().Add(*DuplicateBP->GeneratedClass, *InBlueprintObj->GeneratedClass);

		{
			TSharedPtr<FBlueprintCompileReinstancer> Reinstancer = FBlueprintCompileReinstancer::Create(DuplicateBP->GeneratedClass);
			IKismetCompilerInterface& Compiler = FModuleManager::LoadModuleChecked<IKismetCompilerInterface>(KISMET_COMPILER_MODULENAME);
			TGuardValue<bool> GuardTemplateNameFlag(GCompilingBlueprint, true);
			FCompilerResultsLog Results;

			FKismetCompilerOptions CompileOptions;
			CompileOptions.CompileType = EKismetCompileType::Cpp;
			CompileOptions.OutCppSourceCode = OutCppSource;
			CompileOptions.OutHeaderSourceCode = OutHeaderSource;

			Compiler.CompileBlueprint(DuplicateBP, CompileOptions, Results);

			Compiler.RemoveBlueprintGeneratedClasses(DuplicateBP);
		}

		if (EBlueprintType::BPTYPE_Interface == DuplicateBP->BlueprintType && OutCppSource.IsValid())
		{
			OutCppSource->Empty(); // ugly temp hack
		}
	}
	else if ((UDEnum || UDStruct) && OutHeaderSource.IsValid())
/**
* Add to the animation set, the animations contained within the FBX document, for the given skeleton
*/
UAnimSequence * UnFbx::FFbxImporter::ImportAnimations(USkeleton* Skeleton, UObject* Outer, TArray<FbxNode*>& SortedLinks, const FString& Name, UFbxAnimSequenceImportData* TemplateImportData, TArray<FbxNode*>& NodeArray)
{
	// we need skeleton to create animsequence
	if (Skeleton == NULL)
	{
		return NULL;
	}

	int32 ValidTakeCount = 0;
	if (IsValidAnimationData(SortedLinks, NodeArray, ValidTakeCount) == false)
	{
		AddTokenizedErrorMessage(FTokenizedMessage::Create(EMessageSeverity::Warning, LOCTEXT("FBXImport_InvalidAnimationData", "This does not contain any valid animation takes.")), FFbxErrors::Animation_InvalidData);
		return NULL;
	}

	UAnimSequence* LastCreatedAnim = NULL;

	int32 ResampleRate = DEFAULT_SAMPLERATE;
	if ( ImportOptions->bResample )
	{
		// For FBX data, "Frame Rate" is just the speed at which the animation is played back.  It can change
		// arbitrarily, and the underlying data can stay the same.  What we really want here is the Sampling Rate,
		// ie: the number of animation keys per second.  These are the individual animation curve keys
		// on the FBX nodes of the skeleton.  So we loop through the nodes of the skeleton and find the maximum number 
		// of keys that any node has, then divide this by the total length (in seconds) of the animation to find the 
		// sampling rate of this set of data 

		// we want the maximum resample rate, so that we don't lose any precision of fast anims,
		// and don't mind creating lerped frames for slow anims
		int32 MaxStackResampleRate = GetMaxSampleRate(SortedLinks, NodeArray);

		if(MaxStackResampleRate != 0)
		{
			ResampleRate = MaxStackResampleRate;
		}

	}

	int32 AnimStackCount = Scene->GetSrcObjectCount<FbxAnimStack>();
	for( int32 AnimStackIndex = 0; AnimStackIndex < AnimStackCount; AnimStackIndex++ )
	{
		FbxAnimStack* CurAnimStack = Scene->GetSrcObject<FbxAnimStack>(AnimStackIndex);

		FbxTimeSpan AnimTimeSpan = GetAnimationTimeSpan(SortedLinks[0], CurAnimStack);
		bool bValidAnimStack = ValidateAnimStack(SortedLinks, NodeArray, CurAnimStack, ResampleRate, ImportOptions->bImportMorph, AnimTimeSpan);
		// no animation
		if (!bValidAnimStack)
		{
			continue;
		}
		
		FString SequenceName = Name;

		if (ValidTakeCount > 1)
		{
			SequenceName += "_";
			SequenceName += UTF8_TO_TCHAR(CurAnimStack->GetName());
		}

		// See if this sequence already exists.
		SequenceName = ObjectTools::SanitizeObjectName(SequenceName);

		FString 	ParentPath = FString::Printf(TEXT("%s/%s"), *FPackageName::GetLongPackagePath(*Outer->GetName()), *SequenceName);
		UObject* 	ParentPackage = CreatePackage(NULL, *ParentPath);
		UObject* Object = LoadObject<UObject>(ParentPackage, *SequenceName, NULL, LOAD_None, NULL);
		UAnimSequence * DestSeq = Cast<UAnimSequence>(Object);
		// if object with same name exists, warn user
		if (Object && !DestSeq)
		{
			AddTokenizedErrorMessage(FTokenizedMessage::Create(EMessageSeverity::Error, LOCTEXT("Error_AssetExist", "Asset with same name exists. Can't overwrite another asset")), FFbxErrors::Generic_SameNameAssetExists);
			continue; // Move on to next sequence...
		}

		// If not, create new one now.
		if(!DestSeq)
		{
			DestSeq = NewObject<UAnimSequence>(ParentPackage, *SequenceName, RF_Public | RF_Standalone);
	
			// Notify the asset registry
			FAssetRegistryModule::AssetCreated(DestSeq);
		}
		else
		{
			DestSeq->RecycleAnimSequence();
		}

		DestSeq->SetSkeleton(Skeleton);

		// since to know full path, reimport will need to do same
		UFbxAnimSequenceImportData* ImportData = UFbxAnimSequenceImportData::GetImportDataForAnimSequence(DestSeq, TemplateImportData);
		ImportData->Update(UFactory::CurrentFilename);

		ImportAnimation(Skeleton, DestSeq, Name, SortedLinks, NodeArray, CurAnimStack, ResampleRate, AnimTimeSpan);

		LastCreatedAnim = DestSeq;
	}

	return LastCreatedAnim;
}
void FContentDirectoryMonitor::ProcessAdditions(const DirectoryWatcher::FTimeLimit& TimeLimit, TArray<UPackage*>& OutPackagesToSave, const TMap<FString, TArray<UFactory*>>& InFactoriesByExtension, FReimportFeedbackContext& Context)
{
	bool bCancelled = false;
	for (int32 Index = 0; Index < AddedFiles.Num(); ++Index)
	{
		auto& Addition = AddedFiles[Index];

		if (bCancelled)
		{
			// Just update the cache immediately if the user cancelled
			Cache.CompleteTransaction(MoveTemp(Addition));
			Context.MainTask->EnterProgressFrame();
			continue;
		}

		const FString FullFilename = Cache.GetDirectory() + Addition.Filename.Get();

		FString NewAssetName = ObjectTools::SanitizeObjectName(FPaths::GetBaseFilename(FullFilename));
		FString PackagePath = PackageTools::SanitizePackageName(MountedContentPath / FPaths::GetPath(Addition.Filename.Get()) / NewAssetName);

		// Don't create assets for new files if assets already exist for the filename
		auto ExistingReferences = Utils::FindAssetsPertainingToFile(*Registry, FullFilename);
		if (ExistingReferences.Num() != 0)
		{
			// Treat this as a modified file that will attempt to reimport it (if applicable). We don't update the progress for this item until it is processed by ProcessModifications
			ModifiedFiles.Add(MoveTemp(Addition));
			continue;
		}

		// Move the progress on now that we know we're going to process the file
		Context.MainTask->EnterProgressFrame();

		if (FPackageName::DoesPackageExist(*PackagePath))
		{
			// Package already exists, so try and import over the top of it, if it doesn't already have a source file path
			TArray<FAssetData> Assets;
			if (Registry->GetAssetsByPackageName(*PackagePath, Assets) && Assets.Num() == 1)
			{
				if (UObject* ExistingAsset = Assets[0].GetAsset())
				{
					// We're only eligible for reimport if the existing asset doesn't reference a source file already
					const bool bEligibleForReimport = !Utils::ExtractSourceFilePaths(ExistingAsset).ContainsByPredicate([&](const FString& In){
						return !In.IsEmpty() && In == FullFilename;
					});

					if (bEligibleForReimport)
					{
						ReimportAssetWithNewSource(ExistingAsset, FullFilename, OutPackagesToSave, Context);
					}
				}
			}
		}
		else
		{
			UPackage* NewPackage = CreatePackage(nullptr, *PackagePath);
			if ( !ensure(NewPackage) )
			{
				Context.AddMessage(EMessageSeverity::Error, FText::Format(LOCTEXT("Error_FailedToCreateAsset", "Failed to create new asset ({0}) for file ({1})."), FText::FromString(NewAssetName), FText::FromString(FullFilename)));
			}
			else
			{
				Context.AddMessage(EMessageSeverity::Info, FText::Format(LOCTEXT("Info_CreatingNewAsset", "Importing new asset {0}."), FText::FromString(PackagePath)));

				// Make sure the destination package is loaded
				NewPackage->FullyLoad();
				
				UObject* NewAsset = nullptr;

				// Find a relevant factory for this file
				// @todo import: gmp: show dialog in case of multiple matching factories
				const FString Ext = FPaths::GetExtension(Addition.Filename.Get(), false);
				auto* Factories = InFactoriesByExtension.Find(Ext);
				if (Factories && Factories->Num() != 0)
				{
					// Prefer a factory if it explicitly can import. UFactory::FactoryCanImport returns false by default, even if the factory supports the extension, so we can't use it directly.
					UFactory* const * PreferredFactory = Factories->FindByPredicate([&](UFactory* F){ return F->FactoryCanImport(FullFilename); });
					if (PreferredFactory)
					{
						NewAsset = AttemptImport((*PreferredFactory)->GetClass(), NewPackage, *NewAssetName, bCancelled, FullFilename);
					}
					// If there was no preferred factory, just try them all until one succeeds
					else for (UFactory* Factory : *Factories)
					{
						NewAsset = AttemptImport(Factory->GetClass(), NewPackage, *NewAssetName, bCancelled, FullFilename);

						if (bCancelled || NewAsset)
						{
							break;
						}
					}
				}

				// If we didn't create an asset, unload and delete the package we just created
				if (!NewAsset)
				{
					TArray<UPackage*> Packages;
					Packages.Add(NewPackage);

					TGuardValue<bool> SuppressSlowTaskMessages(Context.bSuppressSlowTaskMessages, true);

					FText ErrorMessage;
					if (!PackageTools::UnloadPackages(Packages, ErrorMessage))
					{
						Context.AddMessage(EMessageSeverity::Error, FText::Format(LOCTEXT("Error_UnloadingPackage", "There was an error unloading a package: {0}."), ErrorMessage));
					}

					// Just add the message to the message log rather than add it to the UI
					// Factories may opt not to import the file, so we let them report errors if they do
					Context.GetMessageLog().Message(EMessageSeverity::Info, FText::Format(LOCTEXT("Info_FailedToImportAsset", "Failed to import file {0}."), FText::FromString(FullFilename)));
				}
				else if (!bCancelled)
				{
					FAssetRegistryModule::AssetCreated(NewAsset);
					GEditor->BroadcastObjectReimported(NewAsset);

					OutPackagesToSave.Add(NewPackage);
				}

				// Refresh the supported class.  Some factories (e.g. FBX) only resolve their type after reading the file
				// ImportAssetType = Factory->ResolveSupportedClass();
				// @todo: analytics?
			}
		}

		// Let the cache know that we've dealt with this change (it will be imported immediately)
		Cache.CompleteTransaction(MoveTemp(Addition));

		if (!bCancelled && TimeLimit.Exceeded())
		{
			// Remove the ones we've processed
			AddedFiles.RemoveAt(0, Index + 1);
			return;
		}
	}

	AddedFiles.Empty();
}
Beispiel #21
0
		Package *CreatePackage(std::initializer_list<const wchar_t *> ilPath){
			return CreatePackage(ilPath.begin(), ilPath.end());
		}
FReply FCurveColorCustomization::OnCreateButtonClicked()
{
	if (CurveWidget.IsValid())
	{
		FString DefaultAsset = FPackageName::GetLongPackagePath(Owner->GetOutermost()->GetName()) + TEXT("/") + Owner->GetName() + TEXT("_ExternalCurve");

		TSharedRef<SDlgPickAssetPath> NewCurveDlg =
			SNew(SDlgPickAssetPath)
			.Title(LOCTEXT("NewCurveDialogTitle", "Choose Location for External Curve Asset"))
			.DefaultAssetPath(FText::FromString(DefaultAsset));

		if (NewCurveDlg->ShowModal() != EAppReturnType::Cancel)
		{
			FString Package(NewCurveDlg->GetFullAssetPath().ToString());
			FString Name(NewCurveDlg->GetAssetName().ToString());
			FString Group(TEXT(""));

			// Find (or create!) the desired package for this object
			UPackage* Pkg = CreatePackage(NULL, *Package);
			UPackage* OutermostPkg = Pkg->GetOutermost();

			TArray<UPackage*> TopLevelPackages;
			TopLevelPackages.Add( OutermostPkg );
			if (!PackageTools::HandleFullyLoadingPackages(TopLevelPackages, LOCTEXT("CreateANewObject", "Create a new object")))
			{
				// User aborted.
				return FReply::Handled();
			}

			if (!PromptUserIfExistingObject(Name, Package, Group, Pkg))
			{
				return FReply::Handled();
			}

			// PromptUserIfExistingObject may have GCed and recreated our outermost package - re-acquire it here.
			OutermostPkg = Pkg->GetOutermost();

			// Create a new asset and set it as the external curve
			FName AssetName = *Name;
			UCurveLinearColor* NewCurve = Cast<UCurveLinearColor>(CurveWidget->CreateCurveObject(UCurveLinearColor::StaticClass(), Pkg, AssetName));
			if( NewCurve )
			{
				// run through points of editor data and add to external curve
				for (int32 Index = 0; Index < 4; Index++)
				{
					CopyCurveData(&RuntimeCurve->ColorCurves[Index], &NewCurve->FloatCurves[Index]);
				}

				// Set the new object as the sole selection.
				USelection* SelectionSet = GEditor->GetSelectedObjects();
				SelectionSet->DeselectAll();
				SelectionSet->Select( NewCurve );

				// Notify the asset registry
				FAssetRegistryModule::AssetCreated(NewCurve);

				// Mark the package dirty...
				OutermostPkg->MarkPackageDirty();

				// Make sure expected type of pointer passed to SetValue, so that it's not interpreted as a bool
				ExternalCurveHandle->SetValue(NewCurve);
			}
		}
	}
	return FReply::Handled();
}
Beispiel #23
0
/* ==== Make Dir ====

   vraci ERR_FS_NO_ERROR
	 ERR_DIRREC_NO_DIR
	 ERR_DIRREC_ALREADY_EXISTS
	 ERR_CANNOT_CREATE_DIR
	 + ostatni
*/
word fs_mkdir(byte *path)
{
  byte		buffer[255],*dir;
  byte  	sector2[1024], *DataTag = sector2+512;
  MNODE 	*MemNode;
  word		CallResult,GetNumber,packID;
  dword 	logical;
  NODE		*rnode = (NODE *)sector2;
  FileRecord	*frecord;
  TaskUArea	*Task;

  SyscallActive = 1;
  if (!*path)
  {
    SyscallActive = 0;
    return ERR_CANNOT_CREATE_DIR;
  }
  #ifdef DEBUG
    printf ("\nCreating new directory node");
  #endif


  Task = GetCurrentTaskUArea();

  // alokuju, protoze nemuzu uzivateli vratit zmeneny retezec a delka
  // cesty muze byt obecne libovolne dlouha
  dir = new byte [strlen(path)+1];
  strcpy(dir,path);

  // zjisti umisteni adresare, kde se bude novy adresar vytvaret
  CutLastPathPart (dir,buffer);
  CallResult = NAMEN( dir, MemNode, FPACK_ADD);
  if ( CallResult != ERR_FS_NO_ERROR)
  {
    delete [] dir;
    SyscallActive = 0;
    return CallResult;
  }
  if (!(MemNode->Type & NODE_TYPE_DIRECTORY))
  {
    MemNode->Locked.Release();
    ActiveNodes->Release(MemNode);
    delete [] dir;
    SyscallActive = 0;
    return ERR_NOT_DIRECTORY;
  }

  CallResult = SearchDirByName(MemNode, buffer, logical, FPACK_ADD, 0);
  if (CallResult != ERR_DIRREC_NOT_FOUND)
  {
    MemNode->Locked.Release();
    ActiveNodes->Release(MemNode);
    delete [] dir;
    SyscallActive = 0;
    if (CallResult == ERR_FS_NO_ERROR) return ERR_DIRREC_ALREADY_EXISTS;
				  else return CallResult;
  }

  // naalokuj sektor pro adresarova data
  CreatePackage(MemNode->Device,  MemNode->Partition, packID );
  CallResult = CacheManAllocateSector(MemNode->Device,  MemNode->Partition,
				      MemNode->logical, 2,
				      logical,		GetNumber,
				      packID,		FPACK_ADD);
  if ( CallResult != ERR_FS_NO_ERROR) goto mkdirbad;
  #ifdef DEBUG
    printf ("\n Sectors <%d,%d,%lu> allocated for node, <%d,%d,%lu> for data",
	    MemNode->Device, MemNode->Partition, logical,
	    MemNode->Device, MemNode->Partition, logical+1);
  #endif


  memset(sector2,0,1024);

  memcpy(rnode->MagicWord, DirMagicWord, 8);
  memcpy(rnode->MagicWordII, DirMagicWord, 8);

  rnode->OwnerID = Task->ownerID;
  rnode->GroupID = Task->groupID;
  rnode->Rights  = 0xffff;	// not implemented yet
  rnode->Type    = NODE_TYPE_DIRECTORY;
  rnode->Size    = 512;
  rnode->Links   = 1;

  rnode->DirectBlock[0] = logical+1;

  GlobalTime.Get(rnode->FileAccessed);
  rnode->FileModified = rnode->FileAccessed;
  rnode->NODEAccessed = rnode->FileAccessed;
  rnode->NODEModified = rnode->FileAccessed;

  // init data block
  frecord = (FileRecord *)DataTag;

  frecord->Node = logical;
  frecord->NextRecord = 8;
  frecord->NameLength = 1;
  frecord->FileName[0] = '.';

  DataTag += frecord->NextRecord;
  frecord = (FileRecord *)DataTag;
  frecord->Node = MemNode->logical;
  frecord->NextRecord = 0;
  frecord->NameLength = 2;
  frecord->FileName[0] = '.';
  frecord->FileName[1] = '.';

  CallResult = AddDirectoryEntry( MemNode, logical, FPACK_ADD, buffer, 0);
  if ( CallResult != ERR_FS_NO_ERROR)
  { // odalokuju sektor
    CallResult = CacheManFreeSector( MemNode->Device,  MemNode->Partition,
				     logical,		 2,
				     packID,	       FPACK_ADD);
    goto mkdirbad;
  }

  CallResult = CacheManSaveSector(MemNode->Device,  MemNode->Partition,
				  logical,	    2,
				  packID,           FPACK_ADD,
				  sector2);
  if ( CallResult != ERR_FS_NO_ERROR)
  { // odalokuju sektor
    CallResult = CacheManFreeSector( MemNode->Device,  MemNode->Partition,
				     logical,		 2,
				     packID,	       FPACK_ADD);
    goto mkdirbad;
  }


  CacheManCommitPackage(packID,FPACK_DELETE);
  CacheManCommitPackage(MemNode->packID);
mkdirbad:
  delete [] dir;
  MemNode->Locked.Release();
  ActiveNodes->Release(MemNode);
  SyscallActive = 0;
  return CallResult;
}
FReply FProceduralMeshComponentDetails::ClickedOnConvertToStaticMesh()
{
    // Find first selected ProcMeshComp
    UProceduralMeshComponent* ProcMeshComp = GetFirstSelectedProcMeshComp();
    if (ProcMeshComp != nullptr)
    {
        FString NewNameSuggestion = FString(TEXT("ProcMesh"));
        FString PackageName = FString(TEXT("/Game/Meshes/")) + NewNameSuggestion;
        FString Name;
        FAssetToolsModule& AssetToolsModule = FModuleManager::LoadModuleChecked<FAssetToolsModule>("AssetTools");
        AssetToolsModule.Get().CreateUniqueAssetName(PackageName, TEXT(""), PackageName, Name);

        TSharedPtr<SDlgPickAssetPath> PickAssetPathWidget =
            SNew(SDlgPickAssetPath)
            .Title(LOCTEXT("ConvertToStaticMeshPickName", "Choose New StaticMesh Location"))
            .DefaultAssetPath(FText::FromString(PackageName));

        if (PickAssetPathWidget->ShowModal() == EAppReturnType::Ok)
        {
            // Get the full name of where we want to create the physics asset.
            FString UserPackageName = PickAssetPathWidget->GetFullAssetPath().ToString();
            FName MeshName(*FPackageName::GetLongPackageAssetName(UserPackageName));

            // Check if the user inputed a valid asset name, if they did not, give it the generated default name
            if (MeshName == NAME_None)
            {
                // Use the defaults that were already generated.
                UserPackageName = PackageName;
                MeshName = *Name;
            }

            // Raw mesh data we are filling in
            FRawMesh RawMesh;
            // Materials to apply to new mesh
            TArray<UMaterialInterface*> MeshMaterials;

            const int32 NumSections = ProcMeshComp->GetNumSections();
            int32 VertexBase = 0;
            for (int32 SectionIdx = 0; SectionIdx < NumSections; SectionIdx++)
            {
                FProcMeshSection* ProcSection = ProcMeshComp->GetProcMeshSection(SectionIdx);

                // Copy verts
                for (FProcMeshVertex& Vert : ProcSection->ProcVertexBuffer)
                {
                    RawMesh.VertexPositions.Add(Vert.Position);
                }

                // Copy 'wedge' info
                int32 NumIndices = ProcSection->ProcIndexBuffer.Num();
                for (int32 IndexIdx=0; IndexIdx < NumIndices; IndexIdx++)
                {
                    int32 Index = ProcSection->ProcIndexBuffer[IndexIdx];

                    RawMesh.WedgeIndices.Add(Index + VertexBase);

                    FProcMeshVertex& ProcVertex = ProcSection->ProcVertexBuffer[Index];

                    FVector TangentX = ProcVertex.Tangent.TangentX;
                    FVector TangentZ = ProcVertex.Normal;
                    FVector TangentY = (TangentX ^ TangentZ).GetSafeNormal() * (ProcVertex.Tangent.bFlipTangentY ? -1.f : 1.f);

                    RawMesh.WedgeTangentX.Add(TangentX);
                    RawMesh.WedgeTangentY.Add(TangentY);
                    RawMesh.WedgeTangentZ.Add(TangentZ);

                    RawMesh.WedgeTexCoords[0].Add(ProcVertex.UV0);
                    RawMesh.WedgeColors.Add(ProcVertex.Color);
                }

                // copy face info
                int32 NumTris = NumIndices / 3;
                for (int32 TriIdx=0; TriIdx < NumTris; TriIdx++)
                {
                    RawMesh.FaceMaterialIndices.Add(SectionIdx);
                    RawMesh.FaceSmoothingMasks.Add(0); // Assume this is ignored as bRecomputeNormals is false
                }

                // Remember material
                MeshMaterials.Add(ProcMeshComp->GetMaterial(SectionIdx));

                // Update offset for creating one big index/vertex buffer
                VertexBase += ProcSection->ProcVertexBuffer.Num();
            }

            // If we got some valid data.
            if (RawMesh.VertexPositions.Num() > 3 && RawMesh.WedgeIndices.Num() > 3)
            {
                // Then find/create it.
                UPackage* Package = CreatePackage(NULL, *UserPackageName);
                check(Package);

                // Create StaticMesh object
                UStaticMesh* StaticMesh = NewObject<UStaticMesh>(Package, MeshName, RF_Public | RF_Standalone);
                StaticMesh->InitResources();

                StaticMesh->LightingGuid = FGuid::NewGuid();

                // Add source to new StaticMesh
                FStaticMeshSourceModel* SrcModel = new (StaticMesh->SourceModels) FStaticMeshSourceModel();
                SrcModel->BuildSettings.bRecomputeNormals = false;
                SrcModel->BuildSettings.bRecomputeTangents = false;
                SrcModel->BuildSettings.bRemoveDegenerates = false;
                SrcModel->BuildSettings.bUseHighPrecisionTangentBasis = false;
                SrcModel->BuildSettings.bUseFullPrecisionUVs = false;
                SrcModel->BuildSettings.bGenerateLightmapUVs = true;
                SrcModel->BuildSettings.SrcLightmapIndex = 0;
                SrcModel->BuildSettings.DstLightmapIndex = 1;
                SrcModel->RawMeshBulkData->SaveRawMesh(RawMesh);

                // Copy materials to new mesh
                for (UMaterialInterface* Material : MeshMaterials)
                {
                    StaticMesh->StaticMaterials.Add(FStaticMaterial(Material));
                }

                // Build mesh from source
                StaticMesh->Build(false);
                StaticMesh->PostEditChange();

                // Notify asset registry of new asset
                FAssetRegistryModule::AssetCreated(StaticMesh);
            }
        }
    }

    return FReply::Handled();
}
Beispiel #25
0
void CPackageManage::SendMsgPkg(char *guid)
{
	for(int i=0; i < (int)m_vtMsgPkg.size(); i++)
	{
		if(memcmp(m_vtMsgPkg[i].guid, guid, GUID_SIZE)==0)
		{
			COMPLEX_MSG_DATA* pData = (COMPLEX_MSG_DATA*)m_vtMsgPkg[i].lpData;
			if (pData->sSend == -1)
			{
				// ·¢ËÍÎı¾
 				char buf[MAX_SEND_BUF_LEN] = {0};
 				sendmsg_req *preq = (sendmsg_req *)buf;
 				preq->dwMsgSeq = m_vtMsgPkg[i].dwMsgSeq;
 				COPY_USERID(preq->cTouserid, m_vtMsgPkg[i].userid);
				COPY_USERID(preq->innerID, m_vtMsgPkg[i].szInnerID);
 				m_vtMsgPkg[i].tmSend = time(NULL);
 				preq->tmSend = m_vtMsgPkg[i].tmSend;
 				preq->format = m_vtMsgPkg[i].ucFormat;
 				preq->ucMsgType = m_vtMsgPkg[i].ucMsgType;
				preq->nPublicID = m_vtMsgPkg[i].nPublicID;
				preq->nRouteID = m_vtMsgPkg[i].nRouteID;
 				preq->msglen = pData->nTextLen;
 				if(preq->msglen>0 && preq->msglen<MAX_TEXT_LEN)
 				{
 					strncpy(preq->msg, pData->pBuf, preq->msglen);
 					preq->msg[preq->msglen] = 0;
 				}
 				else 
 				{
 					preq->msglen = 0;
 					preq->msg[0] = 0;
 				}
 				m_vtMsgPkg[i].nSendCount++;
				g_MyClient.SendMsgReq(preq);
				return;
			}

			short sSend = GetFreePicInfo(pData);
			if(sSend<0) return;
			PIC_OBJECT_INFO* pObjInfo = (PIC_OBJECT_INFO*)(&pData->pObjectInfo[sSend]);

			CClientPackage *pkg;

			pkg = CreatePackage(UPIM_MSG_PKG_TRANSFER);
			MSG_PKG_TRANSFER_REQ *p = (MSG_PKG_TRANSFER_REQ*)g_chBuffer;
			memcpy(p->guid, guid, GUID_SIZE);			
			p->sSend = sSend;
			strcpy(p->filename, pObjInfo->szFile);
			p->request = true;
			p->totallength = pObjInfo->nTotalLen;
			if(pObjInfo->nTotalLen-pObjInfo->nLen > DATA_TRANSFER_UNIT)
				p->length = DATA_TRANSFER_UNIT;
			else
				p->length = pObjInfo->nTotalLen - pObjInfo->nLen;
			memcpy(p->data, pObjInfo->pBuf + pObjInfo->nLen, p->length);
			pkg->SetContent(p, sizeof(MSG_PKG_TRANSFER_REQ) + p->length - 1);
			pObjInfo->nLen += p->length;
			m_vtMsgPkg[i].tmSend = time(NULL);
			g_MyClient.SendPkgReq(m_vtMsgPkg[i].userid, true, pkg);
			break;

		}
	}
}
UObject* USspjFactory::FactoryCreateBinary(UClass* InClass, UObject* InParent, FName InName, EObjectFlags Flags, UObject* Context, const TCHAR* Type, const uint8*& Buffer, const uint8* InBufferEnd, FFeedbackContext* Warn)
{
	bool bReimport = this->IsA(UReimportSspjFactory::StaticClass());
	TMap<FString, UTexture*>* ExistImages = NULL;
	if(bReimport)
	{
		ExistImages = &(Cast<UReimportSspjFactory>(this)->ExistImages);
	}

	FAssetToolsModule& AssetToolsModule = FModuleManager::LoadModuleChecked<FAssetToolsModule>("AssetTools");

	FString ProjectNameStr = InName.ToString();
	FName ProjectName = InName;

	UPackage* InParentPackage = Cast<UPackage>(InParent);
	if(InParentPackage && !bReimport)
	{
		FString ProjectPackageName;
		FString BasePackageName = FPackageName::GetLongPackagePath(InParent->GetOutermost()->GetName()) / ProjectNameStr;
		AssetToolsModule.Get().CreateUniqueAssetName(BasePackageName, TEXT(""), ProjectPackageName, ProjectNameStr);
		InParentPackage->Rename(*ProjectPackageName);
	}

	// インポート設定の取得 
	const USsImportSettings* ImportSettings = GetDefault<USsImportSettings>();

	// インポート開始 
	FEditorDelegates::OnAssetPreImport.Broadcast(this, InClass, InParent, ProjectName, Type);

	// sspj
	USsProject* NewProject = FSsLoader::LoadSsProject(InParent, ProjectName, Flags, Buffer, (InBufferEnd - Buffer) + 1);
	NewProject->SetFilepath( GetCurrentFilename() );
	if(NewProject)
	{
		if(NewProject->AssetImportData == nullptr)
		{
			NewProject->AssetImportData = NewObject<UAssetImportData>(NewProject);
		}
		NewProject->AssetImportData->Update(CurrentFilename);

		FString CurPath = FPaths::GetPath(GetCurrentFilename());

		TArray<FString> ImagePaths;
		TArray<SsTexWrapMode::Type> ImageWrapModes;
		TArray<SsTexFilterMode::Type> ImageFilterModes;

		// ssce
		NewProject->CellmapList.Empty();
		NewProject->CellmapList.AddZeroed(NewProject->CellmapNames.Num());
		for(int i = 0; i < NewProject->CellmapNames.Num(); ++i)
		{
			FString FileName = GetFilePath(CurPath, NewProject->Settings.CellMapBaseDirectory, NewProject->CellmapNames[i].ToString());

			TArray<uint8> Data;
			if(FFileHelper::LoadFileToArray(Data, *FileName))
			{
				const uint8* BufferBegin = Data.GetData();
				const uint8* BufferEnd = BufferBegin + Data.Num() - 1;
				if(FSsLoader::LoadSsCellMap(&(NewProject->CellmapList[i]), BufferBegin, (BufferEnd - BufferBegin) + 1))
				{
					NewProject->CellmapList[i].FileName = NewProject->CellmapNames[i];
					if(0 < NewProject->CellmapList[i].ImagePath.Len())
					{
						if(INDEX_NONE == ImagePaths.Find(NewProject->CellmapList[i].ImagePath))
						{
							ImagePaths.Add(NewProject->CellmapList[i].ImagePath);
							if(NewProject->CellmapList[i].OverrideTexSettings)
							{
								ImageWrapModes.Add(NewProject->CellmapList[i].WrapMode);
								ImageFilterModes.Add(NewProject->CellmapList[i].FilterMode);
							}
							else
							{
								ImageWrapModes.Add(NewProject->Settings.WrapMode);
								ImageFilterModes.Add(NewProject->Settings.FilterMode);
							}
						}
					}
				}
			}
		}

		// ssae
		NewProject->AnimeList.Empty();
		NewProject->AnimeList.AddZeroed(NewProject->AnimepackNames.Num());
		for(int i = 0; i < NewProject->AnimepackNames.Num(); ++i)
		{
			FString FileName = GetFilePath(CurPath, NewProject->Settings.AnimeBaseDirectory, NewProject->AnimepackNames[i].ToString());

			TArray<uint8> Data;
			if(FFileHelper::LoadFileToArray(Data, *FileName))
			{
				const uint8* BufferBegin = Data.GetData();
				const uint8* BufferEnd = BufferBegin + Data.Num() - 1;
				FSsLoader::LoadSsAnimePack(&(NewProject->AnimeList[i]), BufferBegin, (BufferEnd - BufferBegin) + 1);
			}
		}

		// texture
		for(int i = 0; i < ImagePaths.Num(); ++i)
		{
			FString FileName = GetFilePath(CurPath, NewProject->Settings.ImageBaseDirectory, ImagePaths[i]);

			UTexture* ImportedTexture = NULL;
			if(ExistImages && ExistImages->Contains(ImagePaths[i]))
			{
				ImportedTexture = ExistImages->FindChecked(ImagePaths[i]);
			}

			TArray<uint8> Data;
			if(FFileHelper::LoadFileToArray(Data, *FileName))
			{

				UTextureFactory* TextureFact = NewObject<UTextureFactory>();
				TextureFact->AddToRoot();

				FString TextureName = FPaths::GetBaseFilename(ImagePaths[i]);

				UPackage* TexturePackage = NULL;
				if(ImportedTexture)
				{
					TexturePackage = ImportedTexture->GetOutermost();
				}
				else
				{
					FString TexturePackageName;
					FString BasePackageName = FPackageName::GetLongPackagePath(InParent->GetOutermost()->GetName()) / TextureName;
					AssetToolsModule.Get().CreateUniqueAssetName(BasePackageName, TEXT(""), TexturePackageName, TextureName);
					TexturePackage = CreatePackage(NULL, *TexturePackageName);
				}

				const uint8* BufferBegin = Data.GetData();
				const uint8* BufferEnd = BufferBegin + Data.Num();
				UTexture2D* NewTexture = (UTexture2D*)TextureFact->FactoryCreateBinary(
					UTexture2D::StaticClass(),
					TexturePackage,
					FName(*TextureName),
					Flags,
					NULL,
					*FPaths::GetExtension(ImagePaths[i]),
					BufferBegin, BufferEnd,
					Warn
					);
				if(NewTexture)
				{
					if(ImportSettings->bOverwriteMipGenSettings)
					{
						NewTexture->MipGenSettings = TMGS_NoMipmaps;
					}
					if(ImportSettings->bOverwriteTextureGroup)
					{
						NewTexture->LODGroup = ImportSettings->TextureGroup;
					}
					if(ImportSettings->bOverwriteCompressionSettings)
					{
						NewTexture->CompressionSettings = TextureCompressionSettings::TC_EditorIcon;
					}
					if(ImportSettings->bOverwriteTilingMethodFromSspj)
					{
						switch(ImageWrapModes[i])
						{
							case SsTexWrapMode::Clamp:
								{
									NewTexture->AddressX = NewTexture->AddressY = TA_Clamp;
								} break;
							case SsTexWrapMode::Repeat:
								{
									NewTexture->AddressX = NewTexture->AddressY = TA_Wrap;
								} break;
							case SsTexWrapMode::Mirror:
								{
									NewTexture->AddressX = NewTexture->AddressY = TA_Mirror;
								} break;
						}
					}
					if(ImportSettings->bOverwriteNeverStream)
					{
						NewTexture->NeverStream = true;
					}
					if(ImportSettings->bOverwriteFilterFromSspj)
					{
						switch(ImageFilterModes[i])
						{
							case SsTexFilterMode::Nearest:
								{
									NewTexture->Filter = TF_Nearest;
								} break;
							case SsTexFilterMode::Linear:
								{
									NewTexture->Filter = TF_Bilinear;
								} break;
						}
					}

					NewTexture->UpdateResource();

					FAssetRegistryModule::AssetCreated(NewTexture);
					TexturePackage->SetDirtyFlag(true);

					TextureFact->RemoveFromRoot();

					ImportedTexture = NewTexture;
				}
			}

			if(ImportedTexture)
			{
				for(int ii = 0; ii < NewProject->CellmapList.Num(); ++ii)
				{
					if(NewProject->CellmapList[ii].ImagePath == ImagePaths[i])
					{
						NewProject->CellmapList[ii].Texture = ImportedTexture;
					}
				}
			}
		}
	}

	// インポート終了
	FEditorDelegates::OnAssetPostImport.Broadcast(this, NewProject);
	return NewProject;
}
Beispiel #27
0
//
// Find or create the linker for a package.
//
FLinkerLoad* GetPackageLinker
(
	UPackage*		InOuter,
	const TCHAR*	InLongPackageName,
	uint32			LoadFlags,
	UPackageMap*	Sandbox,
	FGuid*			CompatibleGuid
)
{
	// See if there is already a linker for this package.
	auto Result = FLinkerLoad::FindExistingLinkerForPackage(InOuter);

	// Try to load the linker.
	// See if the linker is already loaded.
	if (Result)
	{
		return Result;
	}

	FString NewFilename;
	if( !InLongPackageName )
	{
		// Resolve filename from package name.
		if( !InOuter )
		{
			// try to recover from this instead of throwing, it seems recoverable just by doing this
			FText ErrorText(LOCTEXT("PackageResolveFailed", "Can't resolve asset name"));
			LogGetPackageLinkerError(Result, InLongPackageName, ErrorText, ErrorText, InOuter, LoadFlags);
			return nullptr;
		}
	
		FString NativeFilename;
		FString LocalizedFilename;
		const bool DoesNativePackageExist = FPackageName::DoesPackageExist(InOuter->GetName(), CompatibleGuid, &NativeFilename, false);
		const bool DoesLocalizedPackageExist = FPackageName::DoesPackageExist(InOuter->GetName(), CompatibleGuid, &LocalizedFilename, true);

		// If we are the editor, we must have a native package. If we are the game, we must have a localized package or a native package.
		if ( (GIsEditor && !DoesNativePackageExist) || (!GIsEditor && !DoesLocalizedPackageExist && !DoesNativePackageExist) )
		{
			// In memory-only packages have no linker and this is ok.
			if (!(LoadFlags & LOAD_AllowDll) && !(InOuter->PackageFlags & PKG_InMemoryOnly))
			{
				FUObjectThreadContext& ThreadContext = FUObjectThreadContext::Get();
				FFormatNamedArguments Arguments;
				Arguments.Add(TEXT("AssetName"), FText::FromString(InOuter->GetName()));
				Arguments.Add(TEXT("PackageName"), FText::FromString(ThreadContext.SerializedPackageLinker ? *(ThreadContext.SerializedPackageLinker->Filename) : TEXT("NULL")));
				LogGetPackageLinkerError(Result, ThreadContext.SerializedPackageLinker ? *ThreadContext.SerializedPackageLinker->Filename : nullptr,
											FText::Format(LOCTEXT("PackageNotFound", "Can't find file for asset '{AssetName}' while loading {PackageName}."), Arguments),
											LOCTEXT("PackageNotFoundShort", "Can't find file for asset."),
											InOuter,
											LoadFlags);
			}

			return nullptr;
		}

		// The editor must not redirect packages for localization.
		if (GIsEditor)
		{
			NewFilename = NativeFilename;
		}
		else
		{
			if (DoesLocalizedPackageExist)
			{
				NewFilename = LocalizedFilename;
			}
			// If we are the game, we can fallback to the native package, but must issue a warning.
			else
			{
				// In memory-only packages have no linker and this is ok.
				if (!(LoadFlags & LOAD_AllowDll) && !(InOuter->PackageFlags & PKG_InMemoryOnly))
				{
					FUObjectThreadContext& ThreadContext = FUObjectThreadContext::Get();
					FFormatNamedArguments Arguments;
					Arguments.Add(TEXT("AssetName"), FText::FromString(InOuter->GetName()));
					Arguments.Add(TEXT("PackageName"), FText::FromString(ThreadContext.SerializedPackageLinker ? *(ThreadContext.SerializedPackageLinker->Filename) : TEXT("NULL")));
					LogGetPackageLinkerError(Result, ThreadContext.SerializedPackageLinker ? *ThreadContext.SerializedPackageLinker->Filename : nullptr,
						FText::Format(LOCTEXT("PackageNotFound", "Can't find localized file for asset '{AssetName}' while loading {PackageName}."), Arguments),
						LOCTEXT("PackageNotFoundShort", "Can't find localized file for asset."),
						InOuter,
						LoadFlags);
				}

				NewFilename = NativeFilename;
			}
		}
	}
	else
	{
		FString PackageName(InLongPackageName);
		if (!FPackageName::TryConvertFilenameToLongPackageName(InLongPackageName, PackageName))
		{
			// try to recover from this instead of throwing, it seems recoverable just by doing this
			FText ErrorText(LOCTEXT("PackageResolveFailed", "Can't resolve asset name"));
			LogGetPackageLinkerError(Result, InLongPackageName, ErrorText, ErrorText, InOuter, LoadFlags);
			return nullptr;
		}

		UPackage* ExistingPackage = FindObject<UPackage>(nullptr, *PackageName);
		if (ExistingPackage)
		{
			if (!ExistingPackage->GetOuter() && (ExistingPackage->PackageFlags & PKG_InMemoryOnly))
			{
				// This is a memory-only in package and so it has no linker and this is ok.
				return nullptr;
			}
		}

		// Verify that the file exists.
		FString NativeFilename;
		FString LocalizedFilename;
		const bool DoesNativePackageExist = FPackageName::DoesPackageExist(PackageName, CompatibleGuid, &NativeFilename, false);
		const bool DoesLocalizedPackageExist = FPackageName::DoesPackageExist(PackageName, CompatibleGuid, &LocalizedFilename, true);

		if( (GIsEditor && !DoesNativePackageExist) || (!GIsEditor && !DoesLocalizedPackageExist && !DoesNativePackageExist) )
		{
			FFormatNamedArguments Arguments;
			Arguments.Add(TEXT("Filename"), FText::FromString(InLongPackageName));

			// try to recover from this instead of throwing, it seems recoverable just by doing this
			LogGetPackageLinkerError(Result, InLongPackageName, FText::Format(LOCTEXT("FileNotFound", "Can't find file '{Filename}'"), Arguments), LOCTEXT("FileNotFoundShort", "Can't find file"), InOuter, LoadFlags);
			return nullptr;
		}

		// The editor must not redirect packages for localization.
		if (GIsEditor)
		{
			NewFilename = NativeFilename;
		}
		else
		{
			// Use the localized package if possible.
			if (DoesLocalizedPackageExist)
			{
				NewFilename = LocalizedFilename;
			}
			// If we are the game, we can fallback to the native package.
			else
			{
				NewFilename = NativeFilename;
			}
		}

		// Create the package with the provided long package name.
		UPackage* FilenamePkg = (ExistingPackage ? ExistingPackage : CreatePackage(nullptr, *PackageName));
		if (FilenamePkg != ExistingPackage && (LoadFlags & LOAD_PackageForPIE))
		{
			FilenamePkg->PackageFlags |= PKG_PlayInEditor;
		}

		// If no package specified, use package from file.
		if (!InOuter)
		{
			if( !FilenamePkg )
			{
				FFormatNamedArguments Arguments;
				Arguments.Add(TEXT("Filename"), FText::FromString(InLongPackageName));
				LogGetPackageLinkerError(Result, InLongPackageName, FText::Format(LOCTEXT("FilenameToPackage", "Can't convert filename '{Filename}' to asset name"), Arguments), LOCTEXT("FilenameToPackageShort", "Can't convert filename to asset name"), InOuter, LoadFlags);
				return nullptr;
			}
			InOuter = FilenamePkg;
			Result = FLinkerLoad::FindExistingLinkerForPackage(InOuter);
		}
		else if (InOuter != FilenamePkg) //!!should be tested and validated in new UnrealEd
		{
			// Loading a new file into an existing package, so reset the loader.
			//UE_LOG(LogLinker, Log,  TEXT("New File, Existing Package (%s, %s)"), *InOuter->GetFullName(), *FilenamePkg->GetFullName() );
			ResetLoaders( InOuter );
		}
	}

#if 0
	// Make sure the package is accessible in the sandbox.
	if( Sandbox && !Sandbox->SupportsPackage(InOuter) )
	{
		FFormatNamedArguments Arguments;
		Arguments.Add(TEXT("AssetName"), FText::FromString(InOuter->GetName()));

		LogGetPackageLinkerError(Result, InLongPackageName, FText::Format(LOCTEXT("Sandbox", "Asset '{AssetName}' is not accessible in this sandbox"), Arguments), LOCTEXT("SandboxShort", "Asset is not accessible in this sandbox"), InOuter, LoadFlags);
		return nullptr;
	}
#endif

	// Create new linker.
	if( !Result )
	{
		check(IsLoading());

		// we will already have found the filename above
		check(NewFilename.Len() > 0);

		Result = FLinkerLoad::CreateLinker( InOuter, *NewFilename, LoadFlags );
	}

	// Verify compatibility.
	if (Result && CompatibleGuid && Result->Summary.Guid != *CompatibleGuid)
	{
		FFormatNamedArguments Arguments;
		Arguments.Add(TEXT("AssetName"), FText::FromString(InOuter->GetName()));

		// This should never fire, because FindPackageFile should never return an incompatible file
		LogGetPackageLinkerError(Result, InLongPackageName, FText::Format(LOCTEXT("PackageVersion", "Asset '{AssetName}' version mismatch"), Arguments), LOCTEXT("PackageVersionShort", "Asset version mismatch"), InOuter, LoadFlags);
		return nullptr;
	}

	return Result;
}
FReply FRuntimeMeshComponentDetails::ClickedOnConvertToStaticMesh()
{
 	// Find first selected RuntimeMeshComp
 	URuntimeMeshComponent* RuntimeMeshComp = GetFirstSelectedRuntimeMeshComp();
 	if (RuntimeMeshComp != nullptr)
 	{
 		FString NewNameSuggestion = FString(TEXT("RuntimeMeshComp"));
 		FString PackageName = FString(TEXT("/Game/Meshes/")) + NewNameSuggestion;
 		FString Name;
 		FAssetToolsModule& AssetToolsModule = FModuleManager::LoadModuleChecked<FAssetToolsModule>("AssetTools");
 		AssetToolsModule.Get().CreateUniqueAssetName(PackageName, TEXT(""), PackageName, Name);
 
 		TSharedPtr<SDlgPickAssetPath> PickAssetPathWidget =
 			SNew(SDlgPickAssetPath)
 			.Title(LOCTEXT("ConvertToStaticMeshPickName", "Choose New StaticMesh Location"))
 			.DefaultAssetPath(FText::FromString(PackageName));
 
 		if (PickAssetPathWidget->ShowModal() == EAppReturnType::Ok)
 		{
 			// Get the full name of where we want to create the physics asset.
 			FString UserPackageName = PickAssetPathWidget->GetFullAssetPath().ToString();
 			FName MeshName(*FPackageName::GetLongPackageAssetName(UserPackageName));
 
 			// Check if the user inputed a valid asset name, if they did not, give it the generated default name
 			if (MeshName == NAME_None)
 			{
 				// Use the defaults that were already generated.
 				UserPackageName = PackageName;
 				MeshName = *Name;
 			}
 
 			// Raw mesh data we are filling in
 			FRawMesh RawMesh;
 					
			// Unique Materials to apply to new mesh
#if ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION >= 14
			TArray<FStaticMaterial> Materials;
#else
			TArray<UMaterialInterface*> Materials;
#endif
 
			bool bUseHighPrecisionTangents = false;
			bool bUseFullPrecisionUVs = false;

 			const int32 NumSections = RuntimeMeshComp->GetNumSections();
 			int32 VertexBase = 0;
 			for (int32 SectionIdx = 0; SectionIdx < NumSections; SectionIdx++)
 			{
				const IRuntimeMeshVerticesBuilder* Vertices;
				const FRuntimeMeshIndicesBuilder* Indices;
				RuntimeMeshComp->GetSectionMesh(SectionIdx, Vertices, Indices);

				if (Vertices->HasHighPrecisionNormals())
				{
					bUseHighPrecisionTangents = true;
				}
				if (Vertices->HasHighPrecisionUVs())
				{
					bUseFullPrecisionUVs = true;
				}
 
 				// Copy verts
				Vertices->Seek(-1);
				while (Vertices->MoveNext() < Vertices->Length())
				{
					RawMesh.VertexPositions.Add(Vertices->GetPosition());
				}
 
 				// Copy 'wedge' info
				Indices->Seek(0);
				while (Indices->HasRemaining())
 				{
					int32 Index = Indices->ReadOne();
 
 					RawMesh.WedgeIndices.Add(Index + VertexBase);
 

					Vertices->Seek(Index);
 
					FVector TangentX = Vertices->GetTangent();
					FVector TangentZ = Vertices->GetNormal();
 					FVector TangentY = (TangentX ^ TangentZ).GetSafeNormal() * Vertices->GetNormal().W;
 
 					RawMesh.WedgeTangentX.Add(TangentX);
 					RawMesh.WedgeTangentY.Add(TangentY);
 					RawMesh.WedgeTangentZ.Add(TangentZ);
 
					for (int UVIndex = 0; UVIndex < 8; UVIndex++)
					{
						if (!Vertices->HasUVComponent(UVIndex))
						{
							break;
						}
						RawMesh.WedgeTexCoords[UVIndex].Add(Vertices->GetUV(UVIndex));
					}

 					RawMesh.WedgeColors.Add(Vertices->GetColor());
 				}
 
				// Find a material index for this section.
				UMaterialInterface* Material = RuntimeMeshComp->GetMaterial(SectionIdx);

#if ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION >= 14
				int32 MaterialIndex = Materials.AddUnique(FStaticMaterial(Material));
#else
				int32 MaterialIndex = Materials.AddUnique(Material);
#endif
				

 				// copy face info
 				int32 NumTris = Indices->Length() / 3;
 				for (int32 TriIdx=0; TriIdx < NumTris; TriIdx++)
 				{
					// Set the face material
					RawMesh.FaceMaterialIndices.Add(MaterialIndex);

 					RawMesh.FaceSmoothingMasks.Add(0); // Assume this is ignored as bRecomputeNormals is false
 				}
 
 				// Update offset for creating one big index/vertex buffer
				VertexBase += Vertices->Length();
 			}
 
 			// If we got some valid data.
 			if (RawMesh.VertexPositions.Num() >= 3 && RawMesh.WedgeIndices.Num() >= 3)
 			{
 				// Then find/create it.
 				UPackage* Package = CreatePackage(NULL, *UserPackageName);
 				check(Package);
 
 				// Create StaticMesh object
 				UStaticMesh* StaticMesh = NewObject<UStaticMesh>(Package, MeshName, RF_Public | RF_Standalone);
 				StaticMesh->InitResources();
 
 				StaticMesh->LightingGuid = FGuid::NewGuid();
 
 				// Add source to new StaticMesh
 				FStaticMeshSourceModel* SrcModel = new (StaticMesh->SourceModels) FStaticMeshSourceModel();
 				SrcModel->BuildSettings.bRecomputeNormals = false;
 				SrcModel->BuildSettings.bRecomputeTangents = false;
 				SrcModel->BuildSettings.bRemoveDegenerates = false;
 				SrcModel->BuildSettings.bUseHighPrecisionTangentBasis = bUseHighPrecisionTangents;
				SrcModel->BuildSettings.bUseFullPrecisionUVs = bUseFullPrecisionUVs;
 				SrcModel->BuildSettings.bGenerateLightmapUVs = true;
 				SrcModel->BuildSettings.SrcLightmapIndex = 0;
 				SrcModel->BuildSettings.DstLightmapIndex = 1;
 				SrcModel->RawMeshBulkData->SaveRawMesh(RawMesh);
 
				// Set the materials used for this static mesh
#if ENGINE_MAJOR_VERSION == 4 && ENGINE_MINOR_VERSION >= 14
				StaticMesh->StaticMaterials = Materials;
				int32 NumMaterials = StaticMesh->StaticMaterials.Num();
#else
				StaticMesh->Materials = Materials;
				int32 NumMaterials = StaticMesh->Materials.Num();
#endif

				// Set up the SectionInfoMap to enable collision
				for (int32 SectionIdx = 0; SectionIdx < NumMaterials; SectionIdx++)
				{
					FMeshSectionInfo Info = StaticMesh->SectionInfoMap.Get(0, SectionIdx);
					Info.MaterialIndex = SectionIdx;
					Info.bEnableCollision = true;
					StaticMesh->SectionInfoMap.Set(0, SectionIdx, Info);
				}

				// Configure body setup for working collision.
				StaticMesh->CreateBodySetup();
				StaticMesh->BodySetup->CollisionTraceFlag = CTF_UseComplexAsSimple;

 				// Build mesh from source
 				StaticMesh->Build(false);

				// Make package dirty.
				StaticMesh->MarkPackageDirty();

 				StaticMesh->PostEditChange();
 
 				// Notify asset registry of new asset
 				FAssetRegistryModule::AssetCreated(StaticMesh);
 			}
 		}
 	}

	return FReply::Handled();
}