HLODOutliner::FDragValidationInfo HLODOutliner::FLODActorDropTarget::ValidateDrop(FDragDropPayload& DraggedObjects) const { if (DraggedObjects.StaticMeshActors.IsSet() && DraggedObjects.StaticMeshActors->Num() > 0) { if (DraggedObjects.StaticMeshActors->Num() > 0 && DraggedObjects.LODActors->Num() == 0) { if (DraggedObjects.bSceneOutliner == false) { bool bContaining = false; // Check if this StaticMesh Actor is not already inside this cluster for (int32 ActorIndex = 0; ActorIndex < DraggedObjects.StaticMeshActors->Num(); ++ActorIndex) { if (LODActor->SubActors.Contains(DraggedObjects.StaticMeshActors.GetValue()[ActorIndex])) { bContaining = true; break; } } if (!bContaining) { if (DraggedObjects.StaticMeshActors->Num() > 1) { return FDragValidationInfo(EHierarchicalLODActionType::MoveActorToCluster, FHLODOutlinerDragDropOp::ToolTip_MultipleSelection_Compatible, LOCTEXT("MoveMultipleToCluster", "Move Actors to Cluster")); } else { return FDragValidationInfo(EHierarchicalLODActionType::MoveActorToCluster, FHLODOutlinerDragDropOp::ToolTip_Compatible, LOCTEXT("MoveToCluster", "Move Actor to Cluster")); } } else { return FDragValidationInfo(EHierarchicalLODActionType::InvalidAction, FHLODOutlinerDragDropOp::ToolTip_Incompatible, LOCTEXT("AlreadyInCluster", "Cannot Add to Existing cluster")); } } else { TArray<AActor*> Actors; for (auto StaticMeshActor : DraggedObjects.StaticMeshActors.GetValue()) { Actors.Add(StaticMeshActor.Get()); } Actors.Add(LODActor.Get()); const bool MultipleActors = DraggedObjects.StaticMeshActors->Num() > 1; if (FHierarchicalLODUtilities::AreActorsInSamePersistingLevel(Actors)) { return FDragValidationInfo(EHierarchicalLODActionType::AddActorToCluster, MultipleActors ? FHLODOutlinerDragDropOp::ToolTip_MultipleSelection_Compatible : FHLODOutlinerDragDropOp::ToolTip_Compatible, MultipleActors ? LOCTEXT("AddMultipleToCluster", "Add Actors to Cluster") : LOCTEXT("AddToCluster", "Add Actor to Cluster")); } else { return FDragValidationInfo(EHierarchicalLODActionType::InvalidAction, MultipleActors ? FHLODOutlinerDragDropOp::ToolTip_MultipleSelection_Incompatible : FHLODOutlinerDragDropOp::ToolTip_Incompatible, LOCTEXT("NotInSameLODLevel", "Actors are not all in the same persisting level")); } } } if (DraggedObjects.bSceneOutliner) { return FDragValidationInfo(EHierarchicalLODActionType::InvalidAction, FHLODOutlinerDragDropOp::ToolTip_Incompatible, LOCTEXT("AlreadyInHLOD", "Actor is already in one of the Hierarchical LOD clusters")); } } else if (DraggedObjects.LODActors.IsSet() && DraggedObjects.LODActors->Num() > 0) { // Only valid if dragging inside the HLOD outliner if (!DraggedObjects.bSceneOutliner) { bool bValidForMerge = true; bool bValidForChilding = true; int32 FirstLODLevel = -1; UObject* LevelOuter = nullptr; UObject* SubActorOuter = (LODActor->SubActors.Num()) ? LODActor->SubActors[0]->GetOuter() : nullptr; for (auto Actor : DraggedObjects.LODActors.GetValue()) { ALODActor* InLODActor = Cast<ALODActor>(Actor.Get()); if (InLODActor) { // If dragged onto self or already containing LODActor early out if (InLODActor == LODActor.Get() || LODActor->SubActors.Contains(InLODActor)) { bValidForMerge = false; bValidForChilding = false; break; } // Check in case of multiple selected LODActor items to make sure all of them come from the same LOD level if (FirstLODLevel == -1) { FirstLODLevel = InLODActor->LODLevel; } if (InLODActor->LODLevel != LODActor->LODLevel) { bValidForMerge = false; if (InLODActor->LODLevel != FirstLODLevel) { bValidForChilding = false; } } // Check if in same level asset if (LevelOuter == nullptr) { LevelOuter = InLODActor->GetOuter(); } else if (LevelOuter != InLODActor->GetOuter()) { bValidForMerge = false; bValidForChilding = false; } if (InLODActor->SubActors.Num() && SubActorOuter != InLODActor->SubActors[0]->GetOuter()) { bValidForChilding = false; bValidForMerge = false; } } } if (bValidForMerge) { return FDragValidationInfo(EHierarchicalLODActionType::MergeClusters, (DraggedObjects.LODActors->Num() == 1) ? FHLODOutlinerDragDropOp::ToolTip_Compatible : FHLODOutlinerDragDropOp::ToolTip_MultipleSelection_Compatible, LOCTEXT("MergeHLODClusters", "Merge Cluster(s)")); } else if (bValidForChilding) { return FDragValidationInfo(EHierarchicalLODActionType::ChildCluster, (DraggedObjects.LODActors->Num() == 1) ? FHLODOutlinerDragDropOp::ToolTip_Compatible : FHLODOutlinerDragDropOp::ToolTip_MultipleSelection_Compatible, LOCTEXT("ChildHLODClusters", "Add Child Cluster(s)")); } else { return FDragValidationInfo(EHierarchicalLODActionType::InvalidAction, FHLODOutlinerDragDropOp::ToolTip_Incompatible, LOCTEXT("InvalidOperation", "Invalid Operation")); } } } return FDragValidationInfo(EHierarchicalLODActionType::InvalidAction, FHLODOutlinerDragDropOp::ToolTip_Incompatible, LOCTEXT("NotImplemented", "Not implemented")); }