diff --git a/CHANGES.md b/CHANGES.md index 2fcd28377..319018ee8 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -12,6 +12,25 @@ - The "Place Georeference Origin Here" action on CesiumGeoreference is now undoable. - Cesium Actors now have the "Is Spatially Loaded" flag disabled by default. When using World Partition, this is essential for some, such as `CesiumGeoreference`. +- The `CesiumCameraManager` instance to use with a `Cesium3DTileset` can now be specified with a property on the tileset. In addition to offering more flexibility, this avoids the work of finding the camera manager in the level every frame. +- Cesium Actors created with the Quick Add or Cesium ion panels are now created inside the active sub-level, if there is one. +- Cesium objects in sub-levels can now explicitly reference `ACesiumGeoreference`, `ACesiumCreditSystem`, and `ACesiumCameraManager` instances in the Persistent Level. + +##### Fixes :wrench: + +- Fixed a bug in `ACesiumSunSky` that could cause an error when it was created inside a sub-level. +- `ACesiumGeoreference`, `ACesiumCameraManager`, and `ACesiumCreditSystem` are now created in the Persistent Level, even if the object that triggered their automatic creation (such as `ACesium3DTileset`) exists in a sub-level. It is very rarely useful to have instances of these objects within a sub-level. +- An instance of `ACesiumCreditSystem` in a sub-level will no longer cause overlapping and broken-looking credits. However, we still recommend deleting credit system instances from sub-levels. + +### v1.29.0 - 2023-08-01 + +##### Fixes :wrench: + +- Fixed a bug introduced in v1.28.0 that prevented point clouds from rendering with attenuation. +- Fixed a bug where Google Photorealistic 3D Tiles would sometimes not render in Movie Render Queue. +- Fixed a bug that caused `UnrealLightmass` to crash when attempting to build lighting containing static meshes created by a `Cesium3DTileset`. + +In addition to the above, this release updates [cesium-native](https://github.com/CesiumGS/cesium-native) from v0.25.1 to v0.26.0. See the [changelog](https://github.com/CesiumGS/cesium-native/blob/main/CHANGES.md) for a complete list of changes in cesium-native. ### v1.28.0 - 2023-07-03 diff --git a/CesiumForUnreal.uplugin b/CesiumForUnreal.uplugin index e1aa65511..1fdbc1be1 100644 --- a/CesiumForUnreal.uplugin +++ b/CesiumForUnreal.uplugin @@ -1,7 +1,7 @@ { "FileVersion": 3, - "Version": 46, - "VersionName": "1.28.0", + "Version": 47, + "VersionName": "1.29.0", "FriendlyName": "Cesium for Unreal", "Description": "Unlock the 3D geospatial ecosystem in Unreal Engine with real-world 3D content and a high accuracy full-scale WGS84 globe.", "Category": "Geospatial", diff --git a/Shaders/Private/CesiumPointAttenuationVertexFactory.ush b/Shaders/Private/CesiumPointAttenuationVertexFactory.ush index 684d65dc8..03c77bbb4 100644 --- a/Shaders/Private/CesiumPointAttenuationVertexFactory.ush +++ b/Shaders/Private/CesiumPointAttenuationVertexFactory.ush @@ -235,15 +235,19 @@ float4 VertexFactoryGetPreviousWorldPosition(FVertexFactoryInput Input, FVertexF } float4 ApplyAttenuation(float4 WorldPosition, uint CornerIndex) { - // Unreal uses counter-clockwise winding order. + // These offsets generate the quad like so: + // 1 --- 2 + // | / | // 0 --- 3 - // | \ | - // 1 --- 2 + // Unreal uses counter-clockwise winding order, but Cesium models are created + // with a y-inverting transform. To compensate, we create the quad facing the + // wrong way, such that when the transform is applied, the quad faces the right + // way. // Results in -0.5 for 0, 1 and 0.5 for 2, 3 float OffsetX = CornerIndex / 2 - 0.5; float OffsetY = -0.5f; - if (CornerIndex == 0 || CornerIndex == 3) { + if (CornerIndex == 1 || CornerIndex == 2) { OffsetY = 0.5; } diff --git a/Source/CesiumEditor/Private/CesiumEditor.cpp b/Source/CesiumEditor/Private/CesiumEditor.cpp index 06fe89d6f..f4c31f44f 100644 --- a/Source/CesiumEditor/Private/CesiumEditor.cpp +++ b/Source/CesiumEditor/Private/CesiumEditor.cpp @@ -455,6 +455,13 @@ FCesiumEditorModule::FindFirstTilesetWithAssetID(int64_t assetID) { for (TActorIterator it(pCurrentWorld); !pTilesetActor && it; ++it) { + ACesium3DTileset* pActor = *it; + + // The existing Actor must be in the current level. Because it's sometimes + // useful to add the same tileset to multiple sub-levels. + if (!IsValid(pActor) || pActor->GetLevel() != pCurrentLevel) + continue; + const Cesium3DTilesSelection::Tileset* pTileset = it->GetTileset(); if (pTileset && it->GetIonAssetID() == assetID) { return *it; @@ -573,7 +580,7 @@ AActor* GetFirstCurrentLevelActorWithClass(UClass* pActorClass) { UWorld* pCurrentWorld = GEditor->GetEditorWorldContext().World(); ULevel* pCurrentLevel = pCurrentWorld->GetCurrentLevel(); for (TActorIterator it(pCurrentWorld); it; ++it) { - if (it->GetClass() == pActorClass) { + if (it->GetClass() == pActorClass && it->GetLevel() == pCurrentLevel) { return *it; } } @@ -602,9 +609,16 @@ AActor* SpawnActorWithClass(UClass* actorClass) { if (!actorClass) { return nullptr; } + UWorld* pCurrentWorld = GEditor->GetEditorWorldContext().World(); - AActor* pNewActor = pCurrentWorld->SpawnActor(actorClass); - return pNewActor; + ULevel* pCurrentLevel = pCurrentWorld->GetCurrentLevel(); + + return GEditor->AddActor( + pCurrentLevel, + actorClass, + FTransform(), + false, + RF_Transactional); } } // namespace diff --git a/Source/CesiumRuntime/CesiumRuntime.Build.cs b/Source/CesiumRuntime/CesiumRuntime.Build.cs index d404a738c..9cbd2b379 100644 --- a/Source/CesiumRuntime/CesiumRuntime.Build.cs +++ b/Source/CesiumRuntime/CesiumRuntime.Build.cs @@ -92,6 +92,7 @@ public CesiumRuntime(ReadOnlyTargetRules Target) : base(Target) "draco", "ktx_read", //"MikkTSpace", + "meshoptimizer", "modp_b64", "s2geometry", "spdlog", diff --git a/Source/CesiumRuntime/Private/Cesium3DTileset.cpp b/Source/CesiumRuntime/Private/Cesium3DTileset.cpp index 3832ea1be..dd2077153 100644 --- a/Source/CesiumRuntime/Private/Cesium3DTileset.cpp +++ b/Source/CesiumRuntime/Private/Cesium3DTileset.cpp @@ -114,7 +114,7 @@ ACesium3DTileset::ACesium3DTileset() ACesium3DTileset::~ACesium3DTileset() { this->DestroyTileset(); } -ACesiumGeoreference* ACesium3DTileset::GetGeoreference() const { +TSoftObjectPtr ACesium3DTileset::GetGeoreference() const { return this->Georeference; } @@ -125,7 +125,8 @@ void ACesium3DTileset::SetMobility(EComponentMobility::Type NewMobility) { } } -void ACesium3DTileset::SetGeoreference(ACesiumGeoreference* NewGeoreference) { +void ACesium3DTileset::SetGeoreference( + TSoftObjectPtr NewGeoreference) { this->Georeference = NewGeoreference; this->InvalidateResolvedGeoreference(); this->ResolveGeoreference(); @@ -136,8 +137,8 @@ ACesiumGeoreference* ACesium3DTileset::ResolveGeoreference() { return this->ResolvedGeoreference; } - if (IsValid(this->Georeference)) { - this->ResolvedGeoreference = this->Georeference; + if (IsValid(this->Georeference.Get())) { + this->ResolvedGeoreference = this->Georeference.Get(); } else { this->ResolvedGeoreference = ACesiumGeoreference::GetDefaultGeoreference(this); @@ -164,11 +165,12 @@ void ACesium3DTileset::InvalidateResolvedGeoreference() { this->ResolvedGeoreference = nullptr; } -ACesiumCreditSystem* ACesium3DTileset::GetCreditSystem() const { +TSoftObjectPtr ACesium3DTileset::GetCreditSystem() const { return this->CreditSystem; } -void ACesium3DTileset::SetCreditSystem(ACesiumCreditSystem* NewCreditSystem) { +void ACesium3DTileset::SetCreditSystem( + TSoftObjectPtr NewCreditSystem) { this->CreditSystem = NewCreditSystem; this->InvalidateResolvedCreditSystem(); this->ResolveCreditSystem(); @@ -179,8 +181,8 @@ ACesiumCreditSystem* ACesium3DTileset::ResolveCreditSystem() { return this->ResolvedCreditSystem; } - if (IsValid(this->CreditSystem)) { - this->ResolvedCreditSystem = this->CreditSystem; + if (IsValid(this->CreditSystem.Get())) { + this->ResolvedCreditSystem = this->CreditSystem.Get(); } else { this->ResolvedCreditSystem = ACesiumCreditSystem::GetDefaultCreditSystem(this); @@ -197,6 +199,38 @@ void ACesium3DTileset::InvalidateResolvedCreditSystem() { this->RefreshTileset(); } +TSoftObjectPtr +ACesium3DTileset::GetCameraManager() const { + return this->CameraManager; +} + +void ACesium3DTileset::SetCameraManager( + TSoftObjectPtr NewCameraManager) { + this->CameraManager = NewCameraManager; + this->InvalidateResolvedCameraManager(); + this->ResolveCameraManager(); +} + +ACesiumCameraManager* ACesium3DTileset::ResolveCameraManager() { + if (IsValid(this->ResolvedCameraManager)) { + return this->ResolvedCameraManager; + } + + if (IsValid(this->CameraManager.Get())) { + this->ResolvedCameraManager = this->CameraManager.Get(); + } else { + this->ResolvedCameraManager = + ACesiumCameraManager::GetDefaultCameraManager(this); + } + + return this->ResolvedCameraManager; +} + +void ACesium3DTileset::InvalidateResolvedCameraManager() { + this->ResolvedCameraManager = nullptr; + this->RefreshTileset(); +} + void ACesium3DTileset::RefreshTileset() { this->DestroyTileset(); } void ACesium3DTileset::TroubleshootToken() { @@ -572,6 +606,10 @@ void ACesium3DTileset::UpdateTransformFromCesium() { void ACesium3DTileset::BeginPlay() { Super::BeginPlay(); + this->ResolveGeoreference(); + this->ResolveCameraManager(); + this->ResolveCreditSystem(); + this->LoadTileset(); // Search for level sequence. @@ -598,6 +636,10 @@ void ACesium3DTileset::BeginPlay() { } void ACesium3DTileset::OnConstruction(const FTransform& Transform) { + this->ResolveGeoreference(); + this->ResolveCameraManager(); + this->ResolveCreditSystem(); + this->LoadTileset(); // Hide all existing tiles. The still-visible ones will be shown next time we @@ -944,8 +986,6 @@ void ACesium3DTileset::LoadTileset() { this->_encodedMetadataDescription = {}; } - ACesiumCreditSystem* pCreditSystem = this->ResolveCreditSystem(); - this->_cesiumViewExtension = cesiumViewExtension; if (GetDefault() @@ -967,6 +1007,8 @@ void ACesium3DTileset::LoadTileset() { this->BoundingVolumePoolComponent->initPool(this->OcclusionPoolSize); } + ACesiumCreditSystem* pCreditSystem = this->ResolvedCreditSystem; + Cesium3DTilesSelection::TilesetExternals externals{ pAssetAccessor, std::make_shared(this), @@ -1216,8 +1258,7 @@ std::vector ACesium3DTileset::GetCameras() const { std::make_move_iterator(editorCameras.end())); #endif - ACesiumCameraManager* pCameraManager = - ACesiumCameraManager::GetDefaultCameraManager(this->GetWorld()); + ACesiumCameraManager* pCameraManager = this->ResolvedCameraManager; if (pCameraManager) { const TMap& extraCameras = pCameraManager->GetCameras(); @@ -1929,6 +1970,10 @@ void ACesium3DTileset::Tick(float DeltaTime) { Super::Tick(DeltaTime); + this->ResolveGeoreference(); + this->ResolveCameraManager(); + this->ResolveCreditSystem(); + UCesium3DTilesetRoot* pRoot = Cast(this->RootComponent); if (!pRoot) { return; diff --git a/Source/CesiumRuntime/Private/CesiumCameraManager.cpp b/Source/CesiumRuntime/Private/CesiumCameraManager.cpp index fae98beb0..0fcaecaba 100644 --- a/Source/CesiumRuntime/Private/CesiumCameraManager.cpp +++ b/Source/CesiumRuntime/Private/CesiumCameraManager.cpp @@ -42,7 +42,8 @@ FName ACesiumCameraManager::DEFAULT_CAMERAMANAGER_TAG = actorIterator; ++actorIterator) { AActor* actor = *actorIterator; - if (actor->ActorHasTag(DEFAULT_CAMERAMANAGER_TAG)) { + if (actor->GetLevel() == world->PersistentLevel && + actor->ActorHasTag(DEFAULT_CAMERAMANAGER_TAG)) { pCameraManager = Cast(actor); break; } @@ -58,6 +59,7 @@ FName ACesiumCameraManager::DEFAULT_CAMERAMANAGER_TAG = FActorSpawnParameters spawnParameters; spawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn; + spawnParameters.OverrideLevel = world->PersistentLevel; pCameraManager = world->SpawnActor(spawnParameters); // Null check so the editor doesn't crash when it makes arbitrary calls to // this function without a valid world context object. diff --git a/Source/CesiumRuntime/Private/CesiumCreditSystem.cpp b/Source/CesiumRuntime/Private/CesiumCreditSystem.cpp index f56993170..ac1d4bc2c 100644 --- a/Source/CesiumRuntime/Private/CesiumCreditSystem.cpp +++ b/Source/CesiumRuntime/Private/CesiumCreditSystem.cpp @@ -61,6 +61,20 @@ ACesiumCreditSystem* findValidDefaultCreditSystem(ULevel* Level) { AActor* DefaultCreditSystem = *DefaultCreditSystemPtr; return Cast(DefaultCreditSystem); } + +bool checkIfInSubLevel(ACesiumCreditSystem* pCreditSystem) { + if (pCreditSystem->GetLevel() != pCreditSystem->GetWorld()->PersistentLevel) { + UE_LOG( + LogCesium, + Warning, + TEXT( + "CesiumCreditSystem should only exist in the Persistent Level. Adding it to a sub-level may cause credits to be lost.")); + return true; + } else { + return false; + } +} + } // namespace FName ACesiumCreditSystem::DEFAULT_CREDITSYSTEM_TAG = @@ -105,7 +119,8 @@ ACesiumCreditSystem::GetDefaultCreditSystem(const UObject* WorldContextObject) { actorIterator; ++actorIterator) { AActor* actor = *actorIterator; - if (actor->ActorHasTag(DEFAULT_CREDITSYSTEM_TAG)) { + if (actor->GetLevel() == world->PersistentLevel && + actor->ActorHasTag(DEFAULT_CREDITSYSTEM_TAG)) { pCreditSystem = Cast(actor); break; } @@ -131,6 +146,7 @@ ACesiumCreditSystem::GetDefaultCreditSystem(const UObject* WorldContextObject) { FActorSpawnParameters spawnParameters; spawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn; + spawnParameters.OverrideLevel = world->PersistentLevel; pCreditSystem = world->SpawnActor( Cast(CesiumCreditSystemBP), spawnParameters); @@ -162,6 +178,10 @@ ACesiumCreditSystem::ACesiumCreditSystem() void ACesiumCreditSystem::BeginPlay() { Super::BeginPlay(); + + if (checkIfInSubLevel(this)) + return; + this->updateCreditsViewport(true); } @@ -175,6 +195,9 @@ static const FName LevelEditorName("LevelEditor"); void ACesiumCreditSystem::OnConstruction(const FTransform& Transform) { Super::OnConstruction(Transform); + if (checkIfInSubLevel(this)) + return; + this->updateCreditsViewport(false); #if WITH_EDITOR diff --git a/Source/CesiumRuntime/Private/CesiumGeoreference.cpp b/Source/CesiumRuntime/Private/CesiumGeoreference.cpp index 7a6dd0e67..f77236642 100644 --- a/Source/CesiumRuntime/Private/CesiumGeoreference.cpp +++ b/Source/CesiumRuntime/Private/CesiumGeoreference.cpp @@ -74,7 +74,8 @@ ACesiumGeoreference::GetDefaultGeoreference(const UObject* WorldContextObject) { actorIterator; ++actorIterator) { AActor* actor = *actorIterator; - if (actor->ActorHasTag(DEFAULT_GEOREFERENCE_TAG)) { + if (actor->GetLevel() == world->PersistentLevel && + actor->ActorHasTag(DEFAULT_GEOREFERENCE_TAG)) { pGeoreference = Cast(actor); break; } @@ -101,6 +102,7 @@ ACesiumGeoreference::GetDefaultGeoreference(const UObject* WorldContextObject) { FActorSpawnParameters spawnParameters; spawnParameters.SpawnCollisionHandlingOverride = ESpawnActorCollisionHandlingMethod::AlwaysSpawn; + spawnParameters.OverrideLevel = world->PersistentLevel; pGeoreference = world->SpawnActor(spawnParameters); // Null check so the editor doesn't crash when it makes arbitrary calls to // this function without a valid world context object. diff --git a/Source/CesiumRuntime/Private/CesiumGlobeAnchorComponent.cpp b/Source/CesiumRuntime/Private/CesiumGlobeAnchorComponent.cpp index e1fc9992d..8950be88f 100644 --- a/Source/CesiumRuntime/Private/CesiumGlobeAnchorComponent.cpp +++ b/Source/CesiumRuntime/Private/CesiumGlobeAnchorComponent.cpp @@ -50,12 +50,13 @@ // * Ignores `AdjustOrientationForGlobeWhenMoving` because the globe position is // not changing. -ACesiumGeoreference* UCesiumGlobeAnchorComponent::GetGeoreference() const { +TSoftObjectPtr +UCesiumGlobeAnchorComponent::GetGeoreference() const { return this->Georeference; } void UCesiumGlobeAnchorComponent::SetGeoreference( - ACesiumGeoreference* NewGeoreference) { + TSoftObjectPtr NewGeoreference) { this->Georeference = NewGeoreference; this->InvalidateResolvedGeoreference(); this->ResolveGeoreference(); @@ -177,8 +178,8 @@ ACesiumGeoreference* UCesiumGlobeAnchorComponent::ResolveGeoreference() { return this->ResolvedGeoreference; } - if (IsValid(this->Georeference)) { - this->ResolvedGeoreference = this->Georeference; + if (IsValid(this->Georeference.Get())) { + this->ResolvedGeoreference = this->Georeference.Get(); } else { this->ResolvedGeoreference = ACesiumGeoreference::GetDefaultGeoreference(this); diff --git a/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp b/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp index fa81d6e16..5880bd78f 100644 --- a/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp +++ b/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp @@ -2107,6 +2107,7 @@ static void loadPrimitiveGameThreadPart( pStaticMesh->AddMaterial(pMaterial); + pStaticMesh->SetLightingGuid(); pStaticMesh->InitResources(); // Set up RenderData bounds and LOD data diff --git a/Source/CesiumRuntime/Private/CesiumSubLevelComponent.cpp b/Source/CesiumRuntime/Private/CesiumSubLevelComponent.cpp index 095f77d3b..106357bfc 100644 --- a/Source/CesiumRuntime/Private/CesiumSubLevelComponent.cpp +++ b/Source/CesiumRuntime/Private/CesiumSubLevelComponent.cpp @@ -54,12 +54,13 @@ void UCesiumSubLevelComponent::SetLoadRadius(double value) { this->LoadRadius = value; } -ACesiumGeoreference* UCesiumSubLevelComponent::GetGeoreference() const { +TSoftObjectPtr +UCesiumSubLevelComponent::GetGeoreference() const { return this->Georeference; } void UCesiumSubLevelComponent::SetGeoreference( - ACesiumGeoreference* NewGeoreference) { + TSoftObjectPtr NewGeoreference) { this->Georeference = NewGeoreference; this->InvalidateResolvedGeoreference(); @@ -81,8 +82,8 @@ ACesiumGeoreference* UCesiumSubLevelComponent::ResolveGeoreference() { return this->ResolvedGeoreference; } - if (IsValid(this->Georeference)) { - this->ResolvedGeoreference = this->Georeference; + if (IsValid(this->Georeference.Get())) { + this->ResolvedGeoreference = this->Georeference.Get(); } else { this->ResolvedGeoreference = ACesiumGeoreference::GetDefaultGeoreference(this); diff --git a/Source/CesiumRuntime/Private/CesiumSunSky.cpp b/Source/CesiumRuntime/Private/CesiumSunSky.cpp index f9eb3ee84..cf4ea34e9 100644 --- a/Source/CesiumRuntime/Private/CesiumSunSky.cpp +++ b/Source/CesiumRuntime/Private/CesiumSunSky.cpp @@ -79,7 +79,7 @@ ACesiumSunSky::ACesiumSunSky() : AActor() { DirectionalLight->SetWorldLocation(FVector(0, 0, 0)); if (!SkySphereClass) { - ConstructorHelpers::FClassFinder skySphereFinder( + static ConstructorHelpers::FClassFinder skySphereFinder( TEXT("Blueprint'/CesiumForUnreal/MobileSkySphere.MobileSkySphere_C'")); if (skySphereFinder.Succeeded()) { SkySphereClass = skySphereFinder.Class; diff --git a/Source/CesiumRuntime/Public/Cesium3DTileset.h b/Source/CesiumRuntime/Public/Cesium3DTileset.h index 668ecf70f..861e95a8b 100644 --- a/Source/CesiumRuntime/Public/Cesium3DTileset.h +++ b/Source/CesiumRuntime/Public/Cesium3DTileset.h @@ -27,6 +27,7 @@ class UMaterialInterface; class ACesiumCartographicSelection; +class ACesiumCameraManager; class UCesiumBoundingVolumePoolComponent; class CesiumViewExtension; struct FCesiumCamera; @@ -124,7 +125,7 @@ class CESIUMRUNTIME_API ACesium3DTileset : public AActor { BlueprintSetter = SetGeoreference, Category = "Cesium", Meta = (AllowPrivateAccess)) - ACesiumGeoreference* Georeference; + TSoftObjectPtr Georeference; /** * The resolved georeference used by this Tileset. This is not serialized @@ -144,11 +145,11 @@ class CESIUMRUNTIME_API ACesium3DTileset : public AActor { public: /** @copydoc ACesium3DTileset::Georeference */ UFUNCTION(BlueprintCallable, Category = "Cesium") - ACesiumGeoreference* GetGeoreference() const; + TSoftObjectPtr GetGeoreference() const; /** @copydoc ACesium3DTileset::Georeference */ UFUNCTION(BlueprintCallable, Category = "Cesium") - void SetGeoreference(ACesiumGeoreference* NewGeoreference); + void SetGeoreference(TSoftObjectPtr NewGeoreference); /** * Resolves the Cesium Georeference to use with this Actor. Returns @@ -183,7 +184,7 @@ class CESIUMRUNTIME_API ACesium3DTileset : public AActor { BlueprintSetter = SetCreditSystem, Category = "Cesium", Meta = (AllowPrivateAccess)) - ACesiumCreditSystem* CreditSystem; + TSoftObjectPtr CreditSystem; /** * The resolved Credit System used by this Tileset. This is not serialized @@ -200,6 +201,38 @@ class CESIUMRUNTIME_API ACesium3DTileset : public AActor { Meta = (AllowPrivateAccess)) ACesiumCreditSystem* ResolvedCreditSystem = nullptr; + /** + * The actor providing custom cameras for use with this Tileset. + * + * If this is null, the Tileset will find and use the first + * CesiumCameraManager Actor in the level, or create one if necessary. To get + * the active/effective Camera Manager from Blueprints or C++, use + * ResolvedCameraManager instead. + */ + UPROPERTY( + EditAnywhere, + BlueprintReadWrite, + BlueprintGetter = GetCameraManager, + BlueprintSetter = SetCameraManager, + Category = "Cesium", + Meta = (AllowPrivateAccess)) + TSoftObjectPtr CameraManager; + + /** + * The resolved Camera Manager used by this Tileset. This is not serialized + * because it may point to a Camera Manager in the PersistentLevel while this + * tileset is in a sublevel. If the CameraManager property is specified, + * however then this property will have the same value. + * + * This property will be null before ResolveCameraManager is called. + */ + UPROPERTY( + Transient, + BlueprintReadOnly, + Category = "Cesium", + Meta = (AllowPrivateAccess)) + ACesiumCameraManager* ResolvedCameraManager = nullptr; + /** * The bounding volume pool component that manages occlusion bounding volume * proxies. @@ -221,11 +254,11 @@ class CESIUMRUNTIME_API ACesium3DTileset : public AActor { public: /** @copydoc ACesium3DTileset::CreditSystem */ UFUNCTION(BlueprintCallable, Category = "Cesium") - ACesiumCreditSystem* GetCreditSystem() const; + TSoftObjectPtr GetCreditSystem() const; /** @copydoc ACesium3DTileset::CreditSystem */ UFUNCTION(BlueprintCallable, Category = "Cesium") - void SetCreditSystem(ACesiumCreditSystem* NewCreditSystem); + void SetCreditSystem(TSoftObjectPtr NewCreditSystem); /** * Resolves the Cesium Credit System to use with this Actor. Returns @@ -250,6 +283,32 @@ class CESIUMRUNTIME_API ACesium3DTileset : public AActor { UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium") bool ShowCreditsOnScreen = false; + /** @copydoc ACesium3DTileset::CameraManager */ + UFUNCTION(BlueprintGetter, Category = "Cesium") + TSoftObjectPtr GetCameraManager() const; + + /** @copydoc ACesium3DTileset::CameraManager */ + UFUNCTION(BlueprintSetter, Category = "Cesium") + void SetCameraManager(TSoftObjectPtr NewCameraManager); + + /** + * Resolves the Cesium Camera Manager to use with this Actor. Returns + * the value of the CameraManager property if it is set. Otherwise, finds a + * Camera Manager in the World and returns it, creating it if necessary. The + * resolved Camera Manager is cached so subsequent calls to this function will + * return the same instance. + */ + UFUNCTION(BlueprintCallable, Category = "Cesium") + ACesiumCameraManager* ResolveCameraManager(); + + /** + * Invalidates the cached resolved Camera Manager, setting it to null. The + * next time ResolveCameraManager is called, the Camera Manager will be + * re-resolved. + */ + UFUNCTION(BlueprintCallable, Category = "Cesium") + void InvalidateResolvedCameraManager(); + /** * The maximum number of pixels of error when rendering this tileset. * diff --git a/Source/CesiumRuntime/Public/CesiumCreditSystem.h b/Source/CesiumRuntime/Public/CesiumCreditSystem.h index 5b11eadca..2e7da6a7b 100644 --- a/Source/CesiumRuntime/Public/CesiumCreditSystem.h +++ b/Source/CesiumRuntime/Public/CesiumCreditSystem.h @@ -44,7 +44,7 @@ class CESIUMRUNTIME_API ACesiumCreditSystem : public AActor { virtual void BeginDestroy() override; UPROPERTY(EditDefaultsOnly, Category = "Cesium") - TSubclassOf CreditsWidgetClass; + TSubclassOf CreditsWidgetClass; /** * Whether the credit string has changed since last frame. diff --git a/Source/CesiumRuntime/Public/CesiumGlobeAnchorComponent.h b/Source/CesiumRuntime/Public/CesiumGlobeAnchorComponent.h index 6c0aa0e30..43310f3e8 100644 --- a/Source/CesiumRuntime/Public/CesiumGlobeAnchorComponent.h +++ b/Source/CesiumRuntime/Public/CesiumGlobeAnchorComponent.h @@ -40,7 +40,7 @@ class CESIUMRUNTIME_API UCesiumGlobeAnchorComponent : public UActorComponent { BlueprintSetter = SetGeoreference, Category = "Cesium|Georeference", Meta = (AllowPrivateAccess)) - ACesiumGeoreference* Georeference = nullptr; + TSoftObjectPtr Georeference = nullptr; /** * The resolved georeference used by this component. This is not serialized @@ -60,12 +60,12 @@ class CESIUMRUNTIME_API UCesiumGlobeAnchorComponent : public UActorComponent { public: /** @copydoc UCesiumGlobeAnchorComponent::Georeference */ - UFUNCTION(BlueprintCallable, Category = "Cesium") - ACesiumGeoreference* GetGeoreference() const; + UFUNCTION(BlueprintGetter, Category = "Cesium") + TSoftObjectPtr GetGeoreference() const; /** @copydoc UCesiumGlobeAnchorComponent::Georeference */ - UFUNCTION(BlueprintCallable, Category = "Cesium") - void SetGeoreference(ACesiumGeoreference* NewGeoreference); + UFUNCTION(BlueprintSetter, Category = "Cesium") + void SetGeoreference(TSoftObjectPtr NewGeoreference); /** * Resolves the Cesium Georeference to use with this Component. Returns diff --git a/Source/CesiumRuntime/Public/CesiumSubLevelComponent.h b/Source/CesiumRuntime/Public/CesiumSubLevelComponent.h index b6e68f0cf..cd258381b 100644 --- a/Source/CesiumRuntime/Public/CesiumSubLevelComponent.h +++ b/Source/CesiumRuntime/Public/CesiumSubLevelComponent.h @@ -145,7 +145,7 @@ class CESIUMRUNTIME_API UCesiumSubLevelComponent : public UActorComponent { * Georeference from Blueprints or C++, use ResolvedGeoreference instead. */ UFUNCTION(BlueprintGetter, Category = "Cesium") - ACesiumGeoreference* GetGeoreference() const; + TSoftObjectPtr GetGeoreference() const; /** * Sets the designated georeference actor controlling how the actor's @@ -157,7 +157,7 @@ class CESIUMRUNTIME_API UCesiumSubLevelComponent : public UActorComponent { * Georeference from Blueprints or C++, use ResolvedGeoreference instead. */ UFUNCTION(BlueprintSetter, Category = "Cesium") - void SetGeoreference(ACesiumGeoreference* NewGeoreference); + void SetGeoreference(TSoftObjectPtr NewGeoreference); /** * Gets the resolved georeference, just like calling the ResolveGeoreference @@ -335,7 +335,7 @@ class CESIUMRUNTIME_API UCesiumSubLevelComponent : public UActorComponent { BlueprintSetter = SetGeoreference, Category = "Cesium", Meta = (AllowPrivateAccess)) - ACesiumGeoreference* Georeference; + TSoftObjectPtr Georeference; /** * The resolved georeference used by this sub-level. This is not serialized diff --git a/extern/cesium-native b/extern/cesium-native index b726f30ad..ecd215bdd 160000 --- a/extern/cesium-native +++ b/extern/cesium-native @@ -1 +1 @@ -Subproject commit b726f30ad301c38772572967f7e21ce60008f538 +Subproject commit ecd215bddc649302a042d19ad5ddf8fd0f05076d diff --git a/package.json b/package.json index a54603440..407e0dd3e 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "cesium-unreal", - "version": "1.28.0", + "version": "1.29.0", "description": "Cesium for Unreal", "main": "index.js", "directories": {