diff --git a/CHANGES.md b/CHANGES.md index e6bab36b1..179b761cd 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -5,6 +5,7 @@ ##### Additions :tada: - Added support for `TRIANGLE_FAN` primitives in tile meshes. +- Added an optional glTF model post-processing stage after the tile loading step, before the tile can be displayed. ##### Fixes :wrench: diff --git a/Source/CesiumRuntime/Private/Cesium3DTileset.cpp b/Source/CesiumRuntime/Private/Cesium3DTileset.cpp index 2dedccb28..6f15e4419 100644 --- a/Source/CesiumRuntime/Private/Cesium3DTileset.cpp +++ b/Source/CesiumRuntime/Private/Cesium3DTileset.cpp @@ -5,6 +5,7 @@ #include "Camera/CameraTypes.h" #include "Camera/PlayerCameraManager.h" #include "Cesium3DTilesSelection/EllipsoidTilesetLoader.h" +#include "Cesium3DTilesSelection/GltfModifier.h" #include "Cesium3DTilesSelection/Tile.h" #include "Cesium3DTilesSelection/TilesetLoadFailureDetails.h" #include "Cesium3DTilesSelection/TilesetOptions.h" @@ -992,7 +993,10 @@ void ACesium3DTileset::LoadTileset() { ->EnableExperimentalOcclusionCullingFeature && this->EnableOcclusionCulling && this->BoundingVolumePoolComponent) ? this->BoundingVolumePoolComponent->getPool() - : nullptr}; + : nullptr, + {}, + _gltfModifier + }; this->_startTime = std::chrono::high_resolution_clock::now(); @@ -2325,3 +2329,8 @@ void ACesium3DTileset::RuntimeSettingsChanged( } } #endif + +void ACesium3DTileset::SetGltfModifier( + const std::shared_ptr& InModifier) { + _gltfModifier = InModifier; +} diff --git a/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp b/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp index 495f52444..25387930f 100644 --- a/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp +++ b/Source/CesiumRuntime/Private/CesiumGltfComponent.cpp @@ -3440,7 +3440,7 @@ UCesiumGltfComponent::CreateOffGameThread( UMaterialInterface* pBaseTranslucentMaterial, UMaterialInterface* pBaseWaterMaterial, FCustomDepthParameters CustomDepthParameters, - const Cesium3DTilesSelection::Tile& tile, + Cesium3DTilesSelection::Tile& tile, bool createNavCollision) { TRACE_CPUPROFILER_EVENT_SCOPE(Cesium::LoadModel) @@ -3454,6 +3454,7 @@ UCesiumGltfComponent::CreateOffGameThread( // } UCesiumGltfComponent* Gltf = NewObject(pTilesetActor); + Gltf->pTile = &tile; Gltf->SetMobility(pTilesetActor->GetRootComponent()->Mobility); Gltf->SetFlags(RF_Transient | RF_DuplicateTransient | RF_TextExportTransient); @@ -3535,6 +3536,13 @@ UCesiumGltfComponent::UCesiumGltfComponent() : USceneComponent() { PrimaryComponentTick.bCanEverTick = false; } +const CesiumGltf::Model* UCesiumGltfComponent::GetGltfModel() const { + if (pTile) + if (auto RenderContent = pTile->getContent().getRenderContent()) + return &RenderContent->getModel(); + return nullptr; +} + void UCesiumGltfComponent::UpdateTransformFromCesium( const glm::dmat4& cesiumToUnrealTransform) { for (USceneComponent* pSceneComponent : this->GetAttachChildren()) { diff --git a/Source/CesiumRuntime/Private/CesiumGltfComponent.h b/Source/CesiumRuntime/Private/CesiumGltfComponent.h index 848a82e5f..cdef417aa 100644 --- a/Source/CesiumRuntime/Private/CesiumGltfComponent.h +++ b/Source/CesiumRuntime/Private/CesiumGltfComponent.h @@ -5,6 +5,7 @@ #include "Cesium3DTilesSelection/Tile.h" #include "Cesium3DTileset.h" #include "CesiumEncodedMetadataUtility.h" +#include "CesiumLoadedTile.h" #include "CesiumModelMetadata.h" #include "Components/PrimitiveComponent.h" #include "Components/SceneComponent.h" @@ -56,7 +57,7 @@ struct FRasterOverlayTile { }; UCLASS() -class UCesiumGltfComponent : public USceneComponent { +class UCesiumGltfComponent : public USceneComponent, public ICesiumLoadedTile { GENERATED_BODY() public: @@ -87,7 +88,7 @@ class UCesiumGltfComponent : public USceneComponent { UMaterialInterface* BaseTranslucentMaterial, UMaterialInterface* BaseWaterMaterial, FCustomDepthParameters CustomDepthParameters, - const Cesium3DTilesSelection::Tile& tile, + Cesium3DTilesSelection::Tile& tile, bool createNavCollision); UCesiumGltfComponent(); @@ -104,6 +105,8 @@ class UCesiumGltfComponent : public USceneComponent { UPROPERTY(EditAnywhere, Category = "Rendering") FCustomDepthParameters CustomDepthParameters{}; + Cesium3DTilesSelection::Tile* pTile = nullptr; + FCesiumModelMetadata Metadata{}; EncodedFeaturesMetadata::EncodedModelMetadata EncodedMetadata{}; @@ -132,6 +135,9 @@ class UCesiumGltfComponent : public USceneComponent { virtual void BeginDestroy() override; + // from ICesiumLoadedTile + const CesiumGltf::Model* GetGltfModel() const override; + void UpdateFade(float fadePercentage, bool fadingIn); private: diff --git a/Source/CesiumRuntime/Public/Cesium3DTileset.h b/Source/CesiumRuntime/Public/Cesium3DTileset.h index ce26a4617..8256d0a8d 100644 --- a/Source/CesiumRuntime/Public/Cesium3DTileset.h +++ b/Source/CesiumRuntime/Public/Cesium3DTileset.h @@ -39,6 +39,7 @@ class CesiumViewExtension; struct FCesiumCamera; namespace Cesium3DTilesSelection { +class GltfModifier; class Tileset; class TilesetView; class TileOcclusionRendererProxyPool; @@ -1257,6 +1258,15 @@ class CESIUMRUNTIME_API ACesium3DTileset : public AActor { */ void UpdateTransformFromCesium(); + /** + * Sets the glTF modifier, an optional extension class that can edit + * each tile's glTF model after it has been loaded, before it can be + * displayed. Can only be called in the same engine tick after the tileset + * actor was spawned, or {@link RefreshTileset} was called. + */ + void SetGltfModifier( + const std::shared_ptr& InModifier); + private: /** * The event handler for ACesiumGeoreference::OnEllipsoidChanged. @@ -1371,6 +1381,8 @@ class CESIUMRUNTIME_API ACesium3DTileset : public AActor { int32 _tilesetsBeingDestroyed; + std::shared_ptr _gltfModifier; + friend class UnrealPrepareRendererResources; friend class UCesiumGltfPointsComponent; }; diff --git a/Source/CesiumRuntime/Public/CesiumLoadedTile.h b/Source/CesiumRuntime/Public/CesiumLoadedTile.h new file mode 100644 index 000000000..d8d53f5f7 --- /dev/null +++ b/Source/CesiumRuntime/Public/CesiumLoadedTile.h @@ -0,0 +1,21 @@ +// Copyright 2020-2024 CesiumGS, Inc. and Contributors + +#pragma once + +#include "UObject/ObjectMacros.h" + +#include "CesiumLoadedTile.generated.h" + +namespace CesiumGltf { +struct Model; +} + +UINTERFACE() +class UCesiumLoadedTile : public UInterface { + GENERATED_BODY() +}; +class ICesiumLoadedTile { + GENERATED_BODY() +public: + virtual const CesiumGltf::Model* GetGltfModel() const = 0; +}; diff --git a/extern/cesium-native b/extern/cesium-native index 790bb78b8..c5fc64121 160000 --- a/extern/cesium-native +++ b/extern/cesium-native @@ -1 +1 @@ -Subproject commit 790bb78b860af84a617389cd9a30aa46d129b542 +Subproject commit c5fc641212cc2bec96dc4e748ab6e5212dea19e3