Skip to content

Commit

Permalink
Backward compatibility for CesiumGeoreference -> CesiumOriginShift.
Browse files Browse the repository at this point in the history
  • Loading branch information
kring committed Sep 13, 2023
1 parent 5d63d4e commit f7e2bfc
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 19 deletions.
Binary file modified Content/DynamicPawn.uasset
Binary file not shown.
112 changes: 94 additions & 18 deletions Source/CesiumRuntime/Private/CesiumGeoreference.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,9 @@
#include "Camera/PlayerCameraManager.h"
#include "CesiumActors.h"
#include "CesiumCommon.h"
#include "CesiumCustomVersion.h"
#include "CesiumGeospatial/Cartographic.h"
#include "CesiumOriginShiftComponent.h"
#include "CesiumRuntime.h"
#include "CesiumSubLevelComponent.h"
#include "CesiumSubLevelSwitcherComponent.h"
Expand Down Expand Up @@ -410,6 +412,8 @@ void ACesiumGeoreference::Tick(float DeltaTime) {
void ACesiumGeoreference::Serialize(FArchive& Ar) {
Super::Serialize(Ar);

Ar.UsingCustomVersion(FCesiumCustomVersion::GUID);

// Recompute derived values on load.
if (Ar.IsLoading()) {
this->_updateCoordinateSystem();
Expand All @@ -430,22 +434,6 @@ void ACesiumGeoreference::BeginPlay() {
return;
}

if (!this->SubLevelCamera) {
// Find the first player's camera manager
APlayerController* pPlayerController = pWorld->GetFirstPlayerController();
if (pPlayerController) {
this->SubLevelCamera = pPlayerController->PlayerCameraManager;
}

if (!this->SubLevelCamera) {
UE_LOG(
LogCesium,
Warning,
TEXT(
"CesiumGeoreference could not find a FirstPlayerController or a corresponding PlayerCameraManager."));
}
}

UpdateGeoreference();
}

Expand All @@ -472,6 +460,94 @@ void ACesiumGeoreference::PostLoad() {
!this->GetWorld()->IsGameWorld()) {
this->_createSubLevelsFromWorldComposition();
}

const int32 CesiumVersion =
this->GetLinkerCustomVersion(FCesiumCustomVersion::GUID);

if (CesiumVersion < FCesiumCustomVersion::OriginShiftComponent &&
!this->SubLevelSwitcher->GetRegisteredSubLevelsWeak().IsEmpty()) {
// In previous versions, the CesiumGeoreference managed origin shifting
// based on a SubLevelCamera, which defaulted to the PlayerCameraManager of
// the World's `GetFirstPlayerController()`.

// Backward compatibility for this is tricky, but we can make a decent
// attempt that will work in a lot of cases. And this is just an unfortunate
// v2.0 breakage for any remaining cases.

AActor* SubLevelActor = nullptr;

if (this->SubLevelCamera) {
// An explicit SubLevelCamera is specified. If it has a target Actor,
// attach a CesiumOriginShiftComponent to that Actor.
SubLevelActor = this->SubLevelCamera->ViewTarget.Target.Get();

if (!SubLevelActor) {
UE_LOG(
LogCesium,
Warning,
TEXT("An explicit SubLevelCamera was specified on this "
"CesiumGeoreference, but its ViewTarget is not a valid "
"Actor, so a CesiumOriginShiftComponent could not be added "
"automatically. You must manually add a "
"CesiumOriginShiftComponent to the Actor whose position "
"should be used to control sub-level switching."));
}
} else {
// No explicit SubLevelCamera, so try to find a Pawn set to auto-possess
// player 0.
for (TActorIterator<APawn> it(
GetWorld(),
APawn::StaticClass(),
EActorIteratorFlags::SkipPendingKill);
it;
++it) {
if (it->AutoPossessPlayer == EAutoReceiveInput::Player0) {
SubLevelActor = *it;
break;
}
}

if (!SubLevelActor) {
UE_LOG(
LogCesium,
Warning,
TEXT(
"Could not find a Pawn in the level set to auto-possess player "
"0, so a CesiumOriginShiftComponent could not be added "
"automatically. You must manually add a "
"CesiumOriginShiftComponent to the Actor whose position "
"should be used to control sub-level switching."));
}
}

if (SubLevelActor) {
// If this is a Blueprint object, like DynamicPawn, its construction
// scripts may not have been run yet at this point. Doing so might cause
// an origin shift component to be added. So we force it to happen here so
// that we don't end up adding a duplicate CesiumOriginShiftComponent.
SubLevelActor->RerunConstructionScripts();
if (SubLevelActor->FindComponentByClass<UCesiumOriginShiftComponent>() ==
nullptr) {

UCesiumOriginShiftComponent* OriginShift =
Cast<UCesiumOriginShiftComponent>(
SubLevelActor->AddComponentByClass(
UCesiumOriginShiftComponent::StaticClass(),
false,
FTransform::Identity,
false));
OriginShift->SetFlags(RF_Transactional);
SubLevelActor->AddInstanceComponent(OriginShift);

UE_LOG(
LogCesium,
Warning,
TEXT("Added CesiumOriginShiftComponent to %s in order to preserve "
"backward compatibility for sub-level switching."),
*SubLevelActor->GetName());
}
}
}
#endif // WITH_EDITOR
}

Expand Down Expand Up @@ -582,8 +658,8 @@ void ACesiumGeoreference::_createSubLevelsFromWorldComposition() {
pLevelComponent->SetEnabled(pFound->Enabled);
pLevelComponent->SetLoadRadius(pFound->LoadRadius);

// But if the georeference origin is close to this sub-level's origin, make
// this the active sub-level.
// But if the georeference origin is close to this sub-level's origin,
// make this the active sub-level.
if (FMath::IsNearlyEqual(
this->OriginLongitude,
pFound->LevelLongitude,
Expand Down
4 changes: 4 additions & 0 deletions Source/CesiumRuntime/Private/CesiumOriginShiftComponent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
UCesiumOriginShiftComponent::UCesiumOriginShiftComponent() : Super() {
this->PrimaryComponentTick.bCanEverTick = true;
this->PrimaryComponentTick.TickGroup = ETickingGroup::TG_PrePhysics;
this->bAutoActivate = true;
}

void UCesiumOriginShiftComponent::OnRegister() {
Expand All @@ -33,6 +34,9 @@ void UCesiumOriginShiftComponent::TickComponent(
FActorComponentTickFunction* ThisTickFunction) {
Super::TickComponent(DeltaTime, TickType, ThisTickFunction);

if (!this->IsActive())
return;

if (!this->GlobeAnchor)
return;

Expand Down
4 changes: 4 additions & 0 deletions Source/CesiumRuntime/Public/CesiumCustomVersion.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,10 @@ struct CESIUMRUNTIME_API FCesiumCustomVersion {
// an array of doubles to being an FMatrix.
GlobeAnchorTransformationAsFMatrix = 4,

// The origin shifting behavior became an independent component rather than
// built into the CesiumGeoreference.
OriginShiftComponent = 5,

VersionPlusOne,
LatestVersion = VersionPlusOne - 1
};
Expand Down
2 changes: 1 addition & 1 deletion Source/CesiumRuntime/Public/CesiumOriginShiftComponent.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class CESIUMRUNTIME_API UCesiumOriginShiftComponent : public UActorComponent {
virtual void BeginPlay() override;
virtual void TickComponent(
float DeltaTime,
enum ELevelTick TickType,
ELevelTick TickType,
FActorComponentTickFunction* ThisTickFunction) override;

private:
Expand Down

0 comments on commit f7e2bfc

Please sign in to comment.