Skip to content

Commit

Permalink
Merge pull request #1229 from CesiumGS/more-tweaks
Browse files Browse the repository at this point in the history
Usability improvements for CesiumGeoreference parentage
  • Loading branch information
kring authored Oct 1, 2023
2 parents 14823c7 + d8b2fb4 commit 3673cb3
Show file tree
Hide file tree
Showing 17 changed files with 340 additions and 160 deletions.
3 changes: 3 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,9 @@
- Added `CesiumOriginShiftComponent`. In addition to triggering transitions between sub-levels, this component optionally allows the Unreal world origin to be shifted as the Actor to which it is attached moves. The shifting may be done by either changing the `CesiumGeoreference` origin or by setting Unreal's `OriginLocation` property.
- Sub-level transitions can now be triggered manually from Blueprints using functions on the `CesiumSubLevelSwitcherComponent` attached to the `CesiumGeoreference`. Be sure to disable any `CesiumOriginShiftComponent` instances in your level if you want manual control of sub-level switching.
- Added `CesiumFlyToComponent` to allow animated flights of any Actor or Pawn.
- Globe aware objects now find their associated CesiumGeoreference by using `ACesiumGeoreference::GetDefaultDefaultGeoreferenceForActor`, which checks first for an attachment parent that is a CesiumGeoreference. This way a `Cesium3DTileset` or similar object will by associated with the CesiumGeoreference it is nested inside by default.
- The Quick Add panel now creates Actors nested inside a `CesiumGeoreference`.
- The `ResolvedGeoreference` is now shown in the Editor Details UI for georeferenced objects, next to the `Georeference` property.

##### Fixes :wrench:

Expand Down
36 changes: 35 additions & 1 deletion Source/CesiumEditor/Private/CesiumEditor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#include "CesiumEditor.h"
#include "Cesium3DTilesSelection/Tileset.h"
#include "Cesium3DTileset.h"
#include "CesiumCartographicPolygon.h"
#include "CesiumCommands.h"
#include "CesiumGeoreferenceCustomization.h"
#include "CesiumGlobeAnchorCustomization.h"
Expand Down Expand Up @@ -520,12 +521,24 @@ FCesiumEditorModule::CreateTileset(const std::string& name, int64_t assetID) {
UWorld* pCurrentWorld = GEditor->GetEditorWorldContext().World();
ULevel* pCurrentLevel = pCurrentWorld->GetCurrentLevel();

ACesiumGeoreference* Georeference =
ACesiumGeoreference::GetDefaultGeoreference(pCurrentWorld);

AActor* pNewActor = GEditor->AddActor(
pCurrentLevel,
ACesium3DTileset::StaticClass(),
FTransform(),
false,
RF_Transactional);

// Make the new Tileset a child of the CesiumGeoreference. Unless they're in
// different levels.
if (Georeference->GetLevel() == pCurrentLevel) {
pNewActor->AttachToActor(
Georeference,
FAttachmentTransformRules::KeepRelativeTransform);
}

ACesium3DTileset* pTilesetActor = Cast<ACesium3DTileset>(pNewActor);
pTilesetActor->SetActorLabel(UTF8_TO_TCHAR(name.c_str()));
if (assetID != -1) {
Expand Down Expand Up @@ -657,12 +670,25 @@ AActor* SpawnActorWithClass(UClass* actorClass) {
UWorld* pCurrentWorld = GEditor->GetEditorWorldContext().World();
ULevel* pCurrentLevel = pCurrentWorld->GetCurrentLevel();

return GEditor->AddActor(
ACesiumGeoreference* Georeference =
ACesiumGeoreference::GetDefaultGeoreference(pCurrentWorld);

AActor* NewActor = GEditor->AddActor(
pCurrentLevel,
actorClass,
FTransform(),
false,
RF_Transactional);

// Make the new Actor a child of the CesiumGeoreference. Unless they're in
// different levels.
if (Georeference->GetLevel() == pCurrentLevel) {
NewActor->AttachToActor(
Georeference,
FAttachmentTransformRules::KeepRelativeTransform);
}

return NewActor;
}
} // namespace

Expand All @@ -686,6 +712,14 @@ UClass* FCesiumEditorModule::GetCesiumSunSkyClass() {
return ACesiumSunSky::StaticClass();
}

AActor* FCesiumEditorModule::SpawnBlankTileset() {
return SpawnActorWithClass(ACesium3DTileset::StaticClass());
}

AActor* FCesiumEditorModule::SpawnCartographicPolygon() {
return SpawnActorWithClass(ACesiumCartographicPolygon::StaticClass());
}

UClass* FCesiumEditorModule::GetDynamicPawnBlueprintClass() {
static UClass* pResult = nullptr;

Expand Down
14 changes: 14 additions & 0 deletions Source/CesiumEditor/Private/CesiumEditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

#pragma once

#include "CesiumEditorReparentHandler.h"
#include "CesiumEditorSubLevelMutex.h"
#include "CesiumIonSession.h"
#include "CoreMinimal.h"
Expand Down Expand Up @@ -85,6 +86,18 @@ class FCesiumEditorModule : public IModuleInterface {
*/
static AActor* SpawnDynamicPawn();

/**
* Spawns a new Cesium3DTileset with default values in the current level of
* the edited world.
*/
static AActor* SpawnBlankTileset();

/**
* Spawns a new CesiumCartographicPolygon in the current level of the edited
* world.
*/
static AActor* SpawnCartographicPolygon();

private:
TSharedRef<SDockTab> SpawnCesiumTab(const FSpawnTabArgs& TabSpawnArgs);
TSharedRef<SDockTab>
Expand All @@ -103,6 +116,7 @@ class FCesiumEditorModule : public IModuleInterface {
FDelegateHandle _rasterOverlayIonTroubleshootingSubscription;

CesiumEditorSubLevelMutex _subLevelMutex;
CesiumEditorReparentHandler _reparentHandler;

static TSharedPtr<FSlateStyleSet> StyleSet;
static FCesiumEditorModule* _pModule;
Expand Down
43 changes: 43 additions & 0 deletions Source/CesiumEditor/Private/CesiumEditorReparentHandler.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
// Copyright 2020-2023 CesiumGS, Inc. and Contributors

#include "CesiumEditorReparentHandler.h"
#include "Cesium3DTileset.h"
#include "CesiumGlobeAnchorComponent.h"
#include "CesiumSubLevelComponent.h"
#include "Engine/Engine.h"

CesiumEditorReparentHandler::CesiumEditorReparentHandler() {
if (GEngine) {
this->_subscription = GEngine->OnLevelActorAttached().AddRaw(
this,
&CesiumEditorReparentHandler::OnLevelActorAttached);
}
}

CesiumEditorReparentHandler::~CesiumEditorReparentHandler() {
if (GEngine) {
GEngine->OnLevelActorAttached().Remove(this->_subscription);
this->_subscription.Reset();
}
}

void CesiumEditorReparentHandler::OnLevelActorAttached(
AActor* Actor,
const AActor* Parent) {
ACesium3DTileset* Tileset = Cast<ACesium3DTileset>(Actor);
if (IsValid(Tileset)) {
Tileset->InvalidateResolvedGeoreference();
}

UCesiumGlobeAnchorComponent* GlobeAnchor =
Actor->FindComponentByClass<UCesiumGlobeAnchorComponent>();
if (IsValid(GlobeAnchor)) {
GlobeAnchor->ResolveGeoreference(true);
}

UCesiumSubLevelComponent* SubLevel =
Actor->FindComponentByClass<UCesiumSubLevelComponent>();
if (IsValid(SubLevel)) {
SubLevel->ResolveGeoreference(true);
}
}
24 changes: 24 additions & 0 deletions Source/CesiumEditor/Private/CesiumEditorReparentHandler.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
// Copyright 2020-2023 CesiumGS, Inc. and Contributors

#pragma once

#include "Delegates/IDelegateInstance.h"

class AActor;

/**
* Detects when Actors are reparented in the Editor by subscribing to
* GEngine::OnLevelActorAttached and handling it appropriately. For example,
* when a Cesium3DTileset's parent changes, we need to re-resolve its
* CesiumGeoreference.
*/
class CesiumEditorReparentHandler {
public:
CesiumEditorReparentHandler();
~CesiumEditorReparentHandler();

private:
void OnLevelActorAttached(AActor* Actor, const AActor* Parent);

FDelegateHandle _subscription;
};
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,9 @@ void FCesiumGlobeAnchorCustomization::CustomizeDetails(

CesiumCategory.AddProperty(
GET_MEMBER_NAME_CHECKED(UCesiumGlobeAnchorComponent, Georeference));
CesiumCategory.AddProperty(GET_MEMBER_NAME_CHECKED(
UCesiumGlobeAnchorComponent,
ResolvedGeoreference));
CesiumCategory.AddProperty(GET_MEMBER_NAME_CHECKED(
UCesiumGlobeAnchorComponent,
AdjustOrientationForGlobeWhenMoving));
Expand Down
28 changes: 2 additions & 26 deletions Source/CesiumEditor/Private/IonQuickAddPanel.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -254,18 +254,6 @@ void IonQuickAddPanel::AddCesiumSunSkyToLevel() {
}
}

void IonQuickAddPanel::AddCartographicPolygonToLevel() {
UWorld* pCurrentWorld = GEditor->GetEditorWorldContext().World();
ULevel* pCurrentLevel = pCurrentWorld->GetCurrentLevel();

GEditor->AddActor(
pCurrentLevel,
ACesiumCartographicPolygon::StaticClass(),
FTransform(),
false,
RF_Transactional);
}

namespace {
/**
* Set a byte property value in the given object.
Expand Down Expand Up @@ -330,18 +318,6 @@ void IonQuickAddPanel::AddDynamicPawnToLevel() {
}
}

void IonQuickAddPanel::AddBlankTilesetToLevel() {
UWorld* pCurrentWorld = GEditor->GetEditorWorldContext().World();
ULevel* pCurrentLevel = pCurrentWorld->GetCurrentLevel();

GEditor->AddActor(
pCurrentLevel,
ACesium3DTileset::StaticClass(),
FTransform(),
false,
RF_Transactional);
}

void IonQuickAddPanel::AddItemToLevel(TSharedRef<QuickAddItem> item) {
if (this->_itemsBeingAdded.find(item->name) != this->_itemsBeingAdded.end()) {
// Add is already in progress.
Expand All @@ -357,7 +333,7 @@ void IonQuickAddPanel::AddItemToLevel(TSharedRef<QuickAddItem> item) {
bool isBlankTileset = item->type == QuickAddItemType::TILESET &&
item->tilesetID == -1 && item->overlayID == -1;
if (isBlankTileset) {
AddBlankTilesetToLevel();
FCesiumEditorModule::SpawnBlankTileset();
this->_itemsBeingAdded.erase(item->name);
} else {
AddIonTilesetToLevel(item);
Expand All @@ -369,7 +345,7 @@ void IonQuickAddPanel::AddItemToLevel(TSharedRef<QuickAddItem> item) {
AddDynamicPawnToLevel();
this->_itemsBeingAdded.erase(item->name);
} else if (item->type == QuickAddItemType::CARTOGRAPHIC_POLYGON) {
AddCartographicPolygonToLevel();
FCesiumEditorModule::SpawnCartographicPolygon();
this->_itemsBeingAdded.erase(item->name);
}
}
2 changes: 0 additions & 2 deletions Source/CesiumEditor/Private/IonQuickAddPanel.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,9 @@ class IonQuickAddPanel : public SCompoundWidget {
const TSharedRef<STableViewBase>& list);

void AddItemToLevel(TSharedRef<QuickAddItem> item);
void AddBlankTilesetToLevel();
void AddIonTilesetToLevel(TSharedRef<QuickAddItem> item);
void AddCesiumSunSkyToLevel();
void AddDynamicPawnToLevel();
void AddCartographicPolygonToLevel();

TArray<TSharedRef<QuickAddItem>> _quickAddItems;
std::unordered_set<std::string> _itemsBeingAdded;
Expand Down
2 changes: 1 addition & 1 deletion Source/CesiumRuntime/Private/Cesium3DTileset.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ ACesiumGeoreference* ACesium3DTileset::ResolveGeoreference() {
this->ResolvedGeoreference = this->Georeference.Get();
} else {
this->ResolvedGeoreference =
ACesiumGeoreference::GetDefaultGeoreference(this);
ACesiumGeoreference::GetDefaultGeoreferenceForActor(this);
}

UCesium3DTilesetRoot* pRoot = Cast<UCesium3DTilesetRoot>(this->RootComponent);
Expand Down
Loading

0 comments on commit 3673cb3

Please sign in to comment.