bmh/FlightSimulation/Plugins/CesiumForUnreal_5.4/Source/CesiumRuntime/Private/CesiumCameraManager.cpp
2025-02-07 22:52:32 +08:00

117 lines
3.6 KiB
C++

// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#include "CesiumCameraManager.h"
#include "CesiumRuntime.h"
#include "Engine/World.h"
#include "EngineUtils.h"
#include <string>
#include <vector>
FName ACesiumCameraManager::DEFAULT_CAMERAMANAGER_TAG =
FName("DEFAULT_CAMERAMANAGER");
/*static*/ ACesiumCameraManager* ACesiumCameraManager::GetDefaultCameraManager(
const UObject* WorldContextObject) {
// A null world context means a null return value (no camera manager
// available)
if (WorldContextObject == nullptr)
return nullptr;
UWorld* world = WorldContextObject->GetWorld();
// This method can be called by actors even when opening the content browser.
if (!IsValid(world)) {
return nullptr;
}
UE_LOG(
LogCesium,
Verbose,
TEXT("World name for GetDefaultCameraManager: %s"),
*world->GetFullName());
// Note: The actor iterator will be created with the
// "EActorIteratorFlags::SkipPendingKill" flag,
// meaning that we don't have to handle objects
// that have been deleted. (This is the default,
// but made explicit here)
ACesiumCameraManager* pCameraManager = nullptr;
EActorIteratorFlags flags = EActorIteratorFlags::OnlyActiveLevels |
EActorIteratorFlags::SkipPendingKill;
for (TActorIterator<AActor> actorIterator(
world,
ACesiumCameraManager::StaticClass(),
flags);
actorIterator;
++actorIterator) {
AActor* actor = *actorIterator;
if (actor->GetLevel() == world->PersistentLevel &&
actor->ActorHasTag(DEFAULT_CAMERAMANAGER_TAG)) {
pCameraManager = Cast<ACesiumCameraManager>(actor);
break;
}
}
if (!pCameraManager) {
UE_LOG(
LogCesium,
Verbose,
TEXT("Creating default ACesiumCameraManager for actor %s"),
*WorldContextObject->GetName());
// Spawn georeference in the persistent level
FActorSpawnParameters spawnParameters;
spawnParameters.SpawnCollisionHandlingOverride =
ESpawnActorCollisionHandlingMethod::AlwaysSpawn;
spawnParameters.OverrideLevel = world->PersistentLevel;
pCameraManager = world->SpawnActor<ACesiumCameraManager>(spawnParameters);
// Null check so the editor doesn't crash when it makes arbitrary calls to
// this function without a valid world context object.
if (pCameraManager) {
pCameraManager->Tags.Add(DEFAULT_CAMERAMANAGER_TAG);
}
} else {
UE_LOG(
LogCesium,
Verbose,
TEXT("Using existing ACesiumCameraManager %s for actor %s"),
*pCameraManager->GetName(),
*WorldContextObject->GetName());
}
return pCameraManager;
}
ACesiumCameraManager::ACesiumCameraManager() : AActor() {
#if WITH_EDITOR
this->SetIsSpatiallyLoaded(false);
#endif
}
bool ACesiumCameraManager::ShouldTickIfViewportsOnly() const { return true; }
void ACesiumCameraManager::Tick(float DeltaTime) { Super::Tick(DeltaTime); }
int32 ACesiumCameraManager::AddCamera(UPARAM(ref) const FCesiumCamera& camera) {
int32 cameraId = this->_currentCameraId++;
this->_cameras.Emplace(cameraId, camera);
return cameraId;
}
bool ACesiumCameraManager::RemoveCamera(int32 cameraId) {
int32 numRemovedPairs = this->_cameras.Remove(cameraId);
bool success = numRemovedPairs > 0;
return success;
}
bool ACesiumCameraManager::UpdateCamera(
int32 cameraId,
UPARAM(ref) const FCesiumCamera& camera) {
FCesiumCamera* pCurrentCamera = this->_cameras.Find(cameraId);
if (pCurrentCamera) {
*pCurrentCamera = camera;
return true;
}
return false;
}
const TMap<int32, FCesiumCamera>& ACesiumCameraManager::GetCameras() const {
return this->_cameras;
}