void FHierarchicalLODUtilities::DestroyCluster(ALODActor* InActor) { // Find if it has a parent ALODActor AActor* Actor = CastChecked<AActor>(InActor); UWorld* World = Actor->GetWorld(); ALODActor* ParentLOD = GetParentLODActor(InActor); const FScopedTransaction Transaction(LOCTEXT("UndoAction_DeleteCluster", "Deleting a (invalid) Cluster")); Actor->Modify(); World->Modify(); if (ParentLOD != nullptr) { ParentLOD->Modify(); ParentLOD->RemoveSubActor(Actor); } // Clean out sub actors and update their LODParent while (InActor->SubActors.Num()) { AActor* SubActor = InActor->SubActors[0]; SubActor->Modify(); InActor->RemoveSubActor(SubActor); } // Also destroy the cluster's data DestroyClusterData(InActor); World->DestroyActor(InActor); if (ParentLOD != nullptr && !ParentLOD->HasValidSubActors()) { DestroyCluster(ParentLOD); } }
void FHierarchicalLODUtilities::DestroyLODActor(ALODActor* InActor) { const FScopedTransaction Transaction(LOCTEXT("UndoAction_DeleteLODActor", "Delete LOD Actor")); UWorld* World = InActor->GetWorld(); World->Modify(); InActor->Modify(); ALODActor* ParentActor = FHierarchicalLODUtilities::GetParentLODActor(InActor); FHierarchicalLODUtilities::DestroyCluster(InActor); World->DestroyActor(InActor); if (ParentActor && !ParentActor->HasValidSubActors()) { ParentActor->Modify(); FHierarchicalLODUtilities::DestroyLODActor(ParentActor); } }
ALODActor* FHierarchicalLODUtilities::CreateNewClusterFromActors(UWorld* InWorld, AWorldSettings* WorldSettings, const TArray<AActor*>& InActors, const int32 InLODLevel /*= 0*/) { checkf(InWorld != nullptr, TEXT("Invalid world")); checkf(InActors.Num() > 0, TEXT("Zero number of sub actors")); checkf(WorldSettings != nullptr, TEXT("Invalid world settings")); checkf(WorldSettings->bEnableHierarchicalLODSystem, TEXT("Hierarchical LOD system is disabled")); const FScopedTransaction Transaction(LOCTEXT("UndoAction_CreateNewCluster", "Create new Cluster")); InWorld->Modify(); // Create the cluster ALODActor* NewCluster = FHierarchicalLODUtilities::CreateNewClusterActor(InWorld, InLODLevel, WorldSettings); checkf(NewCluster != nullptr, TEXT("Failed to create a new cluster")); // Add InActors to new cluster for (AActor* Actor : InActors) { checkf(Actor != nullptr, TEXT("Invalid actor in InActors")); // Check if Actor is currently part of a different cluster ALODActor* ParentActor = FHierarchicalLODUtilities::GetParentLODActor(Actor); if (ParentActor != nullptr) { // If so remove it first ParentActor->Modify(); ParentActor->RemoveSubActor(Actor); // If the parent cluster is now empty (invalid) destroy it if (!ParentActor->HasValidSubActors()) { FHierarchicalLODUtilities::DestroyCluster(ParentActor); } } // Add actor to new cluster NewCluster->AddSubActor(Actor); } // Update sub actor LOD parents to populate NewCluster->UpdateSubActorLODParents(); return NewCluster; }
const bool FHierarchicalLODUtilities::RemoveActorFromCluster(AActor* InActor) { checkf(InActor != nullptr, TEXT("Invalid InActor")); bool bSucces = false; ALODActor* ParentActor = FHierarchicalLODUtilities::GetParentLODActor(InActor); if (ParentActor != nullptr) { const FScopedTransaction Transaction(LOCTEXT("UndoAction_RemoveActorFromCluster", "Remove Actor From Cluster")); ParentActor->Modify(); InActor->Modify(); bSucces = ParentActor->RemoveSubActor(InActor); if (!ParentActor->HasValidSubActors()) { DestroyCluster(ParentActor); } } return bSucces; }