// Copyright Epic Games, Inc. All Rights Reserved. #pragma once #include "CoreMinimal.h" #include "InputCoreTypes.h" #include "GameFramework/Actor.h" #include "Camera/CameraComponent.h" #include "UnrealWidget.h" #include "EditorViewportClient.h" #include "UObject/ObjectKey.h" #include "UnrealEdMisc.h" struct FAssetData; struct FMinimalViewInfo; class FCanvas; class FDragTool; class HModel; class ILevelEditor; class SLevelViewport; class UActorFactory; class UModel; struct FWorldContext; /** Describes an object that's currently hovered over in the level viewport */ struct FViewportHoverTarget { /** The actor we're drawing the hover effect for, or NULL */ AActor* HoveredActor; /** The BSP model we're drawing the hover effect for, or NULL */ UModel* HoveredModel; /** Surface index on the BSP model that currently has a hover effect */ uint32 ModelSurfaceIndex; /** Construct from an actor */ FViewportHoverTarget(AActor* InActor) : HoveredActor(InActor), HoveredModel(NULL), ModelSurfaceIndex(INDEX_NONE) { } /** Construct from an BSP model and surface index */ FViewportHoverTarget(UModel* InModel, int32 InSurfaceIndex) : HoveredActor(NULL), HoveredModel(InModel), ModelSurfaceIndex(InSurfaceIndex) { } /** Equality operator */ bool operator==(const FViewportHoverTarget& RHS) const { return RHS.HoveredActor == HoveredActor && RHS.HoveredModel == HoveredModel && RHS.ModelSurfaceIndex == ModelSurfaceIndex; } friend uint32 GetTypeHash(const FViewportHoverTarget& Key) { return Key.HoveredActor ? GetTypeHash(Key.HoveredActor) : GetTypeHash(Key.HoveredModel) + Key.ModelSurfaceIndex; } }; struct UNREALED_API FTrackingTransaction { /** State of this transaction */ struct ETransactionState { enum Enum { Inactive, Active, Pending, }; }; FTrackingTransaction(); ~FTrackingTransaction(); /** * Initiates a transaction. */ void Begin(const FText& Description, AActor* AdditionalActor = nullptr); void End(); void Cancel(); /** Begin a pending transaction, which won't become a real transaction until PromotePendingToActive is called */ void BeginPending(const FText& Description); /** Promote a pending transaction (if any) to an active transaction */ void PromotePendingToActive(); bool IsActive() const { return TrackingTransactionState == ETransactionState::Active; } bool IsPending() const { return TrackingTransactionState == ETransactionState::Pending; } int32 TransCount; private: /** Editor selection changed delegate handler */ void OnEditorSelectionChanged(UObject* NewSelection); /** The current transaction. */ class FScopedTransaction* ScopedTransaction; /** This is set to Active if TrackingStarted() has initiated a transaction, Pending if a transaction will begin before the next delta change */ ETransactionState::Enum TrackingTransactionState; /** The description to use if a pending transaction turns into a real transaction */ FText PendingDescription; /** Initial package dirty states for the Actors within the transaction */ TMap InitialPackageDirtyStates; }; /** Interface for objects who want to lock the viewport to an actor. */ struct UNREALED_API FLevelViewportActorLock { /** Represents no lock. */ static const FLevelViewportActorLock None; /** Creates a new instance of FLevelViewportActorLock. */ FLevelViewportActorLock() : LockedActor(nullptr) {} /** Creates a new instance of FLevelViewportActorLock. */ FLevelViewportActorLock(AActor* InActor) : LockedActor(InActor) {} /** Creates a new instance of FLevelViewportActorLock. */ FLevelViewportActorLock(AActor* InActor, TOptional InAspectRatioAxisConstraint) : LockedActor(InActor), AspectRatioAxisConstraint(InAspectRatioAxisConstraint) {} /** Returns whether the locked actor is valid. */ bool HasValidLockedActor() const { return LockedActor.IsValid(); } /** Gets the locked actor. */ AActor* GetLockedActor() const { return LockedActor.Get(); } /** The actor the viewport should be locked to. */ TWeakObjectPtr LockedActor; /** An optional aspect ratio axis constraint to use when resizing the viewport. */ TOptional AspectRatioAxisConstraint; }; /** */ class UNREALED_API FLevelEditorViewportClient: public FEditorViewportClient { public: /** @return Returns the current global drop preview actor, or a NULL pointer if we don't currently have one */ static const TArray>& GetDropPreviewActors() { return DropPreviewActors; } FVector2D GetDropPreviewLocation() const { return FVector2D(DropPreviewMouseX, DropPreviewMouseY); } /** * Constructor */ FLevelEditorViewportClient(const TSharedPtr& InLevelViewport); /** * Destructor */ virtual ~FLevelEditorViewportClient(); //////////////////////////// // FViewElementDrawer interface virtual void Draw(const FSceneView* View, FPrimitiveDrawInterface* PDI) override; // End of FViewElementDrawer interface virtual FSceneView* CalcSceneView(FSceneViewFamily* ViewFamily, const EStereoscopicPass StereoPass = eSSP_FULL) override; //////////////////////////// // FEditorViewportClient interface virtual void DrawCanvas(FViewport& InViewport, FSceneView& View, FCanvas& Canvas) override; virtual bool InputKey(FViewport* Viewport, int32 ControllerId, FKey Key, EInputEvent Event, float AmountDepressed = 1.f, bool bGamepad = false) override; virtual bool InputAxis(FViewport* Viewport, int32 ControllerId, FKey Key, float Delta, float DeltaTime, int32 NumSamples = 1, bool bGamepad = false) override; virtual EMouseCursor::Type GetCursor(FViewport* Viewport, int32 X, int32 Y) override; virtual void CapturedMouseMove(FViewport* InViewport, int32 InMouseX, int32 InMouseY) override; virtual void MouseMove(FViewport* InViewport, int32 x, int32 y) override; virtual void Tick(float DeltaSeconds) override; virtual bool InputWidgetDelta(FViewport* Viewport, EAxisList::Type CurrentAxis, FVector& Drag, FRotator& Rot, FVector& Scale) override; virtual TSharedPtr MakeDragTool(EDragTool::Type DragToolType) override; virtual bool IsLevelEditorClient() const override { return ParentLevelEditor.IsValid(); } virtual void TrackingStarted(const struct FInputEventState& InInputState, bool bIsDraggingWidget, bool bNudge) override; virtual void TrackingStopped() override; virtual void AbortTracking() override; virtual FWidget::EWidgetMode GetWidgetMode() const override; virtual FVector GetWidgetLocation() const override; virtual FMatrix GetWidgetCoordSystem() const override; virtual void SetupViewForRendering(FSceneViewFamily& ViewFamily, FSceneView& View) override; virtual FLinearColor GetBackgroundColor() const override; virtual int32 GetCameraSpeedSetting() const override; virtual void SetCameraSpeedSetting(int32 SpeedSetting) override; virtual float GetCameraSpeedScalar() const override; virtual void SetCameraSpeedScalar(float SpeedScalar) override; virtual void ReceivedFocus(FViewport* InViewport) override; virtual void LostFocus(FViewport* InViewport) override; virtual void ProcessClick(FSceneView& View, HHitProxy* HitProxy, FKey Key, EInputEvent Event, uint32 HitX, uint32 HitY) override; virtual UWorld* GetWorld() const override; virtual void BeginCameraMovement(bool bHasMovement) override; virtual void EndCameraMovement() override; virtual void SetVREditView(bool bGameViewEnable) override; virtual bool GetPivotForOrbit(FVector& Pivot) const override; virtual bool ShouldScaleCameraSpeedByDistance() const override; virtual bool OverrideHighResScreenshotCaptureRegion(FIntRect& OutCaptureRegion) override; /** Sets a flag for this frame indicating that the camera has been cut, and temporal effects (such as motion blur) should be reset */ void SetIsCameraCut() { bEditorCameraCut = true; bWasEditorCameraCut = false; } bool GetIsCameraCut() const { return bEditorCameraCut; } /** * Initialize visibility flags */ void InitializeVisibilityFlags(); /** * Reset the camera position and rotation. Used when creating a new level. */ void ResetCamera(); /** * Reset the view for a new map */ void ResetViewForNewMap(); /** * Stores camera settings that may be adversely affected by PIE, so that they may be restored later */ void PrepareCameraForPIE(); /** * Restores camera settings that may be adversely affected by PIE */ void RestoreCameraFromPIE(); /** * Updates the audio listener for this viewport * * @param View The scene view to use when calculate the listener position */ void UpdateAudioListener(const FSceneView& View); /** Determines if the new MoveCanvas movement should be used */ bool ShouldUseMoveCanvasMovement(void); /** * Returns true if the passed in volume is visible in the viewport (due to volume actor visibility flags) * * @param VolumeActor The volume to check */ bool IsVolumeVisibleInViewport(const AActor& VolumeActor) const; /** * Updates or resets view properties such as aspect ratio, FOV, location etc to match that of any actor we are locked to */ void UpdateViewForLockedActor(float DeltaTime = 0.f); /** * Returns the horizontal axis for this viewport. */ EAxisList::Type GetHorizAxis() const; /** * Returns the vertical axis for this viewport. */ EAxisList::Type GetVertAxis() const; virtual void NudgeSelectedObjects(const struct FInputEventState& InputState) override; /** * Moves the viewport camera according to the locked actors location and rotation */ void MoveCameraToLockedActor(); /** * Check to see if this actor is locked by the viewport */ bool IsActorLocked(const TWeakObjectPtr InActor) const; /** * Check to see if any actor is locked by the viewport */ bool IsAnyActorLocked() const; void ApplyDeltaToActors(const FVector& InDrag, const FRotator& InRot, const FVector& InScale); void ApplyDeltaToActor(AActor* InActor, const FVector& InDeltaDrag, const FRotator& InDeltaRot, const FVector& InDeltaScale); void ApplyDeltaToComponent(USceneComponent* InComponent, const FVector& InDeltaDrag, const FRotator& InDeltaRot, const FVector& InDeltaScale); virtual void SetIsSimulateInEditorViewport(bool bInIsSimulateInEditorViewport) override; /** * Draw the texture streaming bounds. */ void DrawTextureStreamingBounds(const FSceneView* View, FPrimitiveDrawInterface* PDI); /** GC references. */ void AddReferencedObjects(FReferenceCollector& Collector) override; /** * Copies layout and camera settings from the specified viewport * * @param InViewport The viewport to copy settings from */ void CopyLayoutFromViewport(const FLevelEditorViewportClient& InViewport); /** * Returns whether the provided unlocalized sprite category is visible in the viewport or not * * @param InSpriteCategory Sprite category to get the index of * * @return true if the specified category is visible in the viewport; false if it is not */ bool GetSpriteCategoryVisibility(const FName& InSpriteCategory) const; /** * Returns whether the sprite category specified by the provided index is visible in the viewport or not * * @param Index Index of the sprite category to check * * @return true if the category specified by the index is visible in the viewport; false if it is not */ bool GetSpriteCategoryVisibility(int32 Index) const; /** * Sets the visibility of the provided unlocalized category to the provided value * * @param InSpriteCategory Sprite category to get the index of * @param bVisible true if the category should be made visible, false if it should be hidden */ void SetSpriteCategoryVisibility(const FName& InSpriteCategory, bool bVisible); /** * Sets the visibility of the category specified by the provided index to the provided value * * @param Index Index of the sprite category to set the visibility of * @param bVisible true if the category should be made visible, false if it should be hidden */ void SetSpriteCategoryVisibility(int32 Index, bool bVisible); /** * Sets the visibility of all sprite categories to the provided value * * @param bVisible true if all the categories should be made visible, false if they should be hidden */ void SetAllSpriteCategoryVisibility(bool bVisible); void SetReferenceToWorldContext(FWorldContext& WorldContext); void RemoveReferenceToWorldContext(FWorldContext& WorldContext); /** Returns true if a placement dragging actor exists */ virtual bool HasDropPreviewActors() const override; /** * If dragging an actor for placement, this function updates its position. * * @param MouseX The position of the mouse's X coordinate * @param MouseY The position of the mouse's Y coordinate * @param DroppedObjects The Objects that were used to create preview objects * @param out_bDroppedObjectsVisible Output, returns if preview objects are visible or not * * Returns true if preview actors were updated */ virtual bool UpdateDropPreviewActors(int32 MouseX, int32 MouseY, const TArray& DroppedObjects, bool& out_bDroppedObjectsVisible, class UActorFactory* FactoryToUse = NULL) override; /** * If dragging an actor for placement, this function destroys the actor. */ virtual void DestroyDropPreviewActors() override; /** * Checks the viewport to see if the given object can be dropped using the given mouse coordinates local to this viewport * * @param MouseX The position of the mouse's X coordinate * @param MouseY The position of the mouse's Y coordinate * @param AssetInfo Asset in question to be dropped */ virtual FDropQuery CanDropObjectsAtCoordinates(int32 MouseX, int32 MouseY, const FAssetData& AssetInfo) override; /** * Attempts to intelligently drop the given objects in the viewport, using the given mouse coordinates local to this viewport * * @param MouseX The position of the mouse's X coordinate * @param MouseY The position of the mouse's Y coordinate * @param DroppedObjects The Objects to be placed into the editor via this viewport * @param OutNewActors The new actor objects that were created * @param bOnlyDropOnTarget Flag that when True, will only attempt a drop on the actor targeted by the Mouse position. Defaults to false. * @param bCreateDropPreview If true, a drop preview actor will be spawned instead of a normal actor. * @param bSelectActors If true, select the newly dropped actors (defaults: true) * @param FactoryToUse The preferred actor factory to use (optional) */ virtual bool DropObjectsAtCoordinates(int32 MouseX, int32 MouseY, const TArray& DroppedObjects, TArray& OutNewActors, bool bOnlyDropOnTarget = false, bool bCreateDropPreview = false, bool bSelectActors = true, UActorFactory* FactoryToUse = NULL) override; /** * Sets GWorld to the appropriate world for this client * * @return the previous GWorld */ virtual UWorld* ConditionalSetWorld() override; /** * Restores GWorld to InWorld * * @param InWorld The world to restore */ virtual void ConditionalRestoreWorld(UWorld* InWorld) override; /** * Called to check if a material can be applied to an object, given the hit proxy */ bool CanApplyMaterialToHitProxy(const HHitProxy* HitProxy) const; /** * Static: Adds a hover effect to the specified object * * @param InHoverTarget The hoverable object to add the effect to */ static void AddHoverEffect(const struct FViewportHoverTarget& InHoverTarget); /** * Static: Removes a hover effect to the specified object * * @param InHoverTarget The hoverable object to remove the effect from */ static void RemoveHoverEffect(const struct FViewportHoverTarget& InHoverTarget); /** * Static: Clears viewport hover effects from any objects that currently have that */ static void ClearHoverFromObjects(); /** * Helper function for ApplyDeltaTo* functions - modifies scale based on grid settings. * Currently public so it can be re-used in FEdModeBlueprint. */ void ModifyScale(USceneComponent* InComponent, FVector& ScaleDelta) const; /** Set the global ptr to the current viewport */ void SetCurrentViewport(); /** Set the global ptr to the last viewport to receive a key press */ void SetLastKeyViewport(); /** * Access the 'active' actor lock. * * This returns the actor lock (as per GetActorLock) if that is the currently active lock. It is *not* the currently * active lock if there's a valid cinematic lock actor (as per GetCinematicActorLock), since cinematics take * precedence. * * @return The actor currently locked to the viewport and actively linked to the camera movements. */ TWeakObjectPtr GetActiveActorLock() const { if (ActorLocks.CinematicActorLock.HasValidLockedActor()) { return TWeakObjectPtr(); } return ActorLocks.ActorLock.LockedActor; } /** * Find a view component to use for the specified actor. Prioritizes selected * components first, followed by camera components (then falls through to the first component that implements GetEditorPreviewInfo) */ static UActorComponent* FindViewComponentForActor(AActor const* Actor); /** * Find the camera component that is driving this viewport, in the following order of preference: * 1. Cinematic locked actor * 2. User actor lock (if (bLockedCameraView is true) * * @return Pointer to a camera component to use for this viewport's view */ UCameraComponent* GetCameraComponentForView() const { const FLevelViewportActorLock& ActorLock = ActorLocks.GetLock(bLockedCameraView); return Cast(FindViewComponentForActor(ActorLock.GetLockedActor())); } /** * Gets the actor lock. This is the actor locked to the viewport via the viewport menus. */ const FLevelViewportActorLock& GetActorLock() const { return ActorLocks.ActorLock; } /** * Gets the actor lock. This is the actor locked to the viewport via the viewport menus. */ FLevelViewportActorLock& GetActorLock() { return ActorLocks.ActorLock; } /** * Set the actor lock. This is the actor locked to the viewport via the viewport menus. */ void SetActorLock(AActor* Actor); /** * Set the actor lock. This is the actor locked to the viewport via the viewport menus. */ void SetActorLock(const FLevelViewportActorLock& InActorLock); /** * Get the actor locked to the viewport by cinematic tools like Sequencer. */ const FLevelViewportActorLock& GetCinematicActorLock() const { return ActorLocks.CinematicActorLock; } /** * Get the actor locked to the viewport by cinematic tools like Sequencer. */ FLevelViewportActorLock& GetCinematicActorLock() { return ActorLocks.CinematicActorLock; } /** * Set the actor locked to the viewport by cinematic tools like Sequencer. */ void SetCinematicActorLock(AActor* Actor); /** * Set the actor locked to the viewport by cinematic tools like Sequencer. */ void SetCinematicActorLock(const FLevelViewportActorLock& InActorLock); /** * Gets the previous actor lock. This is the actor locked to the viewport via the viewport menus. */ const FLevelViewportActorLock& GetPreviousActorLock() const { return PreviousActorLocks.ActorLock; } /** * Get the previous actor locked to the viewport by cinematic tools like Sequencer. */ const FLevelViewportActorLock& GetPreviousCinematicActorLock() const { return PreviousActorLocks.CinematicActorLock; } /** * Set the actor locked to the viewport by Matinee. */ UE_DEPRECATED(4.27, "Matinee is being deprecated, use SetCinematicActorLock instead.") void SetMatineeActorLock(AActor* Actor) { SetCinematicActorLock(Actor); } /** * Check whether this viewport is locked to the specified actor */ bool IsLockedToActor(AActor* Actor) const { return ActorLocks.HasActorLocked(Actor); } /** * Check whether this viewport is locked to display the matinee view */ UE_DEPRECATED(4.27, "Matinee is being deprecated, use IsLockedToCinematic instead.") bool IsLockedToMatinee() const { return IsLockedToCinematic(); } /** * Check whether this viewport is locked to display a cinematic camera, like a Sequencer camera. */ bool IsLockedToCinematic() const { return ActorLocks.CinematicActorLock.HasValidLockedActor(); } void UpdateHoveredObjects(const TSet& NewHoveredObjects); /** * Calling SetViewportType from Dragtool_ViewportChange */ void SetViewportTypeFromTool(ELevelViewportType InViewportType); /** * Static: Attempts to place the specified object in the level, returning one or more newly-created actors if successful. * IMPORTANT: The placed actor's location must be first set using GEditor->ClickLocation and GEditor->ClickPlane. * * @param InLevel Level in which to drop actor * @param ObjToUse Asset to attempt to use for an actor to place * @param CursorLocation Location of the cursor while dropping * @param bSelectActors If true, select the newly dropped actors (defaults: true) * @param ObjectFlags The flags to place on the actor when it is spawned * @param FactoryToUse The preferred actor factory to use (optional) * @param Cursor Optional pre-calculated cursor location * * @return true if the object was successfully used to place an actor; false otherwise */ static TArray TryPlacingActorFromObject(ULevel* InLevel, UObject* ObjToUse, bool bSelectActors, EObjectFlags ObjectFlags, UActorFactory* FactoryToUse, const FName Name = NAME_None, const FViewportCursorLocation* Cursor = nullptr); /** * Returns true if creating a preview actor in the viewport. */ static bool IsDroppingPreviewActor() { return bIsDroppingPreviewActor; } /** * Static: Given a texture, returns a material for that texture, creating a new asset if necessary. This is used * for dragging and dropping assets into the scene * * @param UnrealTexture Texture that we need a material for * * @return The material that uses this texture, or null if we couldn't find or create one */ static UObject* GetOrCreateMaterialFromTexture(UTexture* UnrealTexture); virtual bool UseAppTime() const override { return false; } protected: /** * Sets the state of creating a preview actor in the viewport. */ static void SetIsDroppingPreviewActor(bool bNewIsDroppingPreviewActor) { bIsDroppingPreviewActor = bNewIsDroppingPreviewActor; } /** * Checks the viewport to see if the given blueprint asset can be dropped on the viewport. * @param AssetInfo The blueprint Asset in question to be dropped * * @return true if asset can be dropped, false otherwise */ bool CanDropBlueprintAsset(const struct FSelectedAssetInfo&); /** Called when editor cleanse event is triggered */ void OnEditorCleanse(); /** Called before the editor tries to begin PIE */ void OnPreBeginPIE(const bool bIsSimulating); /** Callback for when an editor user setting has changed */ void HandleViewportSettingChanged(FName PropertyName); /** Callback for when a map is created or destroyed */ void OnMapChanged(UWorld* InWorld, EMapChangeType MapChangeType); /** Delegate handler for ActorMoved events */ void OnActorMoved(AActor* InActor); /** FEditorViewportClient Interface*/ /** * Collects the set of components and actors on which to apply move operations during or after drag operations. */ void GetSelectedActorsAndComponentsForMove(TArray& OutActorsToMove, TArray& OutComponentsToMove) const; /** * Determines if it is valid to move an actor in this viewport. * * @param InActor - the actor that the viewport may be interested in moving. * @returns true if it is valid for this viewport to update the given actor's transform. */ bool CanMoveActorInViewport(const AActor* InActor) const; /** Performs the legacy behavior for calling post edit move and updating transforms from ApplyDeltaToActors function. */ UE_DEPRECATED(4.26, "This functions is meant to be used for ease of rollback if too many post edit move calls degrade performance during drag operations. See ULevelEditorSettings::bUseLegacyPostEditBehavior to toggle legacy behavior.") bool LegacyApplyDeltasForSelectedComponentsAndActors(const FVector& InDrag, const FRotator& InRot, const FVector& ModifiedScale); /** Performs the legacy behavior for applying transforms and calling post edit move and property changed events from TrackingStopped function. */ UE_DEPRECATED(4.26, "This functions is meant to be used for ease of rollback if too many post edit move calls degrade performance during drag operations. See ULevelEditorSettings::bUseLegacyPostEditBehavior to toggle legacy behavior.") bool LegacyTrackingStoppedForSelectedComponentsAndActors(FPropertyChangedEvent& PropertyChangedEvent); public: virtual void UpdateLinkedOrthoViewports(bool bInvalidate = false) override; virtual ELevelViewportType GetViewportType() const override; virtual void SetViewportType(ELevelViewportType InViewportType) override; virtual void RotateViewportType() override; virtual void OverridePostProcessSettings(FSceneView& View) override; virtual bool ShouldLockPitch() const override; virtual void CheckHoveredHitProxy(HHitProxy* HoveredHitProxy) override; protected: virtual void PerspectiveCameraMoved() override; virtual bool GetActiveSafeFrame(float& OutAspectRatio) const override; virtual void RedrawAllViewportsIntoThisScene() override; private: /** * Checks to see the viewports locked actor need updating */ void UpdateLockedActorViewports(const AActor* InActor, const bool bCheckRealtime); void UpdateLockedActorViewport(const AActor* InActor, const bool bCheckRealtime); /** * Moves the locked actor according to the viewport cameras location and rotation */ void MoveLockedActorToCamera(); /** @return Returns true if the delta tracker was used to modify any selected actors or BSP. Must be called before EndTracking(). */ bool HaveSelectedObjectsBeenChanged() const; /** * Called when to attempt to apply an object to a BSP surface * * @param ObjToUse The object to attempt to apply * @param ModelHitProxy The hitproxy of the BSP model whose surface the user is clicking on * @param Cursor Mouse cursor location * * @return true if the object was applied to the object */ bool AttemptApplyObjAsMaterialToSurface(UObject* ObjToUse, class HModel* ModelHitProxy, FViewportCursorLocation& Cursor); /** * Called when an asset is dropped onto the blank area of a viewport. * * @param Cursor Mouse cursor location * @param DroppedObjects Array of objects dropped into the viewport * @param ObjectFlags The object flags to place on the actors that this function spawns. * @param OutNewActors The list of actors created while dropping * @param bCreateDropPreview If true, the actor being dropped is a preview actor (defaults: false) * @param bSelectActors If true, select the newly dropped actors (defaults: true) * @param FactoryToUse The preferred actor factory to use (optional) * * @return true if the drop operation was successfully handled; false otherwise */ bool DropObjectsOnBackground(struct FViewportCursorLocation& Cursor, const TArray& DroppedObjects, EObjectFlags ObjectFlags, TArray& OutNewActors, bool bCreateDropPreview = false, bool bSelectActors = true, class UActorFactory* FactoryToUse = NULL); /** * Called when an asset is dropped upon an existing actor. * * @param Cursor Mouse cursor location * @param DroppedObjects Array of objects dropped into the viewport * @param DroppedUponActor The actor that we are dropping upon * @param DroppedUponSlot The material slot/submesh that was identified as the drop location. If unknown use -1. * @param ObjectFlags The object flags to place on the actors that this function spawns. * @param OutNewActors The list of actors created while dropping * @param bCreateDropPreview If true, the actor being dropped is a preview actor (defaults: false) * @param bSelectActors If true, select the newly dropped actors (defaults: true) * @param FactoryToUse The preferred actor factory to use (optional) * * @return true if the drop operation was successfully handled; false otherwise */ bool DropObjectsOnActor(struct FViewportCursorLocation& Cursor, const TArray& DroppedObjects, AActor* DroppedUponActor, int32 DroppedUponSlot, EObjectFlags ObjectFlags, TArray& OutNewActors, bool bCreateDropPreview = false, bool bSelectActors = true, class UActorFactory* FactoryToUse = NULL); /** * Called when an asset is dropped upon a BSP surface. * * @param View The SceneView for the dropped-in viewport * @param Cursor Mouse cursor location * @param DroppedObjects Array of objects dropped into the viewport * @param TargetProxy Hit proxy representing the dropped upon model * @param ObjectFlags The object flags to place on the actors that this function spawns. * @param OutNewActors The list of actors created while dropping * @param bCreateDropPreview If true, the actor being dropped is a preview actor (defaults: false) * @param bSelectActors If true, select the newly dropped actors (defaults: true) * @param FactoryToUse The preferred actor factory to use (optional) * * @return true if the drop operation was successfully handled; false otherwise */ bool DropObjectsOnBSPSurface(FSceneView* View, struct FViewportCursorLocation& Cursor, const TArray& DroppedObjects, HModel* TargetProxy, EObjectFlags ObjectFlags, TArray& OutNewActors, bool bCreateDropPreview = false, bool bSelectActors = true, UActorFactory* FactoryToUse = NULL); /** * Called when an asset is dropped upon a manipulation widget. * * @param View The SceneView for the dropped-in viewport * @param Cursor Mouse cursor location * @param DroppedObjects Array of objects dropped into the viewport * @param bCreateDropPreview If true, the actor being dropped is a preview actor (defaults: false) * * @return true if the drop operation was successfully handled; false otherwise */ bool DropObjectsOnWidget(FSceneView* View, struct FViewportCursorLocation& Cursor, const TArray& DroppedObjects, bool bCreateDropPreview = false); /** Helper functions for ApplyDeltaTo* functions - modifies scale based on grid settings */ void ModifyScale(AActor* InActor, FVector& ScaleDelta, bool bCheckSmallExtent = false) const; void ValidateScale(const FVector& InOriginalPreDragScale, const FVector& CurrentScale, const FVector& BoxExtent, FVector& ScaleDelta, bool bCheckSmallExtent = false) const; /** Project the specified actors into the world according to the current drag parameters */ void ProjectActorsIntoWorld(const TArray& Actors, FViewport* Viewport, const FVector& Drag, const FRotator& Rot); /** Draw additional details for brushes in the world */ void DrawBrushDetails(const FSceneView* View, FPrimitiveDrawInterface* PDI); /** Internal function for public FindViewComponentForActor, which finds a view component to use for the specified actor. */ static UActorComponent* FindViewComponentForActor(AActor const* Actor, TSet& CheckedActors); public: /** Static: List of objects we're hovering over */ static TSet HoveredObjects; /** Parent level editor that owns this viewport. Currently, this may be null if the parent doesn't happen to be a level editor. */ TWeakPtr ParentLevelEditor; /** List of layers that are hidden in this view */ TArray ViewHiddenLayers; /** Special volume actor visibility settings. Each bit represents a visibility state for a specific volume class. 1 = visible, 0 = hidden */ TBitArray<> VolumeActorVisibility; /** The viewport location that is restored when exiting PIE */ FVector LastEditorViewLocation; /** The viewport orientation that is restored when exiting PIE */ FRotator LastEditorViewRotation; FVector ColorScale; FColor FadeColor; float FadeAmount; bool bEnableFading; bool bEnableColorScaling; /** Indicates whether, of not, the base attachment volume should be drawn for this viewport. */ bool bDrawBaseInfo; /** * Used for drag duplication. Set to true on Alt+LMB so that the selected * objects (components or actors) will be duplicated as soon as the widget is displaced. */ bool bDuplicateOnNextDrag; /** * bDuplicateActorsOnNextDrag will not be set again while bDuplicateActorsInProgress is true. * The user needs to release ALT and all mouse buttons to clear bDuplicateActorsInProgress. */ bool bDuplicateActorsInProgress; /** * true when a brush is being transformed by its Widget */ bool bIsTrackingBrushModification; /** * true if only the pivot position has been moved */ bool bOnlyMovedPivot; /** True if this viewport is to change its view (aspect ratio, post processing, FOV etc) to match that of the currently locked camera, if applicable */ bool bLockedCameraView; /** Whether this viewport recently received focus. Used to determine whether component selection is permissible. */ bool bReceivedFocusRecently; /** When enabled, the Unreal transform widget will become visible after an actor is selected, even if it was turned off via a show flag */ bool bAlwaysShowModeWidgetAfterSelectionChanges; private: /** The actors that are currently being placed in the viewport via dragging */ static TArray> DropPreviewActors; /** If currently creating a preview actor. */ static bool bIsDroppingPreviewActor; /** A map of actor locations before a drag operation */ mutable TMap, FTransform> PreDragActorTransforms; /** Bit array representing the visibility of every sprite category in the current viewport */ TBitArray<> SpriteCategoryVisibility; UWorld* World; FTrackingTransaction TrackingTransaction; /** Represents the last known drop preview mouse position. */ int32 DropPreviewMouseX; int32 DropPreviewMouseY; /** If this view was controlled by another view this/last frame, don't update itself */ bool bWasControlledByOtherViewport; /** * When locked to an actor this view will be positioned in the same location and rotation as the actor. * If the actor has a camera component the view will also inherit camera settings such as aspect ratio, * FOV, post processing settings, and the like. * * This structure allows us to keep track of two actor locks: a normal actor lock, and a lock specifically * for cinematic tools like Sequencer. A viewport locked to an actor by cinematics will always take * precedent over any other. */ struct FActorLockStack { /** Get the active lock info. Cinematics take precedence. */ const FLevelViewportActorLock& GetLock(bool bAllowActorLock = true) const { if (CinematicActorLock.LockedActor.IsValid()) { return CinematicActorLock; } return bAllowActorLock ? ActorLock : FLevelViewportActorLock::None; } /** Returns whether the given actor is used as one of our locks. */ bool HasActorLocked(const AActor* InActor) const { return CinematicActorLock.LockedActor.Get() == InActor || ActorLock.LockedActor.Get() == InActor; } FLevelViewportActorLock CinematicActorLock; FLevelViewportActorLock ActorLock; }; FActorLockStack ActorLocks; FActorLockStack PreviousActorLocks; /** Caching for expensive FindViewComponentForActor. Invalidated once per Tick. */ static TMap, TWeakObjectPtr> ViewComponentForActorCache; /** If true, we switched between two different cameras. Set by matinee, used by the motion blur to invalidate this frames motion vectors */ bool bEditorCameraCut; /** Stores the previous frame's value of bEditorCameraCut in order to reset it back to false on the next frame */ bool bWasEditorCameraCut; bool bApplyCameraSpeedScaleByDistance; /** Handle to a timer event raised in ::ReceivedFocus*/ FTimerHandle FocusTimerHandle; };