bmh/FlightSimulation/Plugins/CesiumForUnreal_5.4/Source/CesiumRuntime/Public/Cesium3DTileset.h

1315 lines
46 KiB
C
Raw Normal View History

2025-02-07 14:52:32 +00:00
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "Cesium3DTilesSelection/Tileset.h"
#include "Cesium3DTilesSelection/ViewState.h"
#include "Cesium3DTilesSelection/ViewUpdateResult.h"
#include "Cesium3DTilesetLoadFailureDetails.h"
#include "CesiumCreditSystem.h"
#include "CesiumEncodedMetadataComponent.h"
#include "CesiumFeaturesMetadataComponent.h"
#include "CesiumGeoreference.h"
#include "CesiumIonServer.h"
#include "CesiumPointCloudShading.h"
#include "CesiumSampleHeightResult.h"
#include "CoreMinimal.h"
#include "CustomDepthParameters.h"
#include "Engine/EngineTypes.h"
#include "GameFramework/Actor.h"
#include "Interfaces/IHttpRequest.h"
#include "PrimitiveSceneProxy.h"
#include <PhysicsEngine/BodyInstance.h>
#include <atomic>
#include <chrono>
#include <glm/mat4x4.hpp>
#include <unordered_map>
#include <vector>
#include "Cesium3DTileset.generated.h"
#ifdef CESIUM_DEBUG_TILE_STATES
#include <Cesium3DTilesSelection/DebugTileStateDatabase.h>
#endif
class UMaterialInterface;
class ACesiumCartographicSelection;
class ACesiumCameraManager;
class UCesiumBoundingVolumePoolComponent;
class CesiumViewExtension;
struct FCesiumCamera;
namespace Cesium3DTilesSelection {
class Tileset;
class TilesetView;
class TileOcclusionRendererProxyPool;
} // namespace Cesium3DTilesSelection
/**
* The delegate for OnCesium3DTilesetLoadFailure, which is triggered when
* the tileset encounters a load error.
*/
DECLARE_MULTICAST_DELEGATE_OneParam(
FCesium3DTilesetLoadFailure,
const FCesium3DTilesetLoadFailureDetails&);
DECLARE_DELEGATE_ThreeParams(
FCesiumSampleHeightMostDetailedCallback,
ACesium3DTileset*,
const TArray<FCesiumSampleHeightResult>&,
const TArray<FString>&);
/**
* The delegate for the Acesium3DTileset::OnTilesetLoaded,
* which is triggered from UpdateLoadStatus
*/
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FCompletedLoadTrigger);
CESIUMRUNTIME_API extern FCesium3DTilesetLoadFailure
OnCesium3DTilesetLoadFailure;
UENUM(BlueprintType)
enum class ETilesetSource : uint8 {
/**
* The tileset will be loaded from Cesium Ion using the provided IonAssetID
* and IonAccessToken.
*/
FromCesiumIon UMETA(DisplayName = "From Cesium Ion"),
/**
* The tileset will be loaded from the specified Url.
*/
FromUrl UMETA(DisplayName = "From Url"),
/**
* The tileset will be loaded from the georeference ellipsoid.
*/
FromEllipsoid UMETA(DisplayName = "From Ellipsoid")
};
UENUM(BlueprintType)
enum class EApplyDpiScaling : uint8 { Yes, No, UseProjectDefault };
UCLASS()
class CESIUMRUNTIME_API ACesium3DTileset : public AActor {
GENERATED_BODY()
public:
ACesium3DTileset();
virtual ~ACesium3DTileset();
private:
UPROPERTY(VisibleAnywhere, Category = "Cesium") USceneComponent* Root;
UPROPERTY(
Meta =
(AllowPrivateAccess,
DeprecatedProperty,
DeprecationMessage =
"Use the Mobility property on the RootComponent instead."))
TEnumAsByte<EComponentMobility::Type> Mobility_DEPRECATED =
EComponentMobility::Static;
public:
UFUNCTION(BlueprintCallable, meta = (DeprecatedFunction))
EComponentMobility::Type GetMobility() const {
return this->RootComponent->Mobility;
}
UFUNCTION(BlueprintCallable, meta = (DeprecatedFunction))
void SetMobility(EComponentMobility::Type NewMobility);
/**
* @brief Initiates an asynchronous query for the height of this tileset at a
* list of cartographic positions, where the Longitude (X) and Latitude (Y)
* are given in degrees. The most detailed available tiles are used to
* determine each height.
*
* The height of the input positions is ignored, unless height sampling fails
* at that location. The output height is expressed in meters above the
* ellipsoid (usually WGS84), which should not be confused with a height above
* mean sea level.
*
* @param LongitudeLatitudeHeightArray The cartographic positions for which to
* sample heights. The Longitude (X) and Latitude (Y) are expressed in
* degrees, while Height (Z) is given in meters.
* @param OnHeightsSampled A callback that is invoked in the game thread when
* heights have been sampled for all positions.
*/
void SampleHeightMostDetailed(
const TArray<FVector>& LongitudeLatitudeHeightArray,
FCesiumSampleHeightMostDetailedCallback OnHeightsSampled);
private:
/**
* The designated georeference actor controlling how the actor's
* coordinate system relates to the coordinate system in this Unreal Engine
* level.
*
* If this is null, the Tileset will find and use the first Georeference
* Actor in the level, or create one if necessary. To get the active/effective
* Georeference from Blueprints or C++, use ResolvedGeoreference instead.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
BlueprintGetter = GetGeoreference,
BlueprintSetter = SetGeoreference,
Category = "Cesium",
Meta = (AllowPrivateAccess))
TSoftObjectPtr<ACesiumGeoreference> Georeference;
/**
* The resolved georeference used by this Tileset. This is not serialized
* because it may point to a Georeference in the PersistentLevel while this
* tileset is in a sublevel. If the Georeference property is specified,
* however then this property will have the same value.
*
* This property will be null before ResolveGeoreference is called.
*/
UPROPERTY(
Transient,
VisibleAnywhere,
BlueprintReadOnly,
Category = "Cesium",
Meta = (AllowPrivateAccess))
ACesiumGeoreference* ResolvedGeoreference = nullptr;
public:
/** @copydoc ACesium3DTileset::Georeference */
UFUNCTION(BlueprintCallable, Category = "Cesium")
TSoftObjectPtr<ACesiumGeoreference> GetGeoreference() const;
/** @copydoc ACesium3DTileset::Georeference */
UFUNCTION(BlueprintCallable, Category = "Cesium")
void SetGeoreference(TSoftObjectPtr<ACesiumGeoreference> NewGeoreference);
/**
* Resolves the Cesium Georeference to use with this Actor. Returns
* the value of the Georeference property if it is set. Otherwise, finds a
* Georeference in the World and returns it, creating it if necessary. The
* resolved Georeference is cached so subsequent calls to this function will
* return the same instance.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
ACesiumGeoreference* ResolveGeoreference();
/**
* Invalidates the cached resolved georeference, unsubscribing from it and
* setting it to null. The next time ResolveGeoreference is called, the
* Georeference will be re-resolved and re-subscribed.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
void InvalidateResolvedGeoreference();
private:
/**
* The actor managing this tileset's content attributions.
*
* If this is null, the Tileset will find and use the first Credit System
* Actor in the level, or create one if necessary. To get the active/effective
* Credit System from Blueprints or C++, use ResolvedCreditSystem instead.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
BlueprintGetter = GetCreditSystem,
BlueprintSetter = SetCreditSystem,
Category = "Cesium",
Meta = (AllowPrivateAccess))
TSoftObjectPtr<ACesiumCreditSystem> CreditSystem;
/**
* The resolved Credit System used by this Tileset. This is not serialized
* because it may point to a Credit System in the PersistentLevel while this
* tileset is in a sublevel. If the CreditSystem property is specified,
* however then this property will have the same value.
*
* This property will be null before ResolveCreditSystem is called.
*/
UPROPERTY(
Transient,
BlueprintReadOnly,
Category = "Cesium",
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<ACesiumCameraManager> 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.
*/
UPROPERTY(
Transient,
BlueprintReadOnly,
Category = "Cesium",
Meta = (AllowPrivateAccess))
UCesiumBoundingVolumePoolComponent* BoundingVolumePoolComponent = nullptr;
/**
* The custom view extension this tileset uses to pull renderer view
* information.
*/
TSharedPtr<CesiumViewExtension, ESPMode::ThreadSafe> _cesiumViewExtension =
nullptr;
public:
/** @copydoc ACesium3DTileset::CreditSystem */
UFUNCTION(BlueprintCallable, Category = "Cesium")
TSoftObjectPtr<ACesiumCreditSystem> GetCreditSystem() const;
/** @copydoc ACesium3DTileset::CreditSystem */
UFUNCTION(BlueprintCallable, Category = "Cesium")
void SetCreditSystem(TSoftObjectPtr<ACesiumCreditSystem> NewCreditSystem);
/**
* Resolves the Cesium Credit System to use with this Actor. Returns
* the value of the CreditSystem property if it is set. Otherwise, finds a
* Credit System in the World and returns it, creating it if necessary. The
* resolved Credit System is cached so subsequent calls to this function will
* return the same instance.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
ACesiumCreditSystem* ResolveCreditSystem();
/**
* Invalidates the cached resolved Credit System, setting it to null. The next
* time ResolveCreditSystem is called, the Credit System will be re-resolved.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
void InvalidateResolvedCreditSystem();
/**
* Whether or not to show this tileset's credits on screen.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
bool ShowCreditsOnScreen = false;
/** @copydoc ACesium3DTileset::CameraManager */
UFUNCTION(BlueprintGetter, Category = "Cesium")
TSoftObjectPtr<ACesiumCameraManager> GetCameraManager() const;
/** @copydoc ACesium3DTileset::CameraManager */
UFUNCTION(BlueprintSetter, Category = "Cesium")
void SetCameraManager(TSoftObjectPtr<ACesiumCameraManager> 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.
*
* This is used to select an appropriate level-of-detail: A low value
* will cause many tiles with a high level of detail to be loaded,
* causing a finer visual representation of the tiles, but with a
* higher performance cost for loading and rendering. A higher value will
* cause a coarser visual representation, with lower performance
* requirements.
*
* When a tileset uses the older layer.json / quantized-mesh format rather
* than 3D Tiles, this value is effectively divided by 8.0. So the default
* value of 16.0 corresponds to the standard value for quantized-mesh terrain
* of 2.0.
*/
UPROPERTY(
EditAnywhere,
BlueprintGetter = GetMaximumScreenSpaceError,
BlueprintSetter = SetMaximumScreenSpaceError,
Category = "Cesium|Level of Detail",
meta = (ClampMin = 0.0))
double MaximumScreenSpaceError = 16.0;
/**
* Scale Level-of-Detail by Display DPI. This increases the performance for
* mobile devices and high DPI screens.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium|Level of Detail")
EApplyDpiScaling ApplyDpiScaling = EApplyDpiScaling::UseProjectDefault;
/**
* Whether to preload ancestor tiles.
*
* Setting this to true optimizes the zoom-out experience and provides more
* detail in newly-exposed areas when panning. The down side is that it
* requires loading more tiles.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium|Tile Loading")
bool PreloadAncestors = true;
/**
* Whether to preload sibling tiles.
*
* Setting this to true causes tiles with the same parent as a rendered tile
* to be loaded, even if they are culled. Setting this to true may provide a
* better panning experience at the cost of loading more tiles.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium|Tile Loading")
bool PreloadSiblings = true;
/**
* Whether to unrefine back to a parent tile when a child isn't done loading.
*
* When this is set to true, the tileset will guarantee that the tileset will
* never be rendered with holes in place of tiles that are not yet loaded,
* even though the tile that is rendered instead may have low resolution. When
* false, overall loading will be faster, but newly-visible parts of the
* tileset may initially be blank.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium|Tile Loading")
bool ForbidHoles = false;
/**
* The maximum number of tiles that may be loaded at once.
*
* When new parts of the tileset become visible, the tasks to load the
* corresponding tiles are put into a queue. This value determines how
* many of these tasks are processed at the same time. A higher value
* may cause the tiles to be loaded and rendered more quickly, at the
* cost of a higher network- and processing load.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium|Tile Loading",
meta = (ClampMin = 0))
int32 MaximumSimultaneousTileLoads = 20;
/**
* @brief The maximum number of bytes that may be cached.
*
* Note that this value, even if 0, will never
* cause tiles that are needed for rendering to be unloaded. However, if the
* total number of loaded bytes is greater than this value, tiles will be
* unloaded until the total is under this number or until only required tiles
* remain, whichever comes first.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium|Tile Loading")
int64 MaximumCachedBytes = 256 * 1024 * 1024;
/**
* The number of loading descendents a tile should allow before deciding to
* render itself instead of waiting.
*
* Setting this to 0 will cause each level of detail to be loaded
* successively. This will increase the overall loading time, but cause
* additional detail to appear more gradually. Setting this to a high value
* like 1000 will decrease the overall time until the desired level of detail
* is achieved, but this high-detail representation will appear at once, as
* soon as it is loaded completely.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium|Tile Loading",
meta = (ClampMin = 0))
int32 LoadingDescendantLimit = 20;
/**
* Whether to cull tiles that are outside the frustum.
*
* By default this is true, meaning that tiles that are not visible with the
* current camera configuration will be ignored. It can be set to false, so
* that these tiles are still considered for loading, refinement and
* rendering.
*
* This will cause more tiles to be loaded, but helps to avoid holes and
* provides a more consistent mesh, which may be helpful for physics.
*
* Note that this will always be disabled if UseLodTransitions is set to true.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium|Tile Culling",
Meta = (EditCondition = "!UseLodTransitions", EditConditionHides))
bool EnableFrustumCulling = true;
/**
* Whether to cull tiles that are occluded by fog.
*
* This does not refer to the atmospheric fog of the Unreal Engine,
* but to an internal representation of fog: Depending on the height
* of the camera above the ground, tiles that are far away (close to
* the horizon) will be culled when this flag is enabled.
*
* Note that this will always be disabled if UseLodTransitions is set to true.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium|Tile Culling",
Meta = (EditCondition = "!UseLodTransitions", EditConditionHides))
bool EnableFogCulling = true;
/**
* Whether a specified screen-space error should be enforced for tiles that
* are outside the frustum or hidden in fog.
*
* When "Enable Frustum Culling" and "Enable Fog Culling" are both true, tiles
* outside the view frustum or hidden in fog are effectively ignored, and so
* their level-of-detail doesn't matter. And in this scenario, this property
* is ignored.
*
* However, when either of those flags are false, these "would-be-culled"
* tiles continue to be processed, and the question arises of how to handle
* their level-of-detail. When this property is false, refinement terminates
* at these tiles, no matter what their current screen-space error. The tiles
* are available for physics, shadows, etc., but their level-of-detail may
* be very low.
*
* When set to true, these tiles are refined until they achieve the specified
* "Culled Screen Space Error". This allows control over the minimum quality
* of these would-be-culled tiles.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium|Tile Culling")
bool EnforceCulledScreenSpaceError = false;
/**
* The screen-space error to be enforced for tiles that are outside the view
* frustum or hidden in fog.
*
* When "Enable Frustum Culling" and "Enable Fog Culling" are both true, tiles
* outside the view frustum or hidden in fog are effectively ignored, and so
* their level-of-detail doesn't matter. And in this scenario, this property
* is ignored.
*
* However, when either of those flags are false, these "would-be-culled"
* tiles continue to be processed, and the question arises of how to handle
* their level-of-detail. When "Enforce Culled Screen Space Error" is false,
* this property is ignored and refinement terminates at these tiles, no
* matter what their current screen-space error. The tiles are available for
* physics, shadows, etc., but their level-of-detail may be very low.
*
* When set to true, these tiles are refined until they achieve the
* screen-space error specified by this property.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium|Tile Culling",
meta = (EditCondition = "EnforceCulledScreenSpaceError", ClampMin = 0.0))
double CulledScreenSpaceError = 64.0;
// This mirrors
// UCesiumRuntimeSettings::EnableExperimentalOcclusionCullingFeature so that
// it can be used as an EditCondition.
UPROPERTY(Transient, VisibleDefaultsOnly, Category = "Cesium|Tile Occlusion")
bool CanEnableOcclusionCulling = false;
/**
* Whether to cull tiles that are occluded.
*
* If this option is disabled, check that "Enable Experimental Occlusion
* Culling Feature" is enabled in the Plugins -> Cesium section of the Project
* Settings.
*
* When enabled, this feature will use Unreal's occlusion system to determine
* if tiles are actually visible on the screen. For tiles found to be
* occluded, the tile will not refine to show descendants, but it will still
* be rendered to avoid holes. This results in less tile loads and less GPU
* resource usage for dense, high-occlusion scenes like ground-level views in
* cities.
*
* This will not work for tilesets with poorly fit bounding volumes and cause
* more draw calls with very few extra culled tiles. When there is minimal
* occlusion in a scene, such as with terrain tilesets and applications
* focused on top-down views, this feature will yield minimal benefit and
* potentially cause needless overhead.
*/
UPROPERTY(
EditAnywhere,
BlueprintGetter = GetEnableOcclusionCulling,
BlueprintSetter = SetEnableOcclusionCulling,
Category = "Cesium|Tile Occlusion",
meta = (EditCondition = "CanEnableOcclusionCulling"))
bool EnableOcclusionCulling = true;
/**
* The number of CesiumBoundingVolumeComponents to use for querying the
* occlusion state of traversed tiles.
*
* Only applicable when EnableOcclusionCulling is enabled.
*/
UPROPERTY(
EditAnywhere,
BlueprintGetter = GetOcclusionPoolSize,
BlueprintSetter = SetOcclusionPoolSize,
Category = "Cesium|Tile Occlusion",
meta =
(EditCondition =
"EnableOcclusionCulling && CanEnableOcclusionCulling",
ClampMin = "0",
ClampMax = "1000"))
int32 OcclusionPoolSize = 500;
/**
* Whether to wait for valid occlusion results before refining tiles.
*
* Only applicable when EnableOcclusionCulling is enabled. When this option
* is enabled, there may be small delays before tiles are refined, but there
* may be an overall performance advantage by avoiding loads of descendants
* that will be found to be occluded.
*/
UPROPERTY(
EditAnywhere,
BlueprintGetter = GetDelayRefinementForOcclusion,
BlueprintSetter = SetDelayRefinementForOcclusion,
Category = "Cesium|Tile Occlusion",
meta =
(EditCondition =
"EnableOcclusionCulling && CanEnableOcclusionCulling"))
bool DelayRefinementForOcclusion = true;
/**
* Refreshes this tileset, ensuring that all materials and other settings are
* applied. It is not usually necessary to invoke this, but when
* behind-the-scenes changes are made and not reflected in the tileset, this
* function can help.
*/
UFUNCTION(CallInEditor, BlueprintCallable, Category = "Cesium")
void RefreshTileset();
/**
* Pauses level-of-detail and culling updates of this tileset.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium|Debug")
bool SuspendUpdate;
/**
* If true, this tileset is ticked/updated in the editor. If false, is only
* ticked while playing (including Play-in-Editor).
*/
UPROPERTY(EditAnywhere, Category = "Cesium|Debug")
bool UpdateInEditor = true;
/**
* If true, stats about tile selection are printed to the Output Log.
*/
UPROPERTY(EditAnywhere, Category = "Cesium|Debug")
bool LogSelectionStats = false;
/**
* If true, logs stats on the assets in this tileset's shared asset system to
* the Output Log.
*/
UPROPERTY(EditAnywhere, Category = "Cesium|Debug")
bool LogSharedAssetStats = false;
/**
* If true, draws debug text above each tile being rendered with information
* about that tile.
*/
UPROPERTY(EditAnywhere, Category = "Cesium|Debug")
bool DrawTileInfo = false;
/**
* Define the collision profile for all the 3D tiles created inside this
* actor.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadOnly,
Category = "Collision",
meta = (ShowOnlyInnerProperties, SkipUCSModifiedProperties))
FBodyInstance BodyInstance;
/**
* A delegate that will be called whenever the tileset is fully loaded.
*/
UPROPERTY(BlueprintAssignable, Category = "Cesium");
FCompletedLoadTrigger OnTilesetLoaded;
/**
* Use a dithering effect when transitioning between tiles of different LODs.
*
* When this is set to true, Frustrum Culling and Fog Culling are always
* disabled.
*/
UPROPERTY(
EditAnywhere,
BlueprintGetter = GetUseLodTransitions,
BlueprintSetter = SetUseLodTransitions,
Category = "Cesium|Rendering")
bool UseLodTransitions = false;
/**
* How long dithered LOD transitions between different tiles should take, in
* seconds.
*
* Only relevant if UseLodTransitions is true.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium|Rendering",
meta = (EditCondition = "UseLodTransitions", EditConditionHides))
float LodTransitionLength = 0.5f;
private:
UPROPERTY(BlueprintGetter = GetLoadProgress, Category = "Cesium")
float LoadProgress = 0.0f;
/**
* The type of source from which to load this tileset.
*/
UPROPERTY(
EditAnywhere,
BlueprintGetter = GetTilesetSource,
BlueprintSetter = SetTilesetSource,
Category = "Cesium",
meta = (DisplayName = "Source"))
ETilesetSource TilesetSource = ETilesetSource::FromCesiumIon;
/**
* The URL of this tileset's "tileset.json" file.
*
* If this property is specified, the ion asset ID and token are ignored.
*/
UPROPERTY(
EditAnywhere,
BlueprintGetter = GetUrl,
BlueprintSetter = SetUrl,
Category = "Cesium",
meta = (EditCondition = "TilesetSource==ETilesetSource::FromUrl"))
FString Url = "";
/**
* The ID of the Cesium ion asset to use.
*
* This property is ignored if the Url is specified.
*/
UPROPERTY(
EditAnywhere,
BlueprintGetter = GetIonAssetID,
BlueprintSetter = SetIonAssetID,
Category = "Cesium",
meta =
(EditCondition = "TilesetSource==ETilesetSource::FromCesiumIon",
ClampMin = 0))
int64 IonAssetID;
/**
* The access token to use to access the Cesium ion resource.
*/
UPROPERTY(
EditAnywhere,
BlueprintGetter = GetIonAccessToken,
BlueprintSetter = SetIonAccessToken,
Category = "Cesium",
meta = (EditCondition = "TilesetSource==ETilesetSource::FromCesiumIon"))
FString IonAccessToken;
UPROPERTY(
meta =
(DeprecatedProperty,
DeprecationMessage = "Use CesiumIonServer instead."))
FString IonAssetEndpointUrl_DEPRECATED;
/**
* The Cesium ion Server from which this tileset is loaded.
*/
UPROPERTY(
EditAnywhere,
BlueprintGetter = GetCesiumIonServer,
BlueprintSetter = SetCesiumIonServer,
Category = "Cesium",
AdvancedDisplay,
meta = (EditCondition = "TilesetSource==ETilesetSource::FromCesiumIon"))
UCesiumIonServer* CesiumIonServer;
/**
* Headers to be attached to each request made for this tileset.
*/
UPROPERTY(
EditAnywhere,
BlueprintGetter = GetRequestHeaders,
BlueprintSetter = SetRequestHeaders,
Category = "Cesium")
TMap<FString, FString> RequestHeaders;
/**
* Check if the Cesium ion token used to access this tileset is working
* correctly, and fix it if necessary.
*/
UFUNCTION(CallInEditor, Category = "Cesium")
void TroubleshootToken();
/**
* Whether to generate physics meshes for this tileset.
*
* Disabling this option will improve the performance of tile loading, but it
* will no longer be possible to collide with the tileset since the physics
* meshes will not be created.
*
* Physics meshes cannot be generated for primitives containing points.
*/
UPROPERTY(
EditAnywhere,
BlueprintGetter = GetCreatePhysicsMeshes,
BlueprintSetter = SetCreatePhysicsMeshes,
Category = "Cesium|Physics")
bool CreatePhysicsMeshes = true;
/**
* Whether to generate navigation collisions for this tileset.
*
* Enabling this option creates collisions for navigation when a 3D Tiles
* tileset is loaded. It is recommended to set "Runtime Generation" to
* "Static" in the navigation mesh settings in the project settings, as
* collision calculations become very slow.
*/
UPROPERTY(
EditAnywhere,
BlueprintGetter = GetCreateNavCollision,
BlueprintSetter = SetCreateNavCollision,
Category = "Cesium|Navigation")
bool CreateNavCollision = false;
/**
* Whether to always generate a correct tangent space basis for tiles that
* don't have them.
*
* Normally, a per-vertex tangent space basis is only required for glTF models
* with a normal map. However, a custom, user-supplied material may need a
* tangent space basis for other purposes. When this property is set to true,
* tiles lacking an explicit tangent vector will have one computed
* automatically using the MikkTSpace algorithm. When this property is false,
* load time will be improved by skipping the generation of the tangent
* vector, but the tangent space basis will be unreliable.
*
* Note that a tileset with "Enable Water Mask" set will include tangents
* for tiles containing water, regardless of the value of this property.
*/
UPROPERTY(
EditAnywhere,
BlueprintGetter = GetAlwaysIncludeTangents,
BlueprintSetter = SetAlwaysIncludeTangents,
Category = "Cesium|Rendering")
bool AlwaysIncludeTangents = false;
/**
* Whether to generate smooth normals when normals are missing in the glTF.
*
* According to the Gltf spec: "When normals are not specified, client
* implementations should calculate flat normals." However, calculating flat
* normals requires duplicating vertices. This option allows the gltfs to be
* sent with explicit smooth normals when the original gltf was missing
* normals.
*/
UPROPERTY(
EditAnywhere,
BlueprintGetter = GetGenerateSmoothNormals,
BlueprintSetter = SetGenerateSmoothNormals,
Category = "Cesium|Rendering")
bool GenerateSmoothNormals = false;
/**
* Whether to request and render the water mask.
*
* Currently only applicable for quantized-mesh tilesets that support the
* water mask extension.
*/
UPROPERTY(
EditAnywhere,
BlueprintGetter = GetEnableWaterMask,
BlueprintSetter = SetEnableWaterMask,
Category = "Cesium|Rendering")
bool EnableWaterMask = false;
/**
* Whether to ignore the KHR_materials_unlit extension on the glTF tiles in
* this tileset, if it exists, and instead render with standard lighting and
* shadows. This property will have no effect if the tileset does not have any
* tiles that use this extension.
*
* The KHR_materials_unlit extension is often applied to photogrammetry
* tilesets because lighting and shadows are already baked into their
* textures.
*/
UPROPERTY(
EditAnywhere,
BlueprintGetter = GetIgnoreKhrMaterialsUnlit,
BlueprintSetter = SetIgnoreKhrMaterialsUnlit,
Category = "Cesium|Rendering",
meta = (DisplayName = "Ignore KHR_materials_unlit"))
bool IgnoreKhrMaterialsUnlit = false;
/**
* A custom Material to use to render opaque elements in this tileset, in
* order to implement custom visual effects.
*
* The custom material should generally be created by copying the Material
* Instance "MI_CesiumThreeOverlaysAndClipping" and customizing the copy as
* desired.
*/
UPROPERTY(
EditAnywhere,
BlueprintGetter = GetMaterial,
BlueprintSetter = SetMaterial,
Category = "Cesium|Rendering")
UMaterialInterface* Material = nullptr;
/**
* A custom Material to use to render translucent elements of the tileset, in
* order to implement custom visual effects.
*
* The custom material should generally be created by copying the Material
* Instance "MI_CesiumThreeOverlaysAndClippingTranslucent" and customizing the
* copy as desired. Make sure that its Material Property Overrides -> Blend
* Mode is set to "Translucent".
*/
UPROPERTY(
EditAnywhere,
BlueprintGetter = GetTranslucentMaterial,
BlueprintSetter = SetTranslucentMaterial,
Category = "Cesium|Rendering")
UMaterialInterface* TranslucentMaterial = nullptr;
/**
* A custom Material to use to render this tileset in areas where the
* watermask is, in order to implement custom visual effects.
* Currently only applicable for quantized-mesh tilesets that support the
* water mask extension.
*
* The custom material should generally be created by copying the Material
* Instance "MI_CesiumThreeOverlaysAndClippingAndWater" and customizing the
* copy as desired.
*/
UPROPERTY(
EditAnywhere,
BlueprintGetter = GetWaterMaterial,
BlueprintSetter = SetWaterMaterial,
Category = "Cesium|Rendering")
UMaterialInterface* WaterMaterial = nullptr;
UPROPERTY(
EditAnywhere,
BlueprintGetter = GetCustomDepthParameters,
BlueprintSetter = SetCustomDepthParameters,
Category = "Rendering",
meta = (ShowOnlyInnerProperties))
FCustomDepthParameters CustomDepthParameters;
/**
* If this tileset contains points, their appearance can be configured with
* these point cloud shading parameters.
*
* These settings are not supported on mobile platforms.
*/
UPROPERTY(
EditAnywhere,
BlueprintGetter = GetPointCloudShading,
BlueprintSetter = SetPointCloudShading,
Category = "Cesium|Rendering")
FCesiumPointCloudShading PointCloudShading;
protected:
UPROPERTY()
FString PlatformName;
public:
UFUNCTION(BlueprintGetter, Category = "Cesium")
float GetLoadProgress() const { return LoadProgress; }
UFUNCTION(BlueprintGetter, Category = "Cesium")
bool GetUseLodTransitions() const { return UseLodTransitions; }
UFUNCTION(BlueprintSetter, Category = "Cesium")
void SetUseLodTransitions(bool InUseLodTransitions);
UFUNCTION(BlueprintGetter, Category = "Cesium")
ETilesetSource GetTilesetSource() const { return TilesetSource; }
UFUNCTION(BlueprintSetter, Category = "Cesium")
void SetTilesetSource(ETilesetSource InSource);
UFUNCTION(BlueprintGetter, Category = "Cesium")
FString GetUrl() const { return Url; }
UFUNCTION(BlueprintSetter, Category = "Cesium")
void SetUrl(const FString& InUrl);
UFUNCTION(BlueprintGetter, Category = "Cesium")
TMap<FString, FString> GetRequestHeaders() const { return RequestHeaders; }
UFUNCTION(BlueprintSetter, Category = "Cesium")
void SetRequestHeaders(const TMap<FString, FString>& InRequestHeaders);
UFUNCTION(BlueprintGetter, Category = "Cesium")
int64 GetIonAssetID() const { return IonAssetID; }
UFUNCTION(BlueprintSetter, Category = "Cesium")
void SetIonAssetID(int64 InAssetID);
UFUNCTION(BlueprintGetter, Category = "Cesium")
FString GetIonAccessToken() const { return IonAccessToken; }
UFUNCTION(BlueprintSetter, Category = "Cesium")
void SetIonAccessToken(const FString& InAccessToken);
UFUNCTION(BlueprintGetter, Category = "Cesium")
UCesiumIonServer* GetCesiumIonServer() const { return CesiumIonServer; }
UFUNCTION(BlueprintSetter, Category = "Cesium")
void SetCesiumIonServer(UCesiumIonServer* Server);
UFUNCTION(BlueprintGetter, Category = "Cesium")
double GetMaximumScreenSpaceError() { return MaximumScreenSpaceError; }
UFUNCTION(BlueprintSetter, Category = "Cesium")
void SetMaximumScreenSpaceError(double InMaximumScreenSpaceError);
UFUNCTION(BlueprintGetter, Category = "Cesium|Tile Culling|Experimental")
bool GetEnableOcclusionCulling() const;
UFUNCTION(BlueprintSetter, Category = "Cesium|Tile Culling|Experimental")
void SetEnableOcclusionCulling(bool bEnableOcclusionCulling);
UFUNCTION(BlueprintGetter, Category = "Cesium|Tile Culling|Experimental")
int32 GetOcclusionPoolSize() const { return OcclusionPoolSize; }
UFUNCTION(BlueprintSetter, Category = "Cesium|Tile Culling|Experimental")
void SetOcclusionPoolSize(int32 newOcclusionPoolSize);
UFUNCTION(BlueprintGetter, Category = "Cesium|Tile Culling|Experimental")
bool GetDelayRefinementForOcclusion() const {
return DelayRefinementForOcclusion;
}
UFUNCTION(BlueprintSetter, Category = "Cesium|Tile Culling|Experimental")
void SetDelayRefinementForOcclusion(bool bDelayRefinementForOcclusion);
UFUNCTION(BlueprintGetter, Category = "Cesium|Physics")
bool GetCreatePhysicsMeshes() const { return CreatePhysicsMeshes; }
UFUNCTION(BlueprintSetter, Category = "Cesium|Physics")
void SetCreatePhysicsMeshes(bool bCreatePhysicsMeshes);
UFUNCTION(BlueprintGetter, Category = "Cesium|Navigation")
bool GetCreateNavCollision() const { return CreateNavCollision; }
UFUNCTION(BlueprintSetter, Category = "Cesium|Navigation")
void SetCreateNavCollision(bool bCreateNavCollision);
UFUNCTION(BlueprintGetter, Category = "Cesium|Rendering")
bool GetAlwaysIncludeTangents() const { return AlwaysIncludeTangents; }
UFUNCTION(BlueprintSetter, Category = "Cesium|Rendering")
void SetAlwaysIncludeTangents(bool bAlwaysIncludeTangents);
UFUNCTION(BlueprintGetter, Category = "Cesium|Rendering")
bool GetGenerateSmoothNormals() const { return GenerateSmoothNormals; }
UFUNCTION(BlueprintSetter, Category = "Cesium|Rendering")
void SetGenerateSmoothNormals(bool bGenerateSmoothNormals);
UFUNCTION(BlueprintGetter, Category = "Cesium|Rendering")
bool GetEnableWaterMask() const { return EnableWaterMask; }
UFUNCTION(BlueprintSetter, Category = "Cesium|Rendering")
void SetEnableWaterMask(bool bEnableMask);
UFUNCTION(BlueprintGetter, Category = "Cesium|Rendering")
bool GetIgnoreKhrMaterialsUnlit() const { return IgnoreKhrMaterialsUnlit; }
UFUNCTION(BlueprintSetter, Category = "Cesium|Rendering")
void SetIgnoreKhrMaterialsUnlit(bool bIgnoreKhrMaterialsUnlit);
UFUNCTION(BlueprintGetter, Category = "Cesium|Rendering")
UMaterialInterface* GetMaterial() const { return Material; }
UFUNCTION(BlueprintSetter, Category = "Cesium|Rendering")
void SetMaterial(UMaterialInterface* InMaterial);
UFUNCTION(BlueprintGetter, Category = "Cesium|Rendering")
UMaterialInterface* GetTranslucentMaterial() const {
return TranslucentMaterial;
}
UFUNCTION(BlueprintSetter, Category = "Cesium|Rendering")
void SetTranslucentMaterial(UMaterialInterface* InMaterial);
UFUNCTION(BlueprintGetter, Category = "Cesium|Rendering")
UMaterialInterface* GetWaterMaterial() const { return WaterMaterial; }
UFUNCTION(BlueprintSetter, Category = "Cesium|Rendering")
void SetWaterMaterial(UMaterialInterface* InMaterial);
UFUNCTION(BlueprintGetter, Category = "Rendering")
FCustomDepthParameters GetCustomDepthParameters() const {
return CustomDepthParameters;
}
UFUNCTION(BlueprintSetter, Category = "Rendering")
void SetCustomDepthParameters(FCustomDepthParameters InCustomDepthParameters);
UFUNCTION(BlueprintGetter, Category = "Cesium|Rendering")
FCesiumPointCloudShading GetPointCloudShading() const {
return PointCloudShading;
}
UFUNCTION(BlueprintSetter, Category = "Cesium|Rendering")
void SetPointCloudShading(FCesiumPointCloudShading InPointCloudShading);
UFUNCTION(BlueprintCallable, Category = "Cesium|Rendering")
void PlayMovieSequencer();
UFUNCTION(BlueprintCallable, Category = "Cesium|Rendering")
void StopMovieSequencer();
UFUNCTION(BlueprintCallable, Category = "Cesium|Rendering")
void PauseMovieSequencer();
/**
* This method is not supposed to be called by clients. It is currently
* only required by the UnrealPrepareRendererResources.
*
* @internal
* See {@link
* UCesium3DTilesetRoot::GetCesiumTilesetToUnrealRelativeWorldTransform}.
* @endinternal
*/
const glm::dmat4& GetCesiumTilesetToUnrealRelativeWorldTransform() const;
Cesium3DTilesSelection::Tileset* GetTileset() {
return this->_pTileset.Get();
}
const Cesium3DTilesSelection::Tileset* GetTileset() const {
return this->_pTileset.Get();
}
const std::optional<FCesiumFeaturesMetadataDescription>&
getFeaturesMetadataDescription() const {
return this->_featuresMetadataDescription;
}
// AActor overrides (some or most of them should be protected)
virtual bool ShouldTickIfViewportsOnly() const override;
virtual void Tick(float DeltaTime) override;
virtual void BeginDestroy() override;
virtual bool IsReadyForFinishDestroy() override;
virtual void Destroyed() override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
virtual void PostLoad() override;
virtual void Serialize(FArchive& Ar) override;
void UpdateLoadStatus();
// UObject overrides
#if WITH_EDITOR
virtual void
PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
virtual void PostEditChangeChainProperty(
FPropertyChangedChainEvent& PropertyChangedChainEvent) override;
virtual void PostEditUndo() override;
virtual void PostEditImport() override;
virtual bool CanEditChange(const FProperty* InProperty) const override;
#endif
protected:
// Called when the game starts or when spawned
virtual void BeginPlay() override;
virtual void OnConstruction(const FTransform& Transform) override;
/**
* Called after the C++ constructor and after the properties have
* been initialized, including those loaded from config.
*/
void PostInitProperties() override;
virtual void NotifyHit(
class UPrimitiveComponent* MyComp,
AActor* Other,
class UPrimitiveComponent* OtherComp,
bool bSelfMoved,
FVector HitLocation,
FVector HitNormal,
FVector NormalImpulse,
const FHitResult& Hit) override;
private:
void LoadTileset();
void DestroyTileset();
static Cesium3DTilesSelection::ViewState CreateViewStateFromViewParameters(
const FCesiumCamera& camera,
const glm::dmat4& unrealWorldToTileset,
UCesiumEllipsoid* ellipsoid);
std::vector<FCesiumCamera> GetCameras() const;
std::vector<FCesiumCamera> GetPlayerCameras() const;
std::vector<FCesiumCamera> GetSceneCaptures() const;
public:
/**
* Update the transforms of the glTF components based on the
* the transform of the root component.
*
* This is supposed to be called during Tick, if the transform of
* the root component has changed since the previous Tick.
*/
void UpdateTransformFromCesium();
private:
/**
* The event handler for ACesiumGeoreference::OnEllipsoidChanged.
*/
UFUNCTION(CallInEditor)
void HandleOnGeoreferenceEllipsoidChanged(
UCesiumEllipsoid* OldEllipsoid,
UCesiumEllipsoid* NewEllpisoid);
/**
* Writes the values of all properties of this actor into the
* TilesetOptions, to take them into account during the next
* traversal.
*/
void updateTilesetOptionsFromProperties();
/**
* Update all the "_last..." fields of this instance based
* on the given ViewUpdateResult, printing a log message
* if any value changed.
*
* @param result The ViewUpdateREsult
*/
void updateLastViewUpdateResultState(
const Cesium3DTilesSelection::ViewUpdateResult& result);
/**
* Creates the visual representations of the given tiles to
* be rendered in the current frame.
*
* @param tiles The tiles
*/
void
showTilesToRender(const std::vector<Cesium3DTilesSelection::Tile*>& tiles);
/**
* Will be called after the tileset is loaded or spawned, to register
* a delegate that calls OnFocusEditorViewportOnThis when this
* tileset is double-clicked
*/
void AddFocusViewportDelegate();
#if WITH_EDITOR
std::vector<FCesiumCamera> GetEditorCameras() const;
/**
* Will focus all viewports on this tileset.
*
* This is called when double-clicking the tileset in the World Outliner.
* It will move the tileset into the center of the view, *even if* the
* tileset was not visible before, and no geometry has been created yet
* for the tileset: It solely operates on the tile bounding volume that
* was given in the root tile.
*/
void OnFocusEditorViewportOnThis();
void RuntimeSettingsChanged(
UObject* pObject,
struct FPropertyChangedEvent& changed);
#endif
private:
TUniquePtr<Cesium3DTilesSelection::Tileset> _pTileset;
#ifdef CESIUM_DEBUG_TILE_STATES
TUniquePtr<Cesium3DTilesSelection::DebugTileStateDatabase> _pStateDebug;
#endif
std::optional<FCesiumFeaturesMetadataDescription>
_featuresMetadataDescription;
PRAGMA_DISABLE_DEPRECATION_WARNINGS
std::optional<FMetadataDescription> _metadataDescription_DEPRECATED;
PRAGMA_ENABLE_DEPRECATION_WARNINGS
// For debug output
uint32_t _lastTilesRendered;
uint32_t _lastWorkerThreadTileLoadQueueLength;
uint32_t _lastMainThreadTileLoadQueueLength;
uint32_t _lastTilesVisited;
uint32_t _lastCulledTilesVisited;
uint32_t _lastTilesCulled;
uint32_t _lastTilesOccluded;
uint32_t _lastTilesWaitingForOcclusionResults;
uint32_t _lastMaxDepthVisited;
std::chrono::high_resolution_clock::time_point _startTime;
bool _captureMovieMode;
bool _beforeMoviePreloadAncestors;
bool _beforeMoviePreloadSiblings;
int32_t _beforeMovieLoadingDescendantLimit;
bool _beforeMovieUseLodTransitions;
bool _scaleUsingDPI;
// This is used as a workaround for cesium-native#186
//
// The tiles that are no longer supposed to be rendered in the current
// frame, according to ViewUpdateResult::tilesToHideThisFrame,
// are kept in this list, and hidden in the NEXT frame, because some
// internal occlusion culling information from Unreal might prevent
// the tiles that are supposed to be rendered instead from appearing
// immediately.
//
// If we find a way to clear the wrong occlusion information in the
// Unreal Engine, then this field may be removed, and the
// tilesToHideThisFrame may be hidden immediately.
std::vector<Cesium3DTilesSelection::Tile*> _tilesToHideNextFrame;
int32 _tilesetsBeingDestroyed;
friend class UnrealPrepareRendererResources;
friend class UCesiumGltfPointsComponent;
};