void FSpriteEditorViewportClient::EndTransaction() { if (bManipulationDirtiedSomething) { UPaperSprite* Sprite = GetSpriteBeingEdited(); if (IsInSourceRegionEditMode()) { // Snap to pixel grid at the end of the drag Sprite->SourceUV.X = FMath::Max(FMath::RoundToFloat(Sprite->SourceUV.X), 0.0f); Sprite->SourceUV.Y = FMath::Max(FMath::RoundToFloat(Sprite->SourceUV.Y), 0.0f); Sprite->SourceDimension.X = FMath::Max(FMath::RoundToFloat(Sprite->SourceDimension.X), 0.0f); Sprite->SourceDimension.Y = FMath::Max(FMath::RoundToFloat(Sprite->SourceDimension.Y), 0.0f); } Sprite->PostEditChange(); } bManipulationDirtiedSomething = false; if (ScopedTransaction != nullptr) { delete ScopedTransaction; ScopedTransaction = nullptr; } }
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 FSpriteEditorViewportClient::UpdateSourceTextureSpriteFromSprite(UPaperSprite* SourceSprite) { UPaperSprite* TargetSprite = SourceTextureViewComponent->GetSprite(); check(TargetSprite); if (SourceSprite != nullptr) { if ((SourceSprite->GetSourceTexture() != TargetSprite->GetSourceTexture()) || (TargetSprite->PixelsPerUnrealUnit != SourceSprite->PixelsPerUnrealUnit)) { FComponentReregisterContext ReregisterSprite(SourceTextureViewComponent); FSpriteAssetInitParameters SpriteReinitParams; SpriteReinitParams.SetTextureAndFill(SourceSprite->SourceTexture); SpriteReinitParams.DefaultMaterialOverride = SourceSprite->DefaultMaterial; SpriteReinitParams.AlternateMaterialOverride = SourceSprite->AlternateMaterial; SpriteReinitParams.SetPixelsPerUnrealUnit(SourceSprite->PixelsPerUnrealUnit); TargetSprite->InitializeSprite(SpriteReinitParams); RequestFocusOnSelection(/*bInstant=*/ true); } // Position the sprite for the mode its meant to be in FVector2D CurrentPivotPosition; ESpritePivotMode::Type CurrentPivotMode = TargetSprite->GetPivotMode(/*out*/CurrentPivotPosition); FVector Translation(1.0f * PaperAxisZ); if (IsInSourceRegionEditMode()) { if (CurrentPivotMode != ESpritePivotMode::Bottom_Left) { TargetSprite->SetPivotMode(ESpritePivotMode::Bottom_Left, FVector2D::ZeroVector); TargetSprite->PostEditChange(); } SourceTextureViewComponent->SetSpriteColor(FLinearColor::White); SourceTextureViewComponent->SetWorldTransform(FTransform(Translation)); } else { const FVector2D PivotPosition = SourceSprite->GetPivotPosition(); if (CurrentPivotMode != ESpritePivotMode::Custom || CurrentPivotPosition != PivotPosition) { TargetSprite->SetPivotMode(ESpritePivotMode::Custom, PivotPosition); TargetSprite->PostEditChange(); } // Tint the source texture darker to help distinguish the two SourceTextureViewComponent->SetSpriteColor(SpriteEditingConstants::SourceTextureDarkTintColor); const bool bRotated = SourceSprite->IsRotatedInSourceImage(); if (bRotated) { FQuat Rotation(PaperAxisZ, FMath::DegreesToRadians(90.0f)); SourceTextureViewComponent->SetWorldTransform(FTransform(Rotation, Translation)); } else { SourceTextureViewComponent->SetWorldTransform(FTransform(Translation)); } } } else { // No source sprite, so don't draw the target either TargetSprite->SourceTexture = nullptr; } }