311 lines
12 KiB
C++
311 lines
12 KiB
C++
// Copyright Epic Games, Inc. All Rights Reserved.
|
|
|
|
#pragma once
|
|
|
|
#include "BaseTools/BaseBrushTool.h"
|
|
#include "BaseMeshPaintingToolProperties.h"
|
|
#include "MeshPaintingToolsetTypes.h"
|
|
#include "MeshPaintInteractions.h"
|
|
#include "MeshTexturePaintingTool.generated.h"
|
|
|
|
enum class EMeshPaintModeAction : uint8;
|
|
enum class EToolShutdownType : uint8;
|
|
class FScopedTransaction;
|
|
class IMeshPaintComponentAdapter;
|
|
class UMeshToolManager;
|
|
class UTexture2D;
|
|
struct FPaintRayResults;
|
|
struct FPaintTexture2DData;
|
|
struct FTexturePaintMeshSectionInfo;
|
|
struct FToolBuilderState;
|
|
|
|
|
|
/**
|
|
* Builder for the texture color mesh paint tool.
|
|
*/
|
|
UCLASS()
|
|
class MESHPAINTINGTOOLSET_API UMeshTextureColorPaintingToolBuilder : public UInteractiveToolBuilder
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
virtual bool CanBuildTool(const FToolBuilderState& SceneState) const override;
|
|
virtual UInteractiveTool* BuildTool(const FToolBuilderState& SceneState) const override;
|
|
|
|
TWeakObjectPtr<UMeshToolManager> SharedMeshToolData;
|
|
};
|
|
|
|
/**
|
|
* Builder for the texture asset mesh paint tool.
|
|
*/
|
|
UCLASS()
|
|
class MESHPAINTINGTOOLSET_API UMeshTextureAssetPaintingToolBuilder : public UInteractiveToolBuilder
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
virtual bool CanBuildTool(const FToolBuilderState& SceneState) const override;
|
|
virtual UInteractiveTool* BuildTool(const FToolBuilderState& SceneState) const override;
|
|
|
|
TWeakObjectPtr<UMeshToolManager> SharedMeshToolData;
|
|
};
|
|
|
|
|
|
/**
|
|
* Base class for mesh texture paint properties.
|
|
*/
|
|
UCLASS()
|
|
class MESHPAINTINGTOOLSET_API UMeshTexturePaintingToolProperties : public UMeshPaintingToolProperties
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
/** Seam painting flag, True if we should enable dilation to allow the painting of texture seams */
|
|
UPROPERTY(EditAnywhere, Category = TexturePainting)
|
|
bool bEnableSeamPainting = false;
|
|
|
|
/** Optional Texture Brush to which Painting should use */
|
|
UPROPERTY(EditAnywhere, Category = TexturePainting, meta = (DisplayThumbnail = "true", TransientToolProperty))
|
|
TObjectPtr<UTexture2D> PaintBrush = nullptr;
|
|
|
|
/** Initial Rotation offset to apply to our paint brush */
|
|
UPROPERTY(EditAnywhere, Category = TexturePainting, meta = (TransientToolProperty, UIMin = "0.0", UIMax = "360.0", ClampMin = "0.0", ClampMax = "360.0"))
|
|
float PaintBrushRotationOffset = 0.0f;
|
|
|
|
/** Whether or not to continously rotate the brush towards the painting direction */
|
|
UPROPERTY(EditAnywhere, Category = TexturePainting, meta = (TransientToolProperty))
|
|
bool bRotateBrushTowardsDirection = false;
|
|
|
|
/** Whether or not to apply Texture Color Painting to the Red Channel */
|
|
UPROPERTY(EditAnywhere, Category = ColorPainting, meta = (DisplayName = "Red"))
|
|
bool bWriteRed = true;
|
|
|
|
/** Whether or not to apply Texture Color Painting to the Green Channel */
|
|
UPROPERTY(EditAnywhere, Category = ColorPainting, meta = (DisplayName = "Green"))
|
|
bool bWriteGreen = true;
|
|
|
|
/** Whether or not to apply Texture Color Painting to the Blue Channel */
|
|
UPROPERTY(EditAnywhere, Category = ColorPainting, meta = (DisplayName = "Blue"))
|
|
bool bWriteBlue = true;
|
|
|
|
/** Whether or not to apply Texture Color Painting to the Alpha Channel */
|
|
UPROPERTY(EditAnywhere, Category = ColorPainting, meta = (DisplayName = "Alpha"))
|
|
bool bWriteAlpha = false;
|
|
};
|
|
|
|
/**
|
|
* Class for texture color paint properties.
|
|
*/
|
|
UCLASS()
|
|
class MESHPAINTINGTOOLSET_API UMeshTextureColorPaintingToolProperties : public UMeshTexturePaintingToolProperties
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
/** Whether to copy all texture color painting to vertex colors. */
|
|
UPROPERTY(EditAnywhere, Category = ColorPainting)
|
|
bool bPropagateToVertexColor = false;
|
|
};
|
|
|
|
/**
|
|
* Class for texture asset paint properties.
|
|
*/
|
|
UCLASS()
|
|
class MESHPAINTINGTOOLSET_API UMeshTextureAssetPaintingToolProperties : public UMeshTexturePaintingToolProperties
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
/** UV channel which should be used for painting textures. */
|
|
UPROPERTY(EditAnywhere, Category = TexturePainting, meta = (TransientToolProperty))
|
|
int32 UVChannel = 0;
|
|
|
|
/** Texture to which painting should be applied. */
|
|
UPROPERTY(EditAnywhere, Category = TexturePainting, meta = (DisplayThumbnail = "true", TransientToolProperty))
|
|
TObjectPtr<UTexture2D> PaintTexture;
|
|
};
|
|
|
|
|
|
/**
|
|
* Base class for mesh texture painting tool.
|
|
*/
|
|
UCLASS(Abstract)
|
|
class MESHPAINTINGTOOLSET_API UMeshTexturePaintingTool : public UBaseBrushTool, public IMeshPaintSelectionInterface
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
UMeshTexturePaintingTool();
|
|
|
|
DECLARE_DELEGATE_OneParam(FOnPaintingFinishedDelegate, UMeshComponent*);
|
|
FOnPaintingFinishedDelegate& OnPaintingFinished() { return OnPaintingFinishedDelegate; }
|
|
|
|
void FloodCurrentPaintTexture();
|
|
|
|
virtual void GetModifiedTexturesToSave(TArray<UObject*>& OutTexturesToSave) const {}
|
|
virtual int32 GetSelectedUVChannel(UMeshComponent const* InMeshComponent) const { return 0; }
|
|
|
|
protected:
|
|
// Begin UInteractiveTool Interface.
|
|
virtual void Setup() override;
|
|
virtual void Shutdown(EToolShutdownType ShutdownType) override;
|
|
virtual void Render(IToolsContextRenderAPI* RenderAPI) override;
|
|
virtual void OnTick(float DeltaTime) override;
|
|
virtual bool HasCancel() const override { return false; }
|
|
virtual bool HasAccept() const override { return false; }
|
|
virtual bool CanAccept() const override { return false; }
|
|
virtual FInputRayHit CanBeginClickDragSequence(const FInputDeviceRay& PressPos) override;
|
|
virtual void OnUpdateModifierState(int ModifierID, bool bIsOn) override;
|
|
virtual void OnBeginDrag(const FRay& Ray) override;
|
|
virtual void OnUpdateDrag(const FRay& Ray) override;
|
|
virtual void OnEndDrag(const FRay& Ray) override;
|
|
virtual bool HitTest(const FRay& Ray, FHitResult& OutHit) override;
|
|
virtual void OnPropertyModified(UObject* PropertySet, FProperty* Property) override;
|
|
virtual double EstimateMaximumTargetDimension() override;
|
|
// End UInteractiveTool Interface.
|
|
|
|
FPaintTexture2DData* GetPaintTargetData(const UTexture2D* InTexture);
|
|
FPaintTexture2DData* AddPaintTargetData(UTexture2D* InTexture);
|
|
|
|
void SetAllTextureOverrides();
|
|
void ClearAllTextureOverrides();
|
|
|
|
virtual UTexture2D* GetSelectedPaintTexture(UMeshComponent const* InMeshComponent) const { return nullptr; }
|
|
virtual void CacheTexturePaintData() {}
|
|
virtual bool CanPaintTextureToComponent(UTexture* InTexture, UMeshComponent const* InMeshComponent) const { return false; }
|
|
|
|
private:
|
|
void CacheSelectionData();
|
|
void AddTextureOverrideToComponent(FPaintTexture2DData& TextureData, UMeshComponent* MeshComponent, const IMeshPaintComponentAdapter* MeshPaintAdapter = nullptr);
|
|
double CalculateTargetEdgeLength(int TargetTriCount);
|
|
void StartPaintingTexture(UMeshComponent* InMeshComponent, const IMeshPaintComponentAdapter& GeometryInfo);
|
|
void UpdateResult();
|
|
void GatherTextureTriangles(IMeshPaintComponentAdapter* Adapter, int32 TriangleIndex, const int32 VertexIndices[3], TArray<FTexturePaintTriangleInfo>* TriangleInfo, TArray<FTexturePaintMeshSectionInfo>* SectionInfos, int32 UVChannelIndex);
|
|
bool Paint(const FVector& InRayOrigin, const FVector& InRayDirection);
|
|
bool Paint(const TArrayView<TPair<FVector, FVector>>& Rays);
|
|
void PaintTexture(FMeshPaintParameters& InParams, int32 UVChannel, TArray<FTexturePaintTriangleInfo>& InInfluencedTriangles, UMeshComponent* MeshComponent, const IMeshPaintComponentAdapter& GeometryInfo, FMeshPaintParameters* LastParams = nullptr);
|
|
bool PaintInternal(const TArrayView<TPair<FVector, FVector>>& Rays, EMeshPaintModeAction PaintAction, float PaintStrength);
|
|
void FinishPaintingTexture();
|
|
void FinishPainting();
|
|
|
|
protected:
|
|
/** Textures eligible for painting retrieved from the current selection */
|
|
TArray<FPaintableTexture> PaintableTextures;
|
|
|
|
/** Stores data associated with our paint target textures */
|
|
UPROPERTY(Transient)
|
|
TMap<TObjectPtr<UTexture2D>, FPaintTexture2DData> PaintTargetData;
|
|
|
|
private:
|
|
UPROPERTY(Transient)
|
|
TObjectPtr<UMeshPaintSelectionMechanic> SelectionMechanic;
|
|
|
|
UPROPERTY(Transient)
|
|
TObjectPtr<UMeshTexturePaintingToolProperties> TextureProperties;
|
|
|
|
/** The original texture that we're painting */
|
|
UPROPERTY(Transient)
|
|
TObjectPtr<UTexture2D> PaintingTexture2D;
|
|
|
|
/** Hold the transaction while we are painting */
|
|
TUniquePtr<FScopedTransaction> PaintingTransaction;
|
|
|
|
double InitialMeshArea = 0;
|
|
bool bArePainting = false;
|
|
bool bResultValid = false;
|
|
bool bStampPending = false;
|
|
bool bInDrag = false;
|
|
bool bRequestPaintBucketFill = false;
|
|
|
|
bool bCachedClickRay = false;
|
|
FRay PendingStampRay;
|
|
FRay PendingClickRay;
|
|
FVector2D PendingClickScreenPosition;
|
|
|
|
TArray<FPaintRayResults> LastPaintRayResults;
|
|
FHitResult LastBestHitResult;
|
|
|
|
FOnPaintingFinishedDelegate OnPaintingFinishedDelegate;
|
|
};
|
|
|
|
/**
|
|
* Class for texture color painting tool.
|
|
* This paints to special textures stored on the mesh components.
|
|
* Behavior should be similar to vertex painting (per instance painting stored on components).
|
|
* But painting texture colors instead of vertex colors is a better fit for very dense mesh types such as used by nanite.
|
|
*/
|
|
UCLASS()
|
|
class MESHPAINTINGTOOLSET_API UMeshTextureColorPaintingTool : public UMeshTexturePaintingTool
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
UMeshTextureColorPaintingTool();
|
|
|
|
protected:
|
|
// Begin UInteractiveTool Interface.
|
|
virtual void Setup() override;
|
|
// End UInteractiveTool Interface.
|
|
|
|
// Begin UMeshTexturePaintingTool Interface.
|
|
virtual bool AllowsMultiselect() const override { return true; }
|
|
virtual bool IsMeshAdapterSupported(TSharedPtr<IMeshPaintComponentAdapter> MeshAdapter) const override;
|
|
virtual UTexture2D* GetSelectedPaintTexture(UMeshComponent const* InMeshComponent) const override;
|
|
virtual int32 GetSelectedUVChannel(UMeshComponent const* InMeshComponent) const override;
|
|
virtual void GetModifiedTexturesToSave(TArray<UObject*>& OutTexturesToSave) const override;
|
|
virtual void CacheTexturePaintData() override;
|
|
virtual bool CanPaintTextureToComponent(UTexture* InTexture, UMeshComponent const* InMeshComponent) const override;
|
|
// End UMeshTexturePaintingTool Interface.
|
|
|
|
private:
|
|
UPROPERTY(Transient)
|
|
TObjectPtr<UMeshTextureColorPaintingToolProperties> ColorProperties;
|
|
|
|
UPROPERTY(Transient)
|
|
TObjectPtr<UTexture> MeshPaintDummyTexture;
|
|
};
|
|
|
|
/**
|
|
* Class for texture asset painting tool.
|
|
* This paints to texture assets directly from the mesh.
|
|
* The texture asset to paint is selected from the ones referenced in the mesh component's materials.
|
|
*/
|
|
UCLASS()
|
|
class MESHPAINTINGTOOLSET_API UMeshTextureAssetPaintingTool : public UMeshTexturePaintingTool
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
UMeshTextureAssetPaintingTool();
|
|
|
|
/** Change selected texture to previous or next available. */
|
|
void CycleTextures(int32 Direction);
|
|
|
|
/** Get the selected paint texture, and return the modified overriden texture if currently painting. */
|
|
UTexture* GetSelectedPaintTextureWithOverride() const;
|
|
|
|
/** Returns true if asset shouldn't be shown in UI because it is not in our paintable texture array. */
|
|
bool ShouldFilterTextureAsset(const FAssetData& AssetData) const;
|
|
|
|
virtual int32 GetSelectedUVChannel(UMeshComponent const* InMeshComponent) const override;
|
|
|
|
protected:
|
|
// Begin UInteractiveTool Interface.
|
|
virtual void Setup() override;
|
|
// End UInteractiveTool Interface.
|
|
|
|
// Begin UMeshTexturePaintingTool Interface.
|
|
virtual bool AllowsMultiselect() const override { return true; }
|
|
virtual bool IsMeshAdapterSupported(TSharedPtr<IMeshPaintComponentAdapter> MeshAdapter) const override;
|
|
virtual void OnPropertyModified(UObject* PropertySet, FProperty* Property) override;
|
|
virtual UTexture2D* GetSelectedPaintTexture(UMeshComponent const* InMeshComponent) const override;
|
|
virtual void GetModifiedTexturesToSave(TArray<UObject*>& OutTexturesToSave) const override;
|
|
virtual void CacheTexturePaintData() override;
|
|
virtual bool CanPaintTextureToComponent(UTexture* InTexture, UMeshComponent const* InMeshComponent) const override;
|
|
// End UMeshTexturePaintingTool Interface.
|
|
|
|
private:
|
|
UPROPERTY(Transient)
|
|
TObjectPtr<UMeshTextureAssetPaintingToolProperties> AssetProperties;
|
|
};
|