// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "InputCoreTypes.h" #include "UObject/GCObject.h" #include "UnrealWidgetFwd.h" #include "EdMode.h" #include "LandscapeEdit.h" #include "LandscapeEditTypes.h" class FEditorViewportClient; class FPrimitiveDrawInterface; class FSceneView; class FViewport; class ULandscapeInfo; class ULandscapeLayerInfoObject; class UMaterialInstance; class UMaterialInterface; class UViewportInteractor; struct FViewportClick; // FLandscapeToolMousePosition - Struct to store mouse positions since the last time we applied the brush struct FLandscapeToolInteractorPosition { // Stored in heightmap space. FVector2D Position; bool bModifierPressed; FLandscapeToolInteractorPosition(FVector2D InPosition, const bool bInModifierPressed) : Position(InPosition) , bModifierPressed(bInModifierPressed) { } }; enum class ELandscapeBrushType { Normal = 0, Alpha, Component, Gizmo, Splines }; class FLandscapeBrushData { protected: FIntRect Bounds; TArray BrushAlpha; public: FLandscapeBrushData() : Bounds() { } FLandscapeBrushData(FIntRect InBounds) : Bounds(InBounds) { BrushAlpha.SetNumZeroed(Bounds.Area()); } FIntRect GetBounds() const { return Bounds; } // For compatibility with older landscape code that uses inclusive bounds in 4 int32s void GetInclusiveBounds(int32& X1, int32& Y1, int32& X2, int32& Y2) const { X1 = Bounds.Min.X; Y1 = Bounds.Min.Y; X2 = Bounds.Max.X - 1; Y2 = Bounds.Max.Y - 1; } float* GetDataPtr(FIntPoint Position) { return BrushAlpha.GetData() + (Position.Y - Bounds.Min.Y) * Bounds.Width() + (Position.X - Bounds.Min.X); } const float* GetDataPtr(FIntPoint Position) const { return BrushAlpha.GetData() + (Position.Y - Bounds.Min.Y) * Bounds.Width() + (Position.X - Bounds.Min.X); } FORCEINLINE explicit operator bool() const { return BrushAlpha.Num() != 0; } FORCEINLINE bool operator!() const { return !(bool)*this; } }; class FLandscapeBrush : public FGCObject { public: virtual void MouseMove(float LandscapeX, float LandscapeY) = 0; virtual TOptional GetLastMousePosition() const { return TOptional(); } virtual FLandscapeBrushData ApplyBrush(const TArray& InteractorPositions) = 0; virtual TOptional InputKey(FEditorViewportClient* InViewportClient, FViewport* InViewport, FKey InKey, EInputEvent InEvent) { return TOptional(); } virtual void Tick(FEditorViewportClient* ViewportClient, float DeltaTime) {}; virtual void BeginStroke(float LandscapeX, float LandscapeY, class FLandscapeTool* CurrentTool); virtual void EndStroke(); virtual void EnterBrush() {} virtual void LeaveBrush() {} virtual ~FLandscapeBrush() {} virtual UMaterialInterface* GetBrushMaterial() { return NULL; } virtual const TCHAR* GetBrushName() = 0; virtual FText GetDisplayName() = 0; virtual ELandscapeBrushType GetBrushType() { return ELandscapeBrushType::Normal; } // FGCObject interface virtual void AddReferencedObjects(FReferenceCollector& Collector) override {} virtual FString GetReferencerName() const override { return TEXT("FLandscapeBrush"); } }; struct FLandscapeBrushSet { FLandscapeBrushSet(const TCHAR* InBrushSetName) : BrushSetName(InBrushSetName) , PreviousBrushIndex(0) { } const FName BrushSetName; TArray Brushes; int32 PreviousBrushIndex; virtual ~FLandscapeBrushSet() { for (int32 BrushIdx = 0; BrushIdx < Brushes.Num(); BrushIdx++) { delete Brushes[BrushIdx]; } } }; namespace ELandscapeToolTargetTypeMask { enum Type : uint8 { Heightmap = 1 << static_cast(ELandscapeToolTargetType::Heightmap), Weightmap = 1 << static_cast(ELandscapeToolTargetType::Weightmap), Visibility = 1 << static_cast(ELandscapeToolTargetType::Visibility), NA = 0, All = 0xFF, }; inline ELandscapeToolTargetTypeMask::Type FromType(ELandscapeToolTargetType TargetType) { if (TargetType == ELandscapeToolTargetType::Invalid) { return ELandscapeToolTargetTypeMask::NA; } return (ELandscapeToolTargetTypeMask::Type)(1 << static_cast(TargetType)); } } struct FLandscapeToolTarget { TWeakObjectPtr LandscapeInfo; ELandscapeToolTargetType TargetType; TWeakObjectPtr LayerInfo; FName LayerName; FLandscapeToolTarget() : LandscapeInfo() , TargetType(ELandscapeToolTargetType::Heightmap) , LayerInfo() , LayerName(NAME_None) { } }; enum class ELandscapeToolType { Normal = 0, Mask, }; /** * FLandscapeTool */ class FLandscapeTool : public FGCObject { public: virtual void EnterTool() {} virtual bool IsToolActive() const { return false; } virtual void ExitTool() {} virtual bool BeginTool(FEditorViewportClient* ViewportClient, const FLandscapeToolTarget& Target, const FVector& InHitLocation) = 0; virtual void EndTool(FEditorViewportClient* ViewportClient) = 0; virtual void Tick(FEditorViewportClient* ViewportClient, float DeltaTime) {}; virtual bool MouseEnter(FEditorViewportClient* InViewportClient, FViewport* InViewport, int32 MouseX, int32 MouseY) { return true; } virtual bool MouseLeave(FEditorViewportClient* InViewportClient, FViewport* InViewport) { return true; } virtual bool MouseMove(FEditorViewportClient* ViewportClient, FViewport* Viewport, int32 x, int32 y) = 0; virtual bool HandleClick(HHitProxy* HitProxy, const FViewportClick& Click) { return false; } virtual bool InputKey(FEditorViewportClient* InViewportClient, FViewport* InViewport, FKey InKey, EInputEvent InEvent) { return false; } virtual bool InputDelta(FEditorViewportClient* InViewportClient, FViewport* InViewport, FVector& InDrag, FRotator& InRot, FVector& InScale) { return false; } virtual bool GetCursor(EMouseCursor::Type& OutCursor) const { return false; } FLandscapeTool() {} virtual ~FLandscapeTool() {} virtual const TCHAR* GetToolName() const = 0; virtual FText GetDisplayName() const = 0; virtual FText GetDisplayMessage() const = 0; virtual void SetEditRenderType(); virtual void Render(const FSceneView* View, FViewport* Viewport, FPrimitiveDrawInterface* PDI) {} virtual bool HitTrace(const FVector& TraceStart, const FVector& TraceEnd, FVector& OutHitLocation) { return false; } virtual bool UseSphereTrace() { return true; } virtual bool SupportsMask() { return true; } virtual bool SupportsComponentSelection() { return false; } virtual bool OverrideSelection() const { return false; } virtual bool IsSelectionAllowed(AActor* InActor, bool bInSelection) const { return false; } virtual bool UsesTransformWidget() const { return false; } virtual EAxisList::Type GetWidgetAxisToDraw(UE::Widget::EWidgetMode InWidgetMode) const { return EAxisList::All; } virtual bool AffectsEditLayers() const { return true; }; virtual bool OverrideWidgetLocation() const { return true; } virtual bool OverrideWidgetRotation() const { return true; } virtual FVector GetWidgetLocation() const { return FVector::ZeroVector; } virtual FMatrix GetWidgetRotation() const { return FMatrix::Identity; } virtual bool DisallowMouseDeltaTracking() const { return false; } /** Get override cursor visibility settings */ virtual bool GetOverrideCursorVisibility(bool& bWantsOverride, bool& bHardwareCursorVisible, bool bSoftwareCursorVisible) const { return false; } /** Called before mouse movement is converted to drag/rot */ virtual bool PreConvertMouseMovement(FEditorViewportClient* InViewportClient) { return false; } /** Called after mouse movement is converted to drag/rot */ virtual bool PostConvertMouseMovement(FEditorViewportClient* InViewportClient) { return false; } virtual void SetCanToolBeActivated(bool Value) { } virtual bool CanToolBeActivated() const { return true; } virtual EEditAction::Type GetActionEditDuplicate() { return EEditAction::Skip; } virtual EEditAction::Type GetActionEditDelete() { return EEditAction::Skip; } virtual EEditAction::Type GetActionEditCut() { return EEditAction::Skip; } virtual EEditAction::Type GetActionEditCopy() { return EEditAction::Skip; } virtual EEditAction::Type GetActionEditPaste() { return EEditAction::Skip; } virtual bool ProcessEditDuplicate() { return false; } virtual bool ProcessEditDelete() { return false; } virtual bool ProcessEditCut() { return false; } virtual bool ProcessEditCopy() { return false; } virtual bool ProcessEditPaste() { return false; } /** Returns the resolution difference when the Tool action is applied. */ virtual int32 GetToolActionResolutionDelta() const { return 0; } // Functions which doesn't need Viewport data... virtual void Process(int32 Index, int32 Arg) {} virtual ELandscapeToolType GetToolType() { return ELandscapeToolType::Normal; } virtual ELandscapeToolTargetTypeMask::Type GetSupportedTargetTypes() { return ELandscapeToolTargetTypeMask::NA; }; // FGCObject interface virtual void AddReferencedObjects(FReferenceCollector& Collector) override {} virtual FString GetReferencerName() const override { return FString(TEXT("FLandscapeTool::")).Append(GetToolName()); } public: int32 PreviousBrushIndex = INDEX_NONE; TArray ValidBrushes; };