初始提交: UE5.3项目基础框架

This commit is contained in:
2025-10-14 11:14:54 +08:00
commit 721d9fd98e
5334 changed files with 316782 additions and 0 deletions

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,58 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CoreMinimal.h"
#include "Cesium3DTilesetLoadFailureDetails.generated.h"
class ACesium3DTileset;
UENUM(BlueprintType)
enum class ECesium3DTilesetLoadType : uint8 {
/**
* An unknown load error.
*/
Unknown,
/**
* A Cesium ion asset endpoint.
*/
CesiumIon,
/**
* A tileset.json.
*/
TilesetJson
};
USTRUCT(BlueprintType)
struct CESIUMRUNTIME_API FCesium3DTilesetLoadFailureDetails {
GENERATED_BODY()
/**
* The tileset that encountered the load failure.
*/
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Cesium")
TWeakObjectPtr<ACesium3DTileset> Tileset = nullptr;
/**
* The type of request that failed to load.
*/
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Cesium")
ECesium3DTilesetLoadType Type = ECesium3DTilesetLoadType::Unknown;
/**
* The HTTP status code of the response that led to the failure.
*
* If there was no response or the failure did not follow from a request, then
* the value of this property will be 0.
*/
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Cesium")
int32 HttpStatusCode = 0;
/**
* A human-readable explanation of what failed.
*/
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Cesium")
FString Message;
};

View File

@ -0,0 +1,46 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumRasterOverlay.h"
#include "CoreMinimal.h"
#include "CesiumBingMapsRasterOverlay.generated.h"
UENUM(BlueprintType)
enum class EBingMapsStyle : uint8 {
Aerial UMETA(DisplayName = "Aerial"),
AerialWithLabelsOnDemand UMETA(DisplayName = "Aerial with Labels"),
RoadOnDemand UMETA(DisplayName = "Road"),
CanvasDark UMETA(DisplayName = "Canvas Dark"),
CanvasLight UMETA(DisplayName = "Canvas Light"),
CanvasGray UMETA(DisplayName = "Canvas Gray"),
OrdnanceSurvey UMETA(DisplayName = "Ordnance Survey"),
CollinsBart UMETA(DisplayName = "Collins Bart")
};
/**
* A raster overlay that directly accesses Bing Maps. If you're using Bing Maps
* via Cesium ion, use the "Cesium ion Raster Overlay" component instead.
*/
UCLASS(ClassGroup = (Cesium), meta = (BlueprintSpawnableComponent))
class CESIUMRUNTIME_API UCesiumBingMapsRasterOverlay
: public UCesiumRasterOverlay {
GENERATED_BODY()
public:
/**
* The Bing Maps API key to use.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
FString BingMapsKey;
/**
* The map style to use.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
EBingMapsStyle MapStyle = EBingMapsStyle::Aerial;
protected:
virtual std::unique_ptr<CesiumRasterOverlays::RasterOverlay> CreateOverlay(
const CesiumRasterOverlays::RasterOverlayOptions& options = {}) override;
};

View File

@ -0,0 +1,93 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "Math/Rotator.h"
#include "Math/Vector.h"
#include "Math/Vector2D.h"
#include "UObject/ObjectMacros.h"
#include "Cesium3DTilesSelection/ViewState.h"
#include "CesiumCamera.generated.h"
/**
* @brief A camera description that {@link ACesium3DTileset}s can use to decide
* what tiles need to be loaded to sufficiently cover the camera view.
*/
USTRUCT(BlueprintType)
struct CESIUMRUNTIME_API FCesiumCamera {
GENERATED_USTRUCT_BODY()
public:
/**
* @brief The pixel dimensions of the viewport.
*/
UPROPERTY(BlueprintReadWrite, Category = "Cesium")
FVector2D ViewportSize;
/**
* @brief The Unreal location of the camera.
*/
UPROPERTY(BlueprintReadWrite, Category = "Cesium")
FVector Location;
/**
* @brief The Unreal rotation of the camera.
*/
UPROPERTY(BlueprintReadWrite, Category = "Cesium")
FRotator Rotation;
/**
* @brief The horizontal field of view of the camera in degrees.
*/
UPROPERTY(BlueprintReadWrite, Category = "Cesium")
double FieldOfViewDegrees;
/**
* @brief The overriden aspect ratio for this camera.
*
* When this is 0.0f, use the aspect ratio implied by ViewportSize.
*
* This may be different from the aspect ratio implied by the ViewportSize
* and black bars are added as needed in order to achieve this aspect ratio
* within a larger viewport.
*/
UPROPERTY(BlueprintReadWrite, Category = "Cesium")
double OverrideAspectRatio = 0.0;
/**
* @brief Construct an uninitialized FCesiumCamera object.
*/
FCesiumCamera();
/**
* @brief Construct a new FCesiumCamera object.
*
* @param ViewportSize The viewport pixel size.
* @param Location The Unreal location.
* @param Rotation The Unreal rotation.
* @param FieldOfViewDegrees The horizontal field of view in degrees.
*/
FCesiumCamera(
const FVector2D& ViewportSize,
const FVector& Location,
const FRotator& Rotation,
double FieldOfViewDegrees);
/**
* @brief Construct a new FCesiumCamera object.
*
* @param ViewportSize The viewport pixel size.
* @param Location The Unreal location.
* @param Rotation The Unreal rotation.
* @param FieldOfViewDegrees The horizontal field of view in degrees.
* @param OverrideAspectRatio The overriden aspect ratio.
*/
FCesiumCamera(
const FVector2D& ViewportSize,
const FVector& Location,
const FRotator& Rotation,
double FieldOfViewDegrees,
double OverrideAspectRatio);
};

View File

@ -0,0 +1,80 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumCamera.h"
#include "Containers/Map.h"
#include "GameFramework/Actor.h"
#include "CesiumCameraManager.generated.h"
/**
* @brief Manages custom {@link FCesiumCamera}s for all
* {@link ACesium3DTileset}s in the world.
*/
UCLASS()
class CESIUMRUNTIME_API ACesiumCameraManager : public AActor {
GENERATED_BODY()
public:
/**
* @brief Get the camera manager for this world.
*/
UFUNCTION(
BlueprintCallable,
Category = "CesiumCameraManager",
meta = (WorldContext = "WorldContextObject"))
static ACesiumCameraManager*
GetDefaultCameraManager(const UObject* WorldContextObject);
ACesiumCameraManager();
/**
* @brief Register a new camera with the camera manager.
*
* @param Camera The current state for the new camera.
* @return The generated ID for this camera. Use this ID to refer to the
* camera in the future when calling UpdateCamera.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
int32 AddCamera(UPARAM(ref) const FCesiumCamera& Camera);
/**
* @brief Unregister an existing camera with the camera manager.
*
* @param CameraId The ID of the camera, as returned by AddCamera during
* registration.
* @return Whether the updating was successful. If false, the CameraId was
* invalid.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
bool RemoveCamera(int32 CameraId);
/**
* @brief Update the state of the specified camera.
*
* @param CameraId The ID of the camera, as returned by AddCamera during
* registration.
* @param Camera The new, updated state of the camera.
* @return Whether the updating was successful. If false, the CameraId was
* invalid.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
bool UpdateCamera(int32 CameraId, UPARAM(ref) const FCesiumCamera& Camera);
/**
* @brief Get a read-only map of the current camera IDs to cameras.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
const TMap<int32, FCesiumCamera>& GetCameras() const;
virtual bool ShouldTickIfViewportsOnly() const override;
virtual void Tick(float DeltaTime) override;
private:
int32 _currentCameraId = 0;
TMap<int32, FCesiumCamera> _cameras;
static FName DEFAULT_CAMERAMANAGER_TAG;
};

View File

@ -0,0 +1,62 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumGeoreference.h"
#include "CesiumGeospatial/CartographicPolygon.h"
#include "CesiumGeospatial/GlobeRectangle.h"
#include "CesiumGlobeAnchorComponent.h"
#include "Components/SplineComponent.h"
#include "CoreMinimal.h"
#include "Engine/StaticMesh.h"
#include "GameFramework/Actor.h"
#include <vector>
#include "CesiumCartographicPolygon.generated.h"
/**
* A spline-based polygon actor used to rasterize 2D polygons on top of
* Cesium 3D Tileset actors.
*/
UCLASS(ClassGroup = (Cesium), meta = (BlueprintSpawnableComponent))
class CESIUMRUNTIME_API ACesiumCartographicPolygon : public AActor {
GENERATED_BODY()
public:
ACesiumCartographicPolygon();
/**
* The polygon.
*/
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Cesium")
USplineComponent* Polygon;
/**
* The Globe Anchor Component that precisely ties this Polygon to the Globe.
*/
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Cesium")
UCesiumGlobeAnchorComponent* GlobeAnchor;
virtual void OnConstruction(const FTransform& Transform) override;
/**
* Creates and returns a CartographicPolygon object
* created from the current spline selection.
*
* @param worldToTileset The transformation from Unreal world coordinates to
* the coordinates of the Cesium3DTileset Actor for which the cartographic
* polygon is being created.
*/
CesiumGeospatial::CartographicPolygon
CreateCartographicPolygon(const FTransform& worldToTileset) const;
// AActor overrides
virtual void PostLoad() override;
protected:
virtual void BeginPlay() override;
private:
void MakeLinear();
};

View File

@ -0,0 +1,10 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "Runtime/Launch/Resources/Version.h"
#define ENGINE_VERSION_5_5_OR_HIGHER \
(ENGINE_MAJOR_VERSION > 5 || ENGINE_MINOR_VERSION >= 5)
#define ENGINE_VERSION_5_4_OR_HIGHER \
(ENGINE_MAJOR_VERSION > 5 || ENGINE_MINOR_VERSION >= 4)

View File

@ -0,0 +1,97 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "Components/WidgetComponent.h"
#include "Engine/Blueprint.h"
#include "GameFramework/Actor.h"
#include "UObject/Class.h"
#include "UObject/ConstructorHelpers.h"
#include <memory>
#include <string>
#include <unordered_map>
#if WITH_EDITOR
#include "IAssetViewport.h"
#include "UnrealEdMisc.h"
#endif
#include "CesiumCreditSystem.generated.h"
namespace CesiumUtility {
class CreditSystem;
}
/**
* Manages credits / atttribution for Cesium data sources. These credits
* are displayed by the corresponding Blueprints class
* /CesiumForUnreal/CesiumCreditSystemBP.CesiumCreditSystemBP_C.
*/
UCLASS(Abstract)
class CESIUMRUNTIME_API ACesiumCreditSystem : public AActor {
GENERATED_BODY()
public:
static ACesiumCreditSystem*
GetDefaultCreditSystem(const UObject* WorldContextObject);
ACesiumCreditSystem();
virtual void BeginPlay() override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
virtual void OnConstruction(const FTransform& Transform) override;
virtual void BeginDestroy() override;
UPROPERTY(EditDefaultsOnly, Category = "Cesium")
TSubclassOf<class UScreenCreditsWidget> CreditsWidgetClass;
/**
* Whether the credit string has changed since last frame.
*/
UPROPERTY(BlueprintReadOnly, Category = "Cesium")
bool CreditsUpdated = false;
UPROPERTY(BlueprintReadOnly, Transient, Category = "Cesium")
class UScreenCreditsWidget* CreditsWidget;
// Called every frame
virtual bool ShouldTickIfViewportsOnly() const override;
virtual void Tick(float DeltaTime) override;
const std::shared_ptr<CesiumUtility::CreditSystem>&
GetExternalCreditSystem() const {
return _pCreditSystem;
}
void updateCreditsViewport(bool recreateWidget);
void removeCreditsFromViewports();
#if WITH_EDITOR
void OnRedrawLevelEditingViewports(bool);
void OnPreBeginPIE(bool bIsSimulating);
void OnEndPIE();
void OnCleanseEditor();
#endif
private:
static UObject* CesiumCreditSystemBP;
/**
* A tag that is assigned to Credit Systems when they are created
* as the "default" Credit System for a certain world.
*/
static FName DEFAULT_CREDITSYSTEM_TAG;
// the underlying cesium-native credit system that is managed by this actor.
std::shared_ptr<CesiumUtility::CreditSystem> _pCreditSystem;
size_t _lastCreditsCount;
FString ConvertHtmlToRtf(std::string html);
std::unordered_map<std::string, FString> _htmlToRtf;
#if WITH_EDITOR
TWeakPtr<IAssetViewport> _pLastEditorViewport;
#endif
};

View File

@ -0,0 +1,50 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CoreMinimal.h"
#include "Misc/Guid.h"
struct CESIUMRUNTIME_API FCesiumCustomVersion {
enum Versions {
// The version before any custom version was added to Cesium for Unreal
BeforeCustomVersionWasAdded = 0,
// Cesium3DTileset gained the TilesetSource property. In previous versions,
// the tileset source was assumed to be the URL if one was supplied, and
// Cesium ion otherwise.
TilesetExplicitSource = 1,
// The Georeferencing system was refactored.
GeoreferenceRefactoring = 2,
// The explicit Mobility property on Cesium3DTileset was removed, in favor
// of the normal Mobility property on the RootComponent.
TilesetMobilityRemoved = 3,
// The UCesiumGlobeAnchorComponent's globe transformation changed from being
// 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,
// Fly-to behavior became an independent component rather than built into
// the GlobeAwareDefaultPawn.
FlyToComponent = 6,
// Added the CesiumIonServer property to Cesium3DTileset and
// CesiumIonRasterOverlay.
CesiumIonServer = 7,
// Replaced the UseWebMercatorProjection property in
// CesiumWebMapTileServiceOverlay with the enum Projection property.
WebMapTileServiceProjectionAsEnum = 8,
VersionPlusOne,
LatestVersion = VersionPlusOne - 1
};
// The GUID for the Cesium for Unreal plugin's custom version
static const FGuid GUID;
};

View File

@ -0,0 +1,25 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumRasterOverlay.h"
#include "CoreMinimal.h"
#include "CesiumDebugColorizeTilesRasterOverlay.generated.h"
/**
* A raster overlay that can be used to debug tilesets by shading each tile with
* a random color.
*/
UCLASS(
DisplayName = "Cesium Debug Colorize Tiles Raster Overlay",
ClassGroup = (Cesium),
meta = (BlueprintSpawnableComponent))
class CESIUMRUNTIME_API UCesiumDebugColorizeTilesRasterOverlay
: public UCesiumRasterOverlay {
GENERATED_BODY()
public:
protected:
virtual std::unique_ptr<CesiumRasterOverlays::RasterOverlay> CreateOverlay(
const CesiumRasterOverlays::RasterOverlayOptions& options = {}) override;
};

View File

@ -0,0 +1,148 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "Engine/DataAsset.h"
#include "Misc/Optional.h"
#include <CesiumGeospatial/LocalHorizontalCoordinateSystem.h>
#include "CesiumEllipsoid.generated.h"
namespace CesiumGeospatial {
class Ellipsoid;
};
UCLASS()
class CESIUMRUNTIME_API UCesiumEllipsoid : public UDataAsset {
GENERATED_BODY()
public:
/**
* Creates a new {@link UCesiumEllipsoid} with the given radii.
*
* This is equivalent to
* ```
* auto ellipsoid = NewObject<UCesiumEllipsoid>();
* ellipsoid->SetRadii(Radii);
* ```
*/
UFUNCTION(BlueprintCallable, Category = "Cesium|Ellipsoid")
static UCesiumEllipsoid* Create(const FVector& Radii);
/**
* Gets the radii of the ellipsoid in its x-, y-, and z-directions in
* meters.
*/
UFUNCTION(BlueprintPure, Category = "Cesium|Ellipsoid")
FVector GetRadii();
/**
* Sets the radii of this ellipsoid in its x-, y-, and z-directions in meters.
*
* Tilesets using this ellipsoid may have to be refreshed to see the changes
* applied.
*/
void SetRadii(const FVector& NewRadii);
/**
* Gets the maximum radius of the ellipsoid in any dimension, in meters.
*/
UFUNCTION(BlueprintPure, Category = "Cesium|Ellipsoid")
double GetMaximumRadius();
/**
* Gets the minimum radius of the ellipsoid in any dimension, in
* meters.
*/
UFUNCTION(BlueprintPure, Category = "Cesium|Ellipsoid")
double GetMinimumRadius();
/**
* Scale the given Ellipsoid-Centered, Ellipsoid-Fixed position along the
* geodetic surface normal so that it is on the surface of the ellipsoid. If
* the position is near the center of the ellipsoid, the result will have the
* value (0,0,0) because the surface position is undefined.
*/
UFUNCTION(
BlueprintPure,
Category = "Cesium|Ellipsoid",
meta = (ReturnDisplayName = "SurfacePosition"))
FVector
ScaleToGeodeticSurface(const FVector& EarthCenteredEarthFixedPosition);
/**
* Computes the normal of the plane tangent to the surface of the ellipsoid
* at the provided Ellipsoid-Centered, Ellipsoid-Fixed position.
*/
UFUNCTION(
BlueprintPure,
Category = "Cesium|Ellipsoid",
meta = (ReturnDisplayName = "SurfaceNormalVector"))
FVector GeodeticSurfaceNormal(const FVector& EarthCenteredEarthFixedPosition);
/**
* Convert longitude in degrees (X), latitude in degrees (Y), and height above
* the ellipsoid in meters (Z) to Ellipsoid-Centered, Ellipsoid-Fixed (ECEF)
* coordinates.
*/
UFUNCTION(
BlueprintPure,
Category = "Cesium|Ellipsoid",
meta = (ReturnDisplayName = "EarthCenteredEarthFixedPosition"))
FVector LongitudeLatitudeHeightToEllipsoidCenteredEllipsoidFixed(
const FVector& LongitudeLatitudeHeight);
/**
* Convert Ellipsoid-Centered, Ellipsoid-Fixed (ECEF) coordinates to longitude
* in degrees (X), latitude in degrees (Y), and height above the ellipsoid in
* meters (Z). If the position is near the center of the Ellipsoid, the result
* will have the value (0,0,0) because the longitude, latitude, and height are
* undefined.
*/
UFUNCTION(
BlueprintPure,
Category = "Cesium|Ellipsoid",
meta = (ReturnDisplayName = "LongitudeLatitudeHeight"))
FVector EllipsoidCenteredEllipsoidFixedToLongitudeLatitudeHeight(
const FVector& EarthCenteredEarthFixedPosition);
/**
* Computes the transformation matrix from the local East-North-Up (ENU) frame
* to Ellipsoid-Centered, Ellipsoid-Fixed (ECEF) at the specified ECEF
* location.
*/
FMatrix EastNorthUpToEllipsoidCenteredEllipsoidFixed(
const FVector& EarthCenteredEarthFixedPosition);
/**
* Returns a new {@link CesiumGeospatial::LocalHorizontalCoordinateSystem}
* with the given scale, center, and ellipsoid.
*/
CesiumGeospatial::LocalHorizontalCoordinateSystem
CreateCoordinateSystem(const FVector& Center, double Scale);
/**
* Returns the underlying {@link CesiumGeospatial::Ellipsoid}
*/
const CesiumGeospatial::Ellipsoid& GetNativeEllipsoid();
protected:
/**
* The radii of this ellipsoid.
*
* The X coordinate of the vector should be the radius of the largest axis and
* the Z coordinate should be the radius of the smallest axis.
*/
UPROPERTY(
EditAnywhere,
Category = "Cesium|Ellipsoid",
meta = (DisplayName = "Radii"))
FVector Radii;
private:
#if WITH_EDITOR
virtual void
PostSaveRoot(FObjectPostSaveRootContext ObjectSaveContext) override;
#endif
TOptional<CesiumGeospatial::Ellipsoid> NativeEllipsoid;
};

View File

@ -0,0 +1,328 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "Components/ActorComponent.h"
#include "Containers/Array.h"
#include "Containers/UnrealString.h"
#include "Misc/Guid.h"
#if WITH_EDITOR
#include "Materials/MaterialFunctionMaterialLayer.h"
#endif
#include "CesiumEncodedMetadataComponent.generated.h"
PRAGMA_DISABLE_DEPRECATION_WARNINGS
/**
* @brief The GPU component type to coerce this property to.
*
*/
UENUM()
enum class ECesiumPropertyComponentType_DEPRECATED : uint8 {
Uint8_DEPRECATED,
Float_DEPRECATED
};
/**
* @brief The property type.
*/
UENUM()
enum class ECesiumPropertyType_DEPRECATED : uint8 {
Scalar_DEPRECATED,
Vec2_DEPRECATED,
Vec3_DEPRECATED,
Vec4_DEPRECATED
};
/**
* @brief Describes how this feature table is accessed. Either through feature
* id textures, feature id attributes, mixed, or neither.
*/
UENUM()
enum class ECesiumFeatureTableAccessType_DEPRECATED : uint8 {
Unknown_DEPRECATED,
Texture_DEPRECATED,
Attribute_DEPRECATED,
Mixed_DEPRECATED
};
// Note that these don't exhaustively cover the possibilities of glTF metadata
// classes, they only cover the subset that can be encoded into textures. For
// example, arbitrary size arrays and enums are excluded. Other un-encoded
// types like strings will be coerced.
struct UE_DEPRECATED(
5.0,
"CesiumEncodedMetadataComponent and its related description properties have been deprecated. Use CesiumEncodedFeaturesMetadata instead.")
FPropertyDescription;
/**
* @brief Description of a feature table property that should be encoded for
* access on the GPU.
*/
USTRUCT()
struct CESIUMRUNTIME_API FPropertyDescription {
GENERATED_USTRUCT_BODY()
/**
* @brief The name of this property as it will be referenced in the
* material.
*/
UPROPERTY(EditAnywhere, Category = "Cesium")
FString Name;
/**
* @brief The GPU component type to coerce this property to.
*
*/
UPROPERTY(EditAnywhere, Category = "Cesium")
ECesiumPropertyComponentType_DEPRECATED ComponentType =
ECesiumPropertyComponentType_DEPRECATED::Float_DEPRECATED;
/**
* @brief The property type.
*/
UPROPERTY(EditAnywhere, Category = "Cesium")
ECesiumPropertyType_DEPRECATED Type =
ECesiumPropertyType_DEPRECATED::Scalar_DEPRECATED;
/**
* @brief If ComponentType==Uint8, this indicates whether to normalize into a
* [0-1] range before accessing on the GPU.
*/
UPROPERTY(
EditAnywhere,
Category = "Cesium",
Meta =
(EditCondition =
"ComponentType==ECesiumPropertyComponentType_DEPRECATED::Uint8_DEPRECATED"))
bool Normalized = false;
};
struct UE_DEPRECATED(
5.0,
"CesiumEncodedMetadataComponent and its related description properties have been deprecated. Use CesiumEncodedFeaturesMetadata instead.")
FFeatureTableDescription;
/**
* @brief Description of a feature table containing properties to be encoded
* for access on the GPU.
*/
USTRUCT()
struct CESIUMRUNTIME_API FFeatureTableDescription {
GENERATED_USTRUCT_BODY()
/**
* @brief The name of this feature table.
*
*/
UPROPERTY(EditAnywhere, Category = "Cesium")
FString Name;
/**
* @brief Describes how this feature table is accessed. Either through feature
* id textures, feature id attributes, mixed, or neither.
*/
UPROPERTY(EditAnywhere, Category = "Cesium")
ECesiumFeatureTableAccessType_DEPRECATED AccessType =
ECesiumFeatureTableAccessType_DEPRECATED::Unknown_DEPRECATED;
/**
* @brief If the AccessType==Texture, this string represents the channel of
* the feature id texture that will be used to index into this feature table.
*/
UPROPERTY(
EditAnywhere,
Category = "Cesium",
Meta =
(EditCondition =
"AccessType==ECesiumFeatureTableAccessType_DEPRECATED::Texture_DEPRECATED"))
FString Channel;
/**
* @brief Descriptions of the properties to upload to the GPU.
*/
UPROPERTY(EditAnywhere, Category = "Cesium", Meta = (TitleProperty = "Name"))
TArray<FPropertyDescription> Properties;
};
struct UE_DEPRECATED(
5.0,
"CesiumEncodedMetadataComponent and its related properties have been deprecated. Use CesiumEncodedFeaturesMetadata instead.")
FFeatureTexturePropertyDescription;
/**
* @brief Description of a feature texture property that should be uploaded to
* the GPU.
*/
USTRUCT()
struct CESIUMRUNTIME_API FFeatureTexturePropertyDescription {
GENERATED_USTRUCT_BODY()
/**
* @brief The name of this property as it will be referenced in the
* material.
*/
UPROPERTY(EditAnywhere, Category = "Cesium")
FString Name;
// For now, always assumes it is Uint8
/*
UPROPERTY(EditAnywhere, Category = "Cesium")
ECesiumPropertyComponentType ComponentType =
ECesiumPropertyComponentType::Uint8;*/
/**
* @brief The property type.
*/
UPROPERTY(EditAnywhere, Category = "Cesium")
ECesiumPropertyType_DEPRECATED Type =
ECesiumPropertyType_DEPRECATED::Scalar_DEPRECATED;
/**
* @brief If ComponentType==Uint8, this indicates whether to normalize into a
* [0-1] range before accessing on the GPU.
*/
UPROPERTY(EditAnywhere, Category = "Cesium")
bool Normalized = false;
/**
* @brief This string describes the channel order of the incoming feature
* texture property (e.g., "rgb", "bgra", etc.). This helps us fix the
* channel order when accessing on the GPU.
*/
UPROPERTY(EditAnywhere, Category = "Cesium")
FString Swizzle;
};
struct UE_DEPRECATED(
5.0,
"CesiumEncodedMetadataComponent and its related description properties have been deprecated. Use CesiumEncodedFeaturesMetadata instead.")
FFeatureTextureDescription;
/**
* @brief Description of a feature texture with properties that should be
* uploaded to the GPU.
*/
USTRUCT()
struct CESIUMRUNTIME_API FFeatureTextureDescription {
GENERATED_USTRUCT_BODY()
/**
* @brief The name of this feature texture.
*/
UPROPERTY(EditAnywhere, Category = "Cesium")
FString Name;
/**
* @brief Descriptions of the properties to upload to the GPU.
*/
UPROPERTY(EditAnywhere, Category = "Cesium", Meta = (TitleProperty = "Name"))
TArray<FFeatureTexturePropertyDescription> Properties;
};
struct UE_DEPRECATED(
5.0,
"CesiumEncodedMetadataComponent and its related description properties have been deprecated. Use CesiumEncodedFeaturesMetadata instead.")
FMetadataDescription;
struct UE_DEPRECATED(
5.0,
"CesiumEncodedMetadataComponent and its related description properties have been deprecated. Use CesiumEncodedFeaturesMetadata instead.")
FMetadataDescription;
/**
* @brief Description of metadata from a glTF that should be uploaded to the
* GPU for access in materials.
*/
USTRUCT()
struct CESIUMRUNTIME_API FMetadataDescription {
GENERATED_USTRUCT_BODY()
/**
* @brief Descriptions of feature tables to upload to the GPU.
*/
UPROPERTY(
EditAnywhere,
Category = "EncodeMetadata",
Meta = (TitleProperty = "Name"))
TArray<FFeatureTableDescription> FeatureTables;
/**
* @brief Descriptions of feature textures to upload to the GPU.
*/
UPROPERTY(
EditAnywhere,
Category = "EncodeMetadata",
Meta = (TitleProperty = "Name"))
TArray<FFeatureTextureDescription> FeatureTextures;
};
/**
* @brief An actor component that can be added to Cesium3DTileset actors to
* dictate what metadata to encode for access on the GPU. The selection can be
* automatically populated based on available metadata by clicking the
* "Auto Fill" button. Once a selection of desired metadata is made, the
* boiler-plate material code to access the selected properties can be
* auto-generated using the "Generate Material" button.
*/
UCLASS(Deprecated)
class CESIUMRUNTIME_API UDEPRECATED_CesiumEncodedMetadataComponent
: public UActorComponent {
GENERATED_BODY()
public:
#if WITH_EDITORONLY_DATA
/**
* @brief This is the target UMaterialFunctionMaterialLayer that the
* boiler-plate material generation will use. When pressing
* "Generate Material", nodes will be added to this material to enable access
* to the requested metadata. If this is left blank, a new material layer
* will be created in the /Game/ folder.
*/
UPROPERTY(
EditAnywhere,
Category = "EncodeMetadata",
Meta =
(DeprecatedProperty,
DeprecationMessage =
"CesiumEncodedMetadataComponent is deprecated. Use CesiumFeaturesMetadataComponent instead."))
UMaterialFunctionMaterialLayer* TargetMaterialLayer = nullptr;
#endif
// Note: Here, we avoid wrapping the feature tables and feature textures
// inside a FMetadataDescription to avoid further complicating the details
// panel UI for editing the hierarchy.
/**
* @brief Descriptions of feature tables to upload to the GPU.
*/
UPROPERTY(
EditAnywhere,
Category = "EncodeMetadata",
Meta =
(TitleProperty = "Name",
DeprecatedProperty,
DeprecationMessage =
"CesiumEncodedMetadataComponent is deprecated. Use CesiumFeaturesMetadataComponent instead."))
TArray<FFeatureTableDescription> FeatureTables;
/**
* @brief Descriptions of feature textures to upload to the GPU.
*/
UPROPERTY(
EditAnywhere,
Category = "EncodeMetadata",
Meta =
(TitleProperty = "Name",
DeprecatedProperty,
DeprecationMessage =
"CesiumEncodedMetadataComponent is deprecated. Use CesiumFeaturesMetadataComponent instead."))
TArray<FFeatureTextureDescription> FeatureTextures;
// virtual void Serialize(FArchive& Ar) override;
};
PRAGMA_ENABLE_DEPRECATION_WARNINGS

View File

@ -0,0 +1,165 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "Kismet/BlueprintFunctionLibrary.h"
#include <CesiumGltf/AccessorUtility.h>
#include "CesiumFeatureIdAttribute.generated.h"
namespace CesiumGltf {
struct Model;
struct Accessor;
struct Node;
} // namespace CesiumGltf
/**
* @brief Reports the status of a FCesiumFeatureIdAttribute. If the feature ID
* attribute cannot be accessed, this briefly indicates why.
*/
UENUM(BlueprintType)
enum class ECesiumFeatureIdAttributeStatus : uint8 {
/* The feature ID attribute is valid. */
Valid = 0,
/* The feature ID attribute does not exist in the glTF primitive. */
ErrorInvalidAttribute,
/* The feature ID attribute uses an invalid accessor in the glTF. */
ErrorInvalidAccessor
};
/**
* @brief A blueprint-accessible wrapper for a feature ID attribute from a glTF
* model. Provides access to feature IDs which can be used with the
* corresponding {@link FCesiumPropertyTable} to access metadata. These feature
* IDs may be defined per-vertex or per-instance.
*/
USTRUCT(BlueprintType)
struct CESIUMRUNTIME_API FCesiumFeatureIdAttribute {
GENERATED_USTRUCT_BODY()
public:
/**
* @brief Constructs an empty feature ID attribute instance. Empty feature ID
* attributes can be constructed while trying to convert a FCesiumFeatureIdSet
* that is not an attribute. In this case, the status reports it is an invalid
* attribute.
*/
FCesiumFeatureIdAttribute()
: _status(ECesiumFeatureIdAttributeStatus::ErrorInvalidAttribute),
_featureIdAccessor(),
_attributeIndex(-1) {}
/**
* @brief Constructs a feature ID attribute instance.
*
* @param Model The model.
* @param Primitive The mesh primitive containing the feature ID attribute.
* @param FeatureIDAttribute The attribute index specified by the FeatureId.
* @param PropertyTableName The name of the property table this attribute
* corresponds to, if one exists, for backwards compatibility.
*/
FCesiumFeatureIdAttribute(
const CesiumGltf::Model& Model,
const CesiumGltf::MeshPrimitive& Primitive,
const int64 FeatureIDAttribute,
const FString& PropertyTableName);
/**
* @brief Constructs a feature ID attribute instance from
* EXT_instance_features data.
*
* @param Model The model.
* @param Node The node containing the feature ID attribute.
* @param FeatureIDAttribute The attribute index specified by the FeatureId.
* @param PropertyTableName The name of the property table this attribute
* corresponds to, if one exists, for backwards compatibility.
*/
FCesiumFeatureIdAttribute(
const CesiumGltf::Model& Model,
const CesiumGltf::Node& Node,
const int64 FeatureIDAttribute,
const FString& PropertyTableName);
/**
* Gets the index of this feature ID attribute in the glTF primitive.
*/
int64 getAttributeIndex() const { return this->_attributeIndex; }
private:
ECesiumFeatureIdAttributeStatus _status;
CesiumGltf::FeatureIdAccessorType _featureIdAccessor;
int64 _attributeIndex;
// For backwards compatibility.
FString _propertyTableName;
friend class UCesiumFeatureIdAttributeBlueprintLibrary;
};
UCLASS()
class CESIUMRUNTIME_API UCesiumFeatureIdAttributeBlueprintLibrary
: public UBlueprintFunctionLibrary {
GENERATED_BODY()
public:
PRAGMA_DISABLE_DEPRECATION_WARNINGS
/**
* Get the name of the feature table corresponding to this feature ID
* attribute. The name can be used to fetch the appropriate
* FCesiumFeatureTable from the FCesiumMetadataModel.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Meta =
(DeprecatedFunction,
DeprecationMessage =
"Use GetPropertyTableIndex on a CesiumFeatureIdSet instead."))
static const FString&
GetFeatureTableName(UPARAM(ref)
const FCesiumFeatureIdAttribute& FeatureIDAttribute);
PRAGMA_ENABLE_DEPRECATION_WARNINGS
/**
* Gets the status of the feature ID attribute. If this attribute is
* invalid in any way, this will briefly indicate why.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Features|FeatureIDAttribute")
static ECesiumFeatureIdAttributeStatus GetFeatureIDAttributeStatus(
UPARAM(ref) const FCesiumFeatureIdAttribute& FeatureIDAttribute);
/**
* Gets the number of elements in the attribute. This is distinct from the
* number of unique feature IDs within the attribute.
*
* For a feature ID attribute of a regular mesh, this is the number of
* vertices. For a per-instance feature ID, this is the number of instances.
*
* If the feature ID attribute is invalid, this returns 0.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Features|FeatureIDAttribute")
static int64
GetCount(UPARAM(ref) const FCesiumFeatureIdAttribute& FeatureIDAttribute);
/**
* Gets the feature ID at the given index. A feature ID can be used with a
* FCesiumPropertyTable to retrieve the metadata for that ID. If the feature
* ID attribute is invalid, this returns -1.
*
* For a feature ID attribute of a regular mesh, the provided Index is the
* index of a vertex within the mesh. For a per-instance feature ID, the
* provided Index is the index of the instance.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Features|FeatureIDAttribute")
static int64 GetFeatureID(
UPARAM(ref) const FCesiumFeatureIdAttribute& FeatureIDAttribute,
int64 Index);
};

View File

@ -0,0 +1,217 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumFeatureIdAttribute.h"
#include "CesiumFeatureIdTexture.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include <variant>
#include "CesiumFeatureIdSet.generated.h"
namespace CesiumGltf {
struct Model;
struct FeatureId;
struct ExtensionExtInstanceFeaturesFeatureId;
} // namespace CesiumGltf
/**
* @brief The type of a feature ID set.
*/
UENUM(BlueprintType)
enum class ECesiumFeatureIdSetType : uint8 {
None,
Attribute,
Texture,
Implicit,
Instance,
InstanceImplicit
};
/**
* @brief A blueprint-accessible wrapper for a feature ID set from a glTF
* primitive. A feature ID can be defined as a per-vertex attribute, as a
* feature texture, implicitly via vertex ID, or associated with glTF
* instances. These can be used with the corresponding {@link
* FCesiumPropertyTable} to access the metadata.
*/
USTRUCT(BlueprintType)
struct CESIUMRUNTIME_API FCesiumFeatureIdSet {
GENERATED_USTRUCT_BODY()
using FeatureIDType = std::variant<
std::monostate,
FCesiumFeatureIdAttribute,
FCesiumFeatureIdTexture>;
public:
FCesiumFeatureIdSet()
: _featureIDSetType(ECesiumFeatureIdSetType::None),
_featureCount(0),
_nullFeatureID(-1) {}
FCesiumFeatureIdSet(
const CesiumGltf::Model& Model,
const CesiumGltf::MeshPrimitive& Primitive,
const CesiumGltf::FeatureId& FeatureId);
FCesiumFeatureIdSet(
const CesiumGltf::Model& Model,
const CesiumGltf::Node& Node,
const CesiumGltf::ExtensionExtInstanceFeaturesFeatureId&
InstanceFeatureId);
private:
FeatureIDType _featureID;
ECesiumFeatureIdSetType _featureIDSetType;
int64 _featureCount;
int64 _nullFeatureID;
int64 _propertyTableIndex;
FString _label;
friend class UCesiumFeatureIdSetBlueprintLibrary;
};
UCLASS()
class CESIUMRUNTIME_API UCesiumFeatureIdSetBlueprintLibrary
: public UBlueprintFunctionLibrary {
GENERATED_BODY()
public:
/**
* Gets the type of this feature ID set.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Features|FeatureIDSet")
static const ECesiumFeatureIdSetType
GetFeatureIDSetType(UPARAM(ref) const FCesiumFeatureIdSet& FeatureIDSet);
/**
* Gets this feature ID set as a feature ID attribute. This can be used for
* more fine-grained interaction with the attribute itself. If this feature ID
* is not defined as an attribute, then the returned attribute will be
* invalid.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Features|FeatureIDSet")
static const FCesiumFeatureIdAttribute&
GetAsFeatureIDAttribute(UPARAM(ref) const FCesiumFeatureIdSet& FeatureIDSet);
/**
* Gets this feature ID set as a feature ID texture. This can be used for more
* fine-grained interaction with the texture itself. If this feature ID is
* not defined as a texture, then the returned texture will be invalid.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Features|FeatureIDSet")
static const FCesiumFeatureIdTexture&
GetAsFeatureIDTexture(UPARAM(ref) const FCesiumFeatureIdSet& FeatureIDSet);
/**
* Get the index of the property table corresponding to this feature
* ID set. The index can be used to fetch the appropriate
* FCesiumPropertyTable from the FCesiumModelMetadata. If the
* feature ID set does not specify a property table, this returns -1.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Features|FeatureIDSet")
static const int64
GetPropertyTableIndex(UPARAM(ref) const FCesiumFeatureIdSet& FeatureIDSet);
/**
* Get the number of features this primitive has.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Features|FeatureIDSet")
static int64 GetFeatureCount(UPARAM(ref)
const FCesiumFeatureIdSet& FeatureIDSet);
/**
* Gets the null feature ID, i.e., the value that indicates no feature is
* associated with the owner. In other words, if a vertex or texel returns
* this value, then it is not associated with any feature.
*
* If this value was not defined in the glTF feature ID set, this defaults to
* -1.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Features|FeatureIDSet")
static const int64
GetNullFeatureID(UPARAM(ref) const FCesiumFeatureIdSet& FeatureIDSet);
/**
* Gets the label assigned to this feature ID set. If no label was present in
* the glTF feature ID set, this returns an empty string.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Features|FeatureIDSet")
static const FString GetLabel(UPARAM(ref)
const FCesiumFeatureIdSet& FeatureIDSet);
/**
* Gets the feature ID associated with a given vertex. The feature ID can be
* used with a FCesiumPropertyTable to retrieve the corresponding metadata.
*
* This returns -1 if the given vertex is out-of-bounds, or if the feature ID
* set is invalid (e.g., it contains an invalid feature ID texture).
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Features|FeatureIDSet")
static int64 GetFeatureIDForVertex(
UPARAM(ref) const FCesiumFeatureIdSet& FeatureIDSet,
int64 VertexIndex);
/**
* Gets the feature ID associated with a given instance in glTF models using
* the EXT_mesh_gpu_instancing and EXT_instance_features extensions. The
* feature ID can be used with a FCesiumPropertyTable to retrieve the
* corresponding metadata.
*
* This returns -1 if the given instance is out-of-bounds, if the feature ID
* set is not for instances, or if the feature ID set is invalid (e.g., it
* contains an invalid feature ID attribute).
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Features|FeatureIDSet")
static int64 GetFeatureIDForInstance(
UPARAM(ref) const FCesiumFeatureIdSet& FeatureIDSet,
int64 InstanceIndex);
/**
* Given a trace hit result, gets the feature ID from the feature ID set on
* the hit component. This returns a more accurate value for feature ID
* textures, since they define feature IDs per-texel instead of per-vertex.
* The feature ID can be used with a FCesiumPropertyTable to retrieve the
* corresponding metadata.
*
* This can still retrieve the feature IDs for non-texture feature ID sets.
* For attribute or implicit feature IDs, the first feature ID associated
* with the first vertex of the intersected face is returned.
*
* This returns -1 if the feature ID set is invalid (e.g., it contains an
* invalid feature ID texture).
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Features|FeatureIDSet")
static int64 GetFeatureIDFromHit(
UPARAM(ref) const FCesiumFeatureIdSet& FeatureIDSet,
const FHitResult& Hit);
};

View File

@ -0,0 +1,233 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "Containers/UnrealString.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include <CesiumGltf/AccessorUtility.h>
#include <CesiumGltf/FeatureIdTextureView.h>
#include "CesiumFeatureIdTexture.generated.h"
namespace CesiumGltf {
struct Model;
struct FeatureIdTexture;
} // namespace CesiumGltf
/**
* @brief Reports the status of a FCesiumFeatureIdTexture. If the feature ID
* texture cannot be accessed, this briefly indicates why.
*/
UENUM(BlueprintType)
enum ECesiumFeatureIdTextureStatus {
/* The feature ID texture is valid. */
Valid = 0,
/* The feature ID texture cannot be found in the glTF, or the texture itself
has errors. */
ErrorInvalidTexture,
/* The feature ID texture is being read in an invalid way -- for example,
trying to read nonexistent image channels. */
ErrorInvalidTextureAccess,
};
/**
* @brief A blueprint-accessible wrapper for a feature ID texture from a glTF
* primitive. Provides access to per-pixel feature IDs, which can be used with
* the corresponding {@link FCesiumPropertyTable} to access per-pixel metadata.
*/
USTRUCT(BlueprintType)
struct CESIUMRUNTIME_API FCesiumFeatureIdTexture {
GENERATED_USTRUCT_BODY()
public:
/**
* @brief Constructs an empty feature ID texture instance. Empty feature ID
* textures can be constructed while trying to convert a FCesiumFeatureIdSet
* that is not an texture. In this case, the status reports it is an invalid
* texture.
*/
FCesiumFeatureIdTexture()
: _status(ECesiumFeatureIdTextureStatus::ErrorInvalidTexture) {}
/**
* @brief Constructs a feature ID texture instance.
*
* @param Model The model.
* @param Primitive The mesh primitive containing the feature ID texture.
* @param FeatureIdTexture The texture specified by the FeatureId.
* @param PropertyTableName The name of the property table this texture
* corresponds to, if one exists, for backwards compatibility.
*/
FCesiumFeatureIdTexture(
const CesiumGltf::Model& Model,
const CesiumGltf::MeshPrimitive& Primitive,
const CesiumGltf::FeatureIdTexture& FeatureIdTexture,
const FString& PropertyTableName);
/**
* @brief Gets the underlying view of this feature ID texture.
*/
constexpr const CesiumGltf::FeatureIdTextureView&
getFeatureIdTextureView() const {
return this->_featureIdTextureView;
}
private:
ECesiumFeatureIdTextureStatus _status;
CesiumGltf::FeatureIdTextureView _featureIdTextureView;
CesiumGltf::TexCoordAccessorType _texCoordAccessor;
int64 _textureCoordinateSetIndex;
// For backwards compatibility.
FString _propertyTableName;
friend class UCesiumFeatureIdTextureBlueprintLibrary;
};
UCLASS()
class CESIUMRUNTIME_API UCesiumFeatureIdTextureBlueprintLibrary
: public UBlueprintFunctionLibrary {
GENERATED_BODY()
public:
PRAGMA_DISABLE_DEPRECATION_WARNINGS
/**
* Gets the name of the feature table corresponding to this feature ID
* texture. The name can be used to fetch the appropriate
* {@link FCesiumPropertyTable} from the FCesiumMetadataModel.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|FeatureIdTexture",
Meta =
(DeprecatedFunction,
DeprecationMessage =
"Use GetPropertyTableIndex on a CesiumFeatureIdSet instead."))
static const FString&
GetFeatureTableName(UPARAM(ref)
const FCesiumFeatureIdTexture& FeatureIDTexture);
PRAGMA_ENABLE_DEPRECATION_WARNINGS
/**
* Gets the status of the feature ID texture. If this texture is
* invalid in any way, this will briefly indicate why.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Features|FeatureIDTexture")
static ECesiumFeatureIdTextureStatus GetFeatureIDTextureStatus(
UPARAM(ref) const FCesiumFeatureIdTexture& FeatureIDTexture);
/**
* Gets the glTF texture coordinate set index used by the feature ID texture.
* This is the index N corresponding to the "TEXCOORD_N" attribute on the glTF
* primitive that samples this texture.
*
* If the texture contains the `KHR_texture_transform` extension, the original
* texture coordinate set index can be overridden by the one provided by the
* extension.
*
* If the feature ID texture is invalid, this returns -1.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Features|FeatureIDTexture")
static int64 GetGltfTextureCoordinateSetIndex(
UPARAM(ref) const FCesiumFeatureIdTexture& FeatureIDTexture);
/**
* Gets the UV channel containing the texture coordinate set that is used by
* the feature ID texture on the given component. This refers to the UV
* channel it uses on the primitive's static mesh, which is not necessarily
* equal to value of GetGltfTextureCoordinateSetIndex.
*
* This function may be used with FindCollisionUV to get the feature ID from a
* line trace hit. However, in order for this function to work, the feature ID
* texture should be listed under the CesiumFeaturesMetadataComponent of the
* owner Cesium3DTileset. Otherwise, its texture coordinate set may not be
* included in the Unreal mesh data. To avoid using
* CesiumFeaturesMetadataComponent, use GetFeatureIDFromHit instead.
*
* This returns -1 if the feature ID texture is invalid, or if the specified
* texture coordinate set is not present in the component's mesh data.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Features|FeatureIDTexture")
static int64 GetUnrealUVChannel(
const UPrimitiveComponent* Component,
UPARAM(ref) const FCesiumFeatureIdTexture& FeatureIDTexture);
PRAGMA_DISABLE_DEPRECATION_WARNINGS
/**
* Gets the feature ID corresponding to the pixel specified by the texture
* coordinates. The feature ID can be used with a FCesiumPropertyTable to
* retrieve the per-pixel metadata.
*
* This assumes the given texture coordinates are from the appropriate
* texture coordinate set as indicated by GetTextureCoordinateSetIndex. If the
* feature ID texture is invalid, this returns -1.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Features|FeatureIDTexture")
static int64 GetFeatureIDForTextureCoordinates(
UPARAM(ref) const FCesiumFeatureIdTexture& FeatureIDTexture,
float U,
float V);
PRAGMA_ENABLE_DEPRECATION_WARNINGS
/**
* Gets the feature ID corresponding to the pixel specified by the UV texture
* coordinates. The feature ID can be used with a FCesiumPropertyTable to
* retrieve the per-pixel metadata.
*
* If the feature ID texture is invalid, this returns -1.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Features|FeatureIDTexture")
static int64 GetFeatureIDForUV(
UPARAM(ref) const FCesiumFeatureIdTexture& FeatureIDTexture,
const FVector2D& UV);
/**
* Gets the feature ID associated with the given vertex. The
* feature ID can be used with a FCesiumPropertyTable to retrieve the
* per-vertex metadata.
*
* This works if the vertex contains texture coordinates for the relevant
* texture coordinate set as indicated by GetGltfTextureCoordinateSetIndex. If
* the vertex has no such coordinates, or if the feature ID texture itself is
* invalid, this returns -1.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Features|FeatureIDTexture")
static int64 GetFeatureIDForVertex(
UPARAM(ref) const FCesiumFeatureIdTexture& FeatureIDTexture,
int64 VertexIndex);
/**
* Gets the feature ID from a given line trace hit on the primitive containing
* this feature ID texture. The feature ID can be used with a
* FCesiumPropertyTable to retrieve the corresponding metadata.
*
* If the feature ID texture is invalid, this returns -1.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Features|FeatureIDTexture")
static int64 GetFeatureIDFromHit(
UPARAM(ref) const FCesiumFeatureIdTexture& FeatureIDTexture,
const FHitResult& Hit);
};

View File

@ -0,0 +1,415 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumFeatureIdSet.h"
#include "CesiumMetadataEncodingDetails.h"
#include "CesiumMetadataPropertyDetails.h"
#include "Components/ActorComponent.h"
#include "Containers/Array.h"
#include "Containers/UnrealString.h"
#include "Misc/Guid.h"
#if WITH_EDITOR
#include "Materials/MaterialFunctionMaterialLayer.h"
#endif
#include "CesiumFeaturesMetadataComponent.generated.h"
#pragma region Features descriptions
/**
* @brief Description of a feature ID set from EXT_mesh_features.
*/
USTRUCT()
struct CESIUMRUNTIME_API FCesiumFeatureIdSetDescription {
GENERATED_USTRUCT_BODY()
/**
* The display name of the feature ID set. If the feature ID set already has a
* label, this will use the label. Otherwise, if the feature ID set is
* unlabeled, a name will be generated like so:
*
* - If the feature ID set is an attribute, this will appear as
* "_FEATURE_ID_\<index\>", where \<index\> is the set index specified in
* the attribute.
* - If the feature ID set is a texture, this will appear as
* "_FEATURE_ID_TEXTURE_\<index\>", where \<index\> increments with the number
* of feature ID textures seen in an individual primitive.
* - If the feature ID set is an implicit set, this will appear as
* "_IMPLICIT_FEATURE_ID". Implicit feature ID sets don't vary in definition,
* so any additional implicit feature ID sets across the primitives are
* counted by this one.
*
* This name will also be used to represent the feature ID set in the
* generated material.
*/
UPROPERTY(EditAnywhere, Category = "Cesium")
FString Name;
/**
* The type of the feature ID set.
*/
UPROPERTY(EditAnywhere, Category = "Cesium")
ECesiumFeatureIdSetType Type = ECesiumFeatureIdSetType::None;
/**
* Whether this feature ID set contains a KHR_texture_transform glTF
* extension. Only applicable if the feature ID set is a feature ID texture.
*/
UPROPERTY(
EditAnywhere,
Category = "Cesium",
Meta = (EditCondition = "Type == ECesiumFeatureIdSetType::Texture"))
bool bHasKhrTextureTransform = false;
/**
* The name of the property table that this feature ID set corresponds to.
*/
UPROPERTY(EditAnywhere, Category = "Cesium")
FString PropertyTableName;
/**
* The null feature ID for the feature ID set. This value indicates that no
* feature is associated with the vertex or texel containing the value. If no
* such value is specified, this defaults to -1, which prevents it from being
* unnecessarily included in the generated material.
*/
UPROPERTY(EditAnywhere, Category = "Cesium")
bool bHasNullFeatureId = false;
};
/**
* @brief Description of the feature ID sets available from the
* EXT_mesh_features on a glTF's primitives.
*
* This aggregates the feature ID sets of all visible glTF primitives in the
* model. This describes the feature IDs that can be made accessible
* to Unreal Engine materials.
*/
USTRUCT()
struct CESIUMRUNTIME_API FCesiumPrimitiveFeaturesDescription {
GENERATED_USTRUCT_BODY()
/**
* @brief The feature ID sets to make accessible to the material. Note that
* the order of feature ID sets in this array does not necessarily
* correspond to the order of these feature ID sets in a glTF
* primitive.
*/
UPROPERTY(
EditAnywhere,
Category = "Features",
Meta = (TitleProperty = "Name"))
TArray<FCesiumFeatureIdSetDescription> FeatureIdSets;
};
#pragma endregion
#pragma region Metadata descriptions
// These don't exhaustively cover the possibilities of glTF metadata
// classes, they only cover the subset that can be encoded into textures. The
// following types are excluded:
// - enums
// - strings that cannot be parsed as numbers or colors
// - matrices
// - variable length arrays
// - arrays of non-scalar, non-boolean elements
//
// Additionally, if a property contains fixed-length arrays, only the first four
// elements can be encoded.
/**
* @brief Description of a property table property that should be encoded for
* access on the GPU.
*/
USTRUCT()
struct CESIUMRUNTIME_API FCesiumPropertyTablePropertyDescription {
GENERATED_USTRUCT_BODY()
/**
* The name of this property. This will be how it is referenced in the
* material.
*/
UPROPERTY(EditAnywhere, Category = "Cesium")
FString Name;
/**
* Describes the underlying type of this property and other relevant
* information from its EXT_structural_metadata definition. Not all types of
* properties can be encoded to the GPU, or coerced to GPU-compatible types.
*/
UPROPERTY(EditAnywhere, Category = "Cesium")
FCesiumMetadataPropertyDetails PropertyDetails;
/**
* Describes how the property will be encoded as data on the GPU, if possible.
*/
UPROPERTY(EditAnywhere, Category = "Cesium")
FCesiumMetadataEncodingDetails EncodingDetails;
};
/**
* @brief Description of a property table containing properties to be encoded
* for access in Unreal materials.
*/
USTRUCT()
struct CESIUMRUNTIME_API FCesiumPropertyTableDescription {
GENERATED_USTRUCT_BODY()
/**
* @brief The name of this property table. If this property table has no name
* in the EXT_structural_metadata extension, then its class name is used
* instead.
*/
UPROPERTY(EditAnywhere, Category = "Cesium")
FString Name;
/**
* @brief Descriptions of the properties to upload to the GPU.
*/
UPROPERTY(EditAnywhere, Category = "Cesium", Meta = (TitleProperty = "Name"))
TArray<FCesiumPropertyTablePropertyDescription> Properties;
};
/**
* @brief Description of a property texture property that should be made
* accessible to Unreal materials. A property texture property's data is
* already available through a texture, so no additional encoding details need
* to be specified.
*/
USTRUCT()
struct CESIUMRUNTIME_API FCesiumPropertyTexturePropertyDescription {
GENERATED_USTRUCT_BODY()
/**
* The name of this property. This will be how it is referenced in the
* material.
*/
UPROPERTY(EditAnywhere, Category = "Cesium")
FString Name;
/**
* Describes the underlying type of this property and other relevant
* information from its EXT_structural_metadata definition.
*/
UPROPERTY(EditAnywhere, Category = "Cesium")
FCesiumMetadataPropertyDetails PropertyDetails;
/**
* Whether this property texture property contains a KHR_texture_transform
* glTF extension.
*/
UPROPERTY(EditAnywhere, Category = "Cesium")
bool bHasKhrTextureTransform = false;
};
/**
* @brief Description of a property texture with properties that should be
* made accessible to Unreal materials.
*/
USTRUCT()
struct CESIUMRUNTIME_API FCesiumPropertyTextureDescription {
GENERATED_USTRUCT_BODY()
/**
* @brief The name of this property texture.
*/
UPROPERTY(EditAnywhere, Category = "Cesium")
FString Name;
/**
* @brief Descriptions of the properties to upload to the GPU.
*/
UPROPERTY(EditAnywhere, Category = "Cesium", Meta = (TitleProperty = "Name"))
TArray<FCesiumPropertyTexturePropertyDescription> Properties;
};
/**
* @brief Names of the metadata entities referenced by the
* EXT_structural_metadata on a glTF's primitives.
*
* This aggregates the metadata of all visible glTF primitives in the model.
* This lists the names of the property textures actually used by the glTF
* primitive, indicating it can be sampled with the primitive's texture
* coordinates in the Unreal material.
*/
USTRUCT()
struct CESIUMRUNTIME_API FCesiumPrimitiveMetadataDescription {
GENERATED_USTRUCT_BODY()
/**
* @brief The names of the property textures used by the glTF primitives
* across the tileset.
*
* This should be a subset of the property textures listed in the model
* metadata. Property textures can be passed to the material even if they are
* not explicitly used by a glTF primitive, but the primitive may lack the
* corresponding sets of texture coordinates intended to sample them.
*/
UPROPERTY(
EditAnywhere,
Category = "Metadata",
Meta = (TitleProperty = "Name"))
TSet<FString> PropertyTextureNames;
};
/**
* @brief Description of metadata from a glTF's EXT_structural_metadata
* extension that should be uploaded to the GPU for access in Unreal materials.
*/
USTRUCT()
struct CESIUMRUNTIME_API FCesiumModelMetadataDescription {
GENERATED_USTRUCT_BODY()
/**
* @brief Descriptions of property tables to encode for access in Unreal
* materials.
*/
UPROPERTY(
EditAnywhere,
Category = "Metadata",
Meta = (TitleProperty = "Name"))
TArray<FCesiumPropertyTableDescription> PropertyTables;
/**
* @brief Descriptions of property textures to make accessible to Unreal
* materials.
*/
UPROPERTY(
EditAnywhere,
Category = "Metadata",
Meta = (TitleProperty = "Name"))
TArray<FCesiumPropertyTextureDescription> PropertyTextures;
};
#pragma endregion
/**
* @brief Description of both feature IDs and metadata from a glTF via the
* EXT_mesh_Features and EXT_structural_metadata extensions. Indicates what
* parts of the extension should be uploaded to the GPU for access in Unreal
* materials.
*/
USTRUCT()
struct CESIUMRUNTIME_API FCesiumFeaturesMetadataDescription {
GENERATED_USTRUCT_BODY()
public:
/**
* @brief Description of the feature ID sets available from the
* EXT_mesh_features on a glTF's primitives.
*/
FCesiumPrimitiveFeaturesDescription Features;
/**
* @brief Description of the metadata used by the EXT_structural_metadata on a
* glTF's primitives.
*/
FCesiumPrimitiveMetadataDescription PrimitiveMetadata;
/**
* @brief Description of metadata from a glTF's EXT_structural_metadata
* extension.
*/
FCesiumModelMetadataDescription ModelMetadata;
};
/**
* @brief A component that can be added to Cesium3DTileset actors to
* dictate what metadata to encode for access on the GPU. The selection can be
* automatically populated based on available metadata by clicking the
* "Auto Fill" button. Once a selection of desired metadata is made, the
* boiler-plate material code to access the selected properties can be
* auto-generated using the "Generate Material" button.
*/
UCLASS(ClassGroup = (Cesium), Meta = (BlueprintSpawnableComponent))
class CESIUMRUNTIME_API UCesiumFeaturesMetadataComponent
: public UActorComponent {
GENERATED_BODY()
public:
#if WITH_EDITOR
/**
* Populate the description of metadata and feature IDs using the current view
* of the tileset. This determines what to encode to the GPU based on the
* existing metadata.
*
* Warning: Using Auto Fill may populate the description with a large amount
* of metadata. Make sure to delete the properties that aren't relevant.
*/
UFUNCTION(CallInEditor, Category = "Cesium")
void AutoFill();
/**
* This button can be used to create a boiler-plate material layer that
* exposes the requested metadata properties in the current description. The
* nodes to access the metadata will be added to TargetMaterialLayer if it
* exists. Otherwise a new material layer will be created in the /Content/
* folder and TargetMaterialLayer will be set to the new material layer.
*/
UFUNCTION(CallInEditor, Category = "Cesium")
void GenerateMaterial();
#endif
#if WITH_EDITORONLY_DATA
/**
* This is the target UMaterialFunctionMaterialLayer that the
* boiler-plate material generation will use. When pressing
* "Generate Material", nodes will be added to this material to enable access
* to the requested metadata. If this is left blank, a new material layer
* will be created in the /Game/ folder.
*/
UPROPERTY(EditAnywhere, Category = "Cesium")
UMaterialFunctionMaterialLayer* TargetMaterialLayer = nullptr;
#endif
// Using the FCesiumPrimitiveFeaturesDescription and
// FCesiumModelMetadataDescription structs makes the UI less readable, so the
// component uses arrays directly to help flatten the UI.
/**
* Description of the feature ID sets in the visible glTF primitives across
* the tileset.
*/
UPROPERTY(
EditAnywhere,
Category = "Cesium|Primitive Features",
Meta = (TitleProperty = "Name"))
TArray<FCesiumFeatureIdSetDescription> FeatureIdSets;
/**
* Names of the property textures used by the glTF primitives across the
* tileset.
*
* This should be a subset of the property textures listed in the model
* metadata. Property textures can be passed to the material even if they are
* not explicitly used by a glTF primitive, but the primitive may lack the
* corresponding sets of texture coordinates intended to sample them.
*/
UPROPERTY(
EditAnywhere,
Category = "Cesium|Primitive Metadata",
Meta = (TitleProperty = "Name"))
TSet<FString> PropertyTextureNames;
/**
* Descriptions of the property tables in the visible glTF
* models across the tileset.
*/
UPROPERTY(
EditAnywhere,
Category = "Cesium|Model Metadata",
Meta = (TitleProperty = "Name"))
TArray<FCesiumPropertyTableDescription> PropertyTables;
/**
* Descriptions of property textures in the visible glTF models across
* the tileset.
*/
UPROPERTY(
EditAnywhere,
Category = "Cesium|Model Metadata",
Meta = (TitleProperty = "Name"))
TArray<FCesiumPropertyTextureDescription> PropertyTextures;
};

View File

@ -0,0 +1,221 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumGeospatial/SimplePlanarEllipsoidCurve.h"
#include "CesiumGlobeAnchoredActorComponent.h"
#include "CesiumFlyToComponent.generated.h"
class UCurveFloat;
class UCesiumGlobeAnchorComponent;
/**
* The delegate for when the Actor finishes flying.
*/
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FCesiumFlightCompleted);
/**
* The delegate for when the Actor's flight is interrupted.
*/
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FCesiumFlightInterrupted);
/**
* Indicates which rotation to use for orienting the object during flights.
*/
UENUM(BlueprintType)
enum class ECesiumFlyToRotation : uint8 {
/**
* Uses the relative rotation of the root component of the Actor to which the
* CesiumFlyToComponent is attached.
*/
Actor,
/**
* Uses the ControlRotation of the Controller of the Pawn to which the
* CesiumFlyToComponent is attached. The ControlRotation is interpreted as
* being relative to the Unreal coordinate system.
*
* If the component is attached to an Actor that is not a Pawn, or if the Pawn
* does not have a Controller, this option is equivalent to the "Actor"
* option.
*/
ControlRotationInUnreal,
/**
* Uses the ControlRotation of the Controller of the Pawn to which the
* CesiumFlyToComponent is attached. The ControlRotation is interpreted as
* being relative to the Pawn's local East-South-Up coordinate system.
*
* This is the option to use with a GlobeAwareDefaultPawn or a DynamicPawn,
* because those classes interpret the ControlRotation as being relative to
* East-South-Up.
*
* If the component is attached to an Actor that is not a Pawn, or if the Pawn
* does not have a Controller, this option is equivalent to the "Actor"
* option.
*/
ControlRotationInEastSouthUp
};
/**
* Smoothly animates the Actor to which it is attached on a flight to a new
* location on the globe.
*/
UCLASS(ClassGroup = "Cesium", Meta = (BlueprintSpawnableComponent))
class CESIUMRUNTIME_API UCesiumFlyToComponent
: public UCesiumGlobeAnchoredActorComponent {
GENERATED_BODY()
public:
UCesiumFlyToComponent();
/**
* A curve that is used to determine the flight progress percentage for all
* the other curves. The input is the fraction (0.0 to 1.0) of the total time
* that has passed so far, and the output is the fraction of the total curve
* that should be traversed at this time. This curve allows the Actor to
* accelerate and deaccelerate as desired throughout the flight.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
UCurveFloat* ProgressCurve;
/**
* A curve that controls what percentage of the maximum height the Actor
* should take at a given time on the flight. This curve must be kept in the 0
* to 1 range on both axes. The MaximumHeightByDistanceCurve controls the
* actual maximum height that is achieved during the flight.
*
* If this curve is not specified, the height will be a smooth interpolation
* between the height at the original location and the height at the
* destination location, and the MaximumHeightByDistanceCurve will be ignored.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
UCurveFloat* HeightPercentageCurve;
/**
* A curve that controls the maximum height that will be achieved during the
* flight as a function of the straight-line distance of the flight, in
* meters. If the start and end point are on opposite sides of the globe, the
* straight-line distance goes through the Earth even though the flight itself
* will not.
*
* If HeightPercentageCurve is not specified, this property is ignored.
* If HeightPercentageCurve is specified, but this property is not, then the
* maximum height is 30,000 meters regardless of distance.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
UCurveFloat* MaximumHeightByDistanceCurve;
/**
* The length in seconds that the flight should last.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium",
meta = (ClampMin = 0.0))
float Duration = 5.0f;
/**
* Indicates which rotation to use during flights.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
ECesiumFlyToRotation RotationToUse = ECesiumFlyToRotation::Actor;
/**
* A delegate that will be called when the Actor finishes flying.
*
*/
UPROPERTY(BlueprintAssignable, Category = "Cesium");
FCesiumFlightCompleted OnFlightComplete;
/**
* A delegate that will be called when the Actor's flight is interrupted.
*
*/
UPROPERTY(BlueprintAssignable, Category = "Cesium");
FCesiumFlightInterrupted OnFlightInterrupted;
/**
* Begin a smooth flight to the given Earth-Centered, Earth-Fixed
* (ECEF) destination, such that the Actor ends at the specified yaw and
* pitch. The yaw and pitch are expressed relative to an East-South-Up frame
* at the destination. The characteristics of the flight can be configured
* with the properties on this component.
*
* If CanInterruptByMoving is true and the Actor moves independent of this
* component, then the flight in progress will be canceled.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
void FlyToLocationEarthCenteredEarthFixed(
const FVector& EarthCenteredEarthFixedDestination,
double YawAtDestination,
double PitchAtDestination,
bool CanInterruptByMoving);
/**
* Begin a smooth camera flight to the given WGS84 longitude in degrees (x),
* latitude in degrees (y), and height in meters (z) such that the camera
* ends at the given yaw and pitch. The yaw and pitch are expressed relative
* to an East-South-Up frame at the destination. The characteristics of the
* flight can be configured with the properties on this component.
*
* Note that the height is measured in meters above the WGS84 ellipsoid, and
* should not be confused with a height relative to mean sea level, which may
* be tens of meters different depending on where you are on the globe.
*
* If CanInterruptByMoving is true and the Actor moves independent of this
* component, then the flight in progress will be canceled.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
void FlyToLocationLongitudeLatitudeHeight(
const FVector& LongitudeLatitudeHeightDestination,
double YawAtDestination,
double PitchAtDestination,
bool CanInterruptByMoving);
/**
* Begin a smooth flight to the given destination in Unreal coordinates, such
* that the Actor ends at the specified yaw and pitch. The yaw and pitch are
* expressed relative to an East-South-Up frame at the destination. The
* characteristics of the flight can be configured with the properties on this
* component.
*
* If CanInterruptByMoving is true and the Actor moves independent of this
* component, then the flight in progress will be canceled.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
void FlyToLocationUnreal(
const FVector& UnrealDestination,
double YawAtDestination,
double PitchAtDestination,
bool CanInterruptByMoving);
/**
* Interrupts the flight that is currently in progress, leaving the Actor
* wherever it is currently.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
void InterruptFlight();
protected:
virtual void TickComponent(
float DeltaTime,
ELevelTick TickType,
FActorComponentTickFunction* ThisTickFunction) override;
private:
FQuat GetCurrentRotationEastSouthUp();
void SetCurrentRotationEastSouthUp(const FQuat& EastSouthUpRotation);
bool _flightInProgress = false;
bool _canInterruptByMoving;
float _currentFlyTime;
double _maxHeight;
FVector _destinationEcef;
FQuat _sourceRotation;
FQuat _destinationRotation;
FVector _previousPositionEcef;
TUniquePtr<CesiumGeospatial::SimplePlanarEllipsoidCurve> _currentCurve;
double _length;
};

View File

@ -0,0 +1,868 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumEllipsoid.h"
#include "CesiumGeospatial/LocalHorizontalCoordinateSystem.h"
#include "CesiumSubLevel.h"
#include "Delegates/Delegate.h"
#include "GameFramework/Actor.h"
#include "GeoTransforms.h"
#include "OriginPlacement.h"
#include "CesiumGeoreference.generated.h"
class APlayerCameraManager;
class FLevelCollectionModel;
class UCesiumSubLevelSwitcherComponent;
/**
* The delegate for the ACesiumGeoreference::OnGeoreferenceUpdated,
* which is triggered from UpdateGeoreference
*/
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FGeoreferenceUpdated);
/**
* The event that triggers when a georeference's ellipsoid is changed.
* This should be used for performing any necessary coordinate changes.
* The parameters are (OldEllipsoid, NewEllipsoid).
*/
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(
FGeoreferenceEllipsoidChanged,
UCesiumEllipsoid*,
OldEllipsoid,
UCesiumEllipsoid*,
NewEllipsoid);
/**
* Controls how global geospatial coordinates are mapped to coordinates in the
* Unreal Engine level. Internally, Cesium uses a global Earth-centered,
* Earth-fixed (ECEF) ellipsoid-centered coordinate system, where the ellipsoid
* is usually the World Geodetic System 1984 (WGS84) ellipsoid. This is a
* right-handed system centered at the Earth's center of mass, where +X is in
* the direction of the intersection of the Equator and the Prime Meridian (zero
* degrees longitude), +Y is in the direction of the intersection of the Equator
* and +90 degrees longitude, and +Z is through the North Pole. This Actor is
* used by other Cesium Actors and components to control how this coordinate
* system is mapped into an Unreal Engine world and level.
*/
UCLASS()
class CESIUMRUNTIME_API ACesiumGeoreference : public AActor {
GENERATED_BODY()
public:
/**
* The minimum allowed value for the Scale property, 1e-6.
*/
static const double kMinimumScale;
/**
* Finds and returns a CesiumGeoreference in the world. It searches in the
* following order:
*
* 1. A CesiumGeoreference that is tagged with "DEFAULT_GEOREFERENCE" and
* found in the PersistentLevel.
* 2. A CesiumGeoreference with the name "CesiumGeoreferenceDefault" and found
* in the PersistentLevel.
* 3. Any CesiumGeoreference in the PersistentLevel.
*
* If no CesiumGeoreference is found with this search, a new one is created in
* the persistent level and given the "DEFAULT_GEOREFERENCE" tag.
*/
UFUNCTION(
BlueprintCallable,
Category = "Cesium",
meta = (WorldContext = "WorldContextObject"))
static ACesiumGeoreference*
GetDefaultGeoreference(const UObject* WorldContextObject);
/**
* Finds and returns the CesiumGeoreference suitable for use with the given
* Actor. It searches in the following order:
*
* 1. A CesiumGeoreference that is an attachment parent of the given Actor.
* 2. A CesiumGeoreference that is tagged with "DEFAULT_GEOREFERENCE" and
* found in the PersistentLevel.
* 3. A CesiumGeoreference with the name "CesiumGeoreferenceDefault" and found
* in the PersistentLevel.
* 4. Any CesiumGeoreference in the PersistentLevel.
*
* If no CesiumGeoreference is found with this search, a new one is created in
* the persistent level and given the "DEFAULT_GEOREFERENCE" tag.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
static ACesiumGeoreference* GetDefaultGeoreferenceForActor(AActor* Actor);
/**
* A delegate that will be called whenever the Georeference is
* modified in a way that affects its computations.
*/
UPROPERTY(BlueprintAssignable, Category = "Cesium")
FGeoreferenceUpdated OnGeoreferenceUpdated;
/**
* An event that will be called whenever the georeference's ellipsoid has
* been modified.
*/
UPROPERTY(BlueprintAssignable, Category = "Cesium")
FGeoreferenceEllipsoidChanged OnEllipsoidChanged;
#pragma region Properties
private:
/**
* The Ellipsoid being used by this georeference. The ellipsoid informs how
* cartographic coordinates will be interpreted and how they are transformed
* into cartesian coordinates.
*/
UPROPERTY(
Category = "Cesium",
EditAnywhere,
BlueprintReadWrite,
BlueprintGetter = GetEllipsoid,
BlueprintSetter = SetEllipsoid,
meta = (AllowPrivateAccess))
UCesiumEllipsoid* Ellipsoid;
/**
* The placement of this Actor's origin (coordinate 0,0,0) within the tileset.
*
* 3D Tiles tilesets often use Earth-centered, Earth-fixed coordinates, such
* that the tileset content is in a small bounding volume 6-7 million meters
* (the radius of the Earth) away from the coordinate system origin. This
* property allows an alternative position, other then the tileset's true
* origin, to be treated as the origin for the purpose of this Actor. Using
* this property will preserve vertex precision (and thus avoid jittering)
* much better than setting the Actor's Transform property.
*/
UPROPERTY(
Category = "Cesium",
EditAnywhere,
BlueprintReadWrite,
BlueprintGetter = GetOriginPlacement,
BlueprintSetter = SetOriginPlacement,
meta = (AllowPrivateAccess))
EOriginPlacement OriginPlacement = EOriginPlacement::CartographicOrigin;
/**
* The latitude of the custom origin placement in degrees, in the range [-90,
* 90]
*/
UPROPERTY(
Category = "Cesium",
EditAnywhere,
BlueprintReadWrite,
BlueprintGetter = GetOriginLatitude,
BlueprintSetter = SetOriginLatitude,
Interp,
meta =
(AllowPrivateAccess,
EditCondition =
"OriginPlacement==EOriginPlacement::CartographicOrigin",
ClampMin = -90.0,
ClampMax = 90.0))
double OriginLatitude = 39.736401;
/**
* The longitude of the custom origin placement in degrees, in the range
* [-180, 180]
*/
UPROPERTY(
Category = "Cesium",
EditAnywhere,
BlueprintReadWrite,
BlueprintGetter = GetOriginLongitude,
BlueprintSetter = SetOriginLongitude,
Interp,
meta =
(AllowPrivateAccess,
EditCondition =
"OriginPlacement==EOriginPlacement::CartographicOrigin",
ClampMin = -180.0,
ClampMax = 180.0))
double OriginLongitude = -105.25737;
/**
* The height of the custom origin placement in meters above the
* ellipsoid.
*/
UPROPERTY(
Category = "Cesium",
EditAnywhere,
BlueprintReadWrite,
BlueprintGetter = GetOriginHeight,
BlueprintSetter = SetOriginHeight,
Interp,
meta =
(AllowPrivateAccess,
EditCondition =
"OriginPlacement==EOriginPlacement::CartographicOrigin"))
double OriginHeight = 2250.0;
/**
* The percentage scale of the globe in the Unreal world. If this value is 50,
* for example, one meter on the globe occupies half a meter in the Unreal
* world.
*/
UPROPERTY(
Category = "Cesium",
EditAnywhere,
BlueprintReadWrite,
BlueprintSetter = SetScale,
BlueprintGetter = GetScale,
Interp,
Meta = (AllowPrivateAccess, UIMin = 0.000001, UIMax = 100.0))
double Scale = 100.0;
/**
* The camera to use to determine which sub-level is closest, so that one can
* be activated and all others deactivated.
* @deprecated Add a CesiumOriginShiftComponent to the appropriate Actor
* instead.
*/
UPROPERTY(
meta =
(DeprecatedProperty,
DeprecationMessage =
"Add a CesiumOriginShiftComponent to the appropriate Actor instead."))
APlayerCameraManager* SubLevelCamera_DEPRECATED = nullptr;
/**
* The component that allows switching between the sub-levels registered with
* this georeference.
*/
UPROPERTY(
Instanced,
Category = "Cesium|Sub-levels",
BlueprintReadOnly,
BlueprintGetter = GetSubLevelSwitcher,
meta = (AllowPrivateAccess))
UCesiumSubLevelSwitcherComponent* SubLevelSwitcher;
#if WITH_EDITORONLY_DATA
/**
* Whether to visualize the level loading radii in the editor. Helpful for
* initially positioning the level and choosing a load radius.
*/
UPROPERTY(
Category = "Cesium|Sub-levels",
EditAnywhere,
BlueprintReadWrite,
BlueprintGetter = GetShowLoadRadii,
BlueprintSetter = SetShowLoadRadii,
meta = (AllowPrivateAccess))
bool ShowLoadRadii = true;
#endif
#pragma endregion
#pragma region PropertyAccessors
public:
/**
* Returns the georeference origin position as an FVector where `X` is
* longitude (degrees), `Y` is latitude (degrees), and `Z` is height above the
* ellipsoid (meters). Only valid if the placement type is Cartographic Origin
* (i.e. Longitude / Latitude / Height).
*/
UFUNCTION(BlueprintPure, Category = "Cesium")
FVector GetOriginLongitudeLatitudeHeight() const;
/**
* This aligns the specified longitude in degrees (X), latitude in
* degrees (Y), and height above the ellipsoid in meters (Z) to the Unreal
* origin. That is, it moves the globe so that these coordinates exactly fall
* on the origin. Only valid if the placement type is Cartographic Origin
* (i.e. Longitude / Latitude / Height).
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
void SetOriginLongitudeLatitudeHeight(
const FVector& TargetLongitudeLatitudeHeight);
/**
* Returns the georeference origin position as an FVector in Earth-Centerd,
* Earth-Fixed (ECEF) coordinates. Only valid if the placement type is
* Cartographic Origin (i.e. Longitude / Latitude / Height).
*/
UFUNCTION(BlueprintPure, Category = "Cesium")
FVector GetOriginEarthCenteredEarthFixed() const;
/**
* This aligns the specified Earth-Centered, Earth-Fixed (ECEF) coordinates to
* the Unreal origin. That is, it moves the globe so that these coordinates
* exactly fall on the origin. Only valid if the placement type is
* Cartographic Origin (i.e. Longitude / Latitude / Height). Note that if the
* provided ECEF coordiantes are near the center of the Earth so that
* Longitude, Latitude, and Height are undefined, this function will instead
* place the origin at 0 degrees longitude, 0 degrees latitude, and 0 meters
* height about the ellipsoid.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
void SetOriginEarthCenteredEarthFixed(
const FVector& TargetEarthCenteredEarthFixed);
/**
* Gets the placement of this Actor's origin (coordinate 0,0,0) within the
* tileset.
*
* 3D Tiles tilesets often use Earth-centered, Earth-fixed coordinates, such
* that the tileset content is in a small bounding volume 6-7 million meters
* (the radius of the Earth) away from the coordinate system origin. This
* property allows an alternative position, other then the tileset's true
* origin, to be treated as the origin for the purpose of this Actor. Using
* this property will preserve vertex precision (and thus avoid jittering)
* much better than setting the Actor's Transform property.
*/
UFUNCTION(BlueprintGetter)
EOriginPlacement GetOriginPlacement() const;
/**
* Sets the placement of this Actor's origin (coordinate 0,0,0) within the
* tileset.
*
* 3D Tiles tilesets often use Earth-centered, Earth-fixed coordinates, such
* that the tileset content is in a small bounding volume 6-7 million meters
* (the radius of the Earth) away from the coordinate system origin. This
* property allows an alternative position, other then the tileset's true
* origin, to be treated as the origin for the purpose of this Actor. Using
* this property will preserve vertex precision (and thus avoid jittering)
* much better than setting the Actor's Transform property.
*/
UFUNCTION(BlueprintSetter)
void SetOriginPlacement(EOriginPlacement NewValue);
/**
* Gets the latitude of the custom origin placement in degrees, in the range
* [-90, 90]
*/
UFUNCTION(BlueprintGetter)
double GetOriginLatitude() const;
/**
* Sets the latitude of the custom origin placement in degrees, in the range
* [-90, 90]
*/
UFUNCTION(BlueprintSetter)
void SetOriginLatitude(double NewValue);
/**
* Gets the longitude of the custom origin placement in degrees, in the range
* [-180, 180]
*/
UFUNCTION(BlueprintGetter)
double GetOriginLongitude() const;
/**
* Sets the longitude of the custom origin placement in degrees, in the range
* [-180, 180]
*/
UFUNCTION(BlueprintSetter)
void SetOriginLongitude(double NewValue);
/**
* Gets the height of the custom origin placement in meters above the
* ellipsoid.
*/
UFUNCTION(BlueprintGetter)
double GetOriginHeight() const;
/**
* Sets the height of the custom origin placement in meters above the
* ellipsoid.
*/
UFUNCTION(BlueprintSetter)
void SetOriginHeight(double NewValue);
/**
* Gets the percentage scale of the globe in the Unreal world. If this value
* is 50, for example, one meter on the globe occupies half a meter in the
* Unreal world.
*/
UFUNCTION(BlueprintGetter)
double GetScale() const;
/**
* Sets the percentage scale of the globe in the Unreal world. If this value
* is 50, for example, one meter on the globe occupies half a meter in the
* Unreal world.
*/
UFUNCTION(BlueprintSetter)
void SetScale(double NewValue);
/**
* Gets the camera to use to determine which sub-level is closest, so that one
* can be activated and all others deactivated.
*/
UE_DEPRECATED(
"Cesium For Unreal v2.0",
"Add a CesiumOriginShiftComponent to the appropriate Actor instead.")
UFUNCTION(BlueprintGetter)
APlayerCameraManager* GetSubLevelCamera() const;
/**
* Sets the camera to use to determine which sub-level is closest, so that one
* can be activated and all others deactivated.
*/
UE_DEPRECATED(
"Cesium For Unreal v2.0",
"Add a CesiumOriginShiftComponent to the appropriate Actor instead.")
UFUNCTION(BlueprintSetter)
void SetSubLevelCamera(APlayerCameraManager* NewValue);
/**
* Gets the component that allows switching between different sub-levels
* registered with this georeference.
*/
UFUNCTION(BlueprintGetter)
UCesiumSubLevelSwitcherComponent* GetSubLevelSwitcher() const {
return this->SubLevelSwitcher;
}
/**
* Returns a pointer to the UCesiumEllipsoid currently being used by this
* georeference.
*/
UFUNCTION(BlueprintCallable, BlueprintGetter, Category = "Cesium")
UCesiumEllipsoid* GetEllipsoid() const;
/**
* Sets the UCesiumEllipsoid used by this georeference.
*
* Calling this will cause all tilesets under this georeference to be
* reloaded.
*/
UFUNCTION(BlueprintSetter, Category = "Cesium")
void SetEllipsoid(UCesiumEllipsoid* NewEllipsoid);
#if WITH_EDITOR
/**
* Gets whether to visualize the level loading radii in the editor. Helpful
* for initially positioning the level and choosing a load radius.
*/
UFUNCTION(BlueprintGetter)
bool GetShowLoadRadii() const;
/**
* Sets whether to visualize the level loading radii in the editor. Helpful
* for initially positioning the level and choosing a load radius.
*/
UFUNCTION(BlueprintSetter)
void SetShowLoadRadii(bool NewValue);
#endif // WITH_EDITOR
#pragma endregion
#pragma region Transformation Functions
public:
/**
* Transforms the given longitude in degrees (x), latitude in
* degrees (y), and height above the ellipsoid in meters (z) into Unreal
* coordinates. The resulting position should generally not be interpreted as
* an Unreal _world_ position, but rather a position expressed in some parent
* Actor's reference frame as defined by its transform. This way, the chain of
* Unreal transforms places and orients the "globe" in the Unreal world.
*/
UFUNCTION(
BlueprintPure,
Category = "Cesium",
meta = (ReturnDisplayName = "UnrealPosition"))
FVector TransformLongitudeLatitudeHeightPositionToUnreal(
const FVector& LongitudeLatitudeHeight) const;
/**
* Transforms a position in Unreal coordinates into longitude in degrees (x),
* latitude in degrees (y), and height above the ellipsoid in meters (z). The
* position should generally not be an Unreal _world_ position, but rather a
* position expressed in some parent Actor's reference frame as defined by its
* transform. This way, the chain of Unreal transforms places and orients the
* "globe" in the Unreal world.
*/
UFUNCTION(
BlueprintPure,
Category = "Cesium",
meta = (ReturnDisplayName = "LongitudeLatitudeHeight"))
FVector TransformUnrealPositionToLongitudeLatitudeHeight(
const FVector& UnrealPosition) const;
/**
* Transforms a position in Earth-Centered, Earth-Fixed (ECEF) coordinates
* into Unreal coordinates. The resulting position should generally not be
* interpreted as an Unreal _world_ position, but rather a position expressed
* in some parent Actor's reference frame as defined by its transform. This
* way, the chain of Unreal transforms places and orients the "globe" in the
* Unreal world.
*/
UFUNCTION(
BlueprintPure,
Category = "Cesium",
meta = (ReturnDisplayName = "UnrealPosition"))
FVector TransformEarthCenteredEarthFixedPositionToUnreal(
const FVector& EarthCenteredEarthFixedPosition) const;
/**
* Transforms the given position from Unreal coordinates to Earth-Centered,
* Earth-Fixed (ECEF). The position should generally not be an Unreal _world_
* position, but rather a position expressed in some parent Actor's reference
* frame as defined by its transform. This way, the chain of Unreal transforms
* places and orients the "globe" in the Unreal world.
*/
UFUNCTION(
BlueprintPure,
Category = "Cesium",
meta = (ReturnDisplayName = "EarthCenteredEarthFixedPosition"))
FVector TransformUnrealPositionToEarthCenteredEarthFixed(
const FVector& UnrealPosition) const;
/**
* Transforms a direction vector in Earth-Centered, Earth-Fixed (ECEF)
* coordinates into Unreal coordinates. The resulting direction vector should
* generally not be interpreted as an Unreal _world_ vector, but rather a
* vector expressed in some parent Actor's reference frame as defined by its
* transform. This way, the chain of Unreal transforms places and orients the
* "globe" in the Unreal world.
*/
UFUNCTION(
BlueprintPure,
Category = "Cesium",
meta = (ReturnDisplayName = "UnrealDirection"))
FVector TransformEarthCenteredEarthFixedDirectionToUnreal(
const FVector& EarthCenteredEarthFixedDirection) const;
/**
* Transforms the given direction vector from Unreal coordinates to
* Earth-Centered, Earth-Fixed (ECEF) coordinates. The direction vector should
* generally not be an Unreal _world_ vector, but rather a vector expressed in
* some parent Actor's reference frame as defined by its transform. This way,
* the chain of Unreal transforms places and orients the "globe" in the Unreal
* world.
*/
UFUNCTION(
BlueprintPure,
Category = "Cesium",
meta = (ReturnDisplayName = "EarthCenteredEarthFixedPosition"))
FVector TransformUnrealDirectionToEarthCenteredEarthFixed(
const FVector& UnrealDirection) const;
/**
* Given a Rotator that transforms an object into the Unreal coordinate
* system, returns a new Rotator that transforms that object into an
* East-South-Up frame centered at a given location.
*
* In an East-South-Up frame, +X points East, +Y points South, and +Z points
* Up. However, the directions of "East", "South", and "Up" in Unreal or ECEF
* coordinates vary depending on where on the globe we are talking about.
* That is why this function takes a location, expressed in Unreal
* coordinates, that defines the origin of the East-South-Up frame of
* interest.
*
* The Unreal location and the resulting Rotator should generally not be
* relative to the Unreal _world_, but rather be expressed in some parent
* Actor's reference frame as defined by its Transform. This way, the chain of
* Unreal transforms places and orients the "globe" in the Unreal world.
*/
UFUNCTION(
BlueprintPure,
Category = "Cesium",
meta = (ReturnDisplayName = "EastSouthUpRotator"))
FRotator TransformUnrealRotatorToEastSouthUp(
const FRotator& UnrealRotator,
const FVector& UnrealLocation) const;
/**
* Given a Rotator that transforms an object into the East-South-Up frame
* centered at a given location, returns a new Rotator that transforms that
* object into Unreal coordinates.
*
* In an East-South-Up frame, +X points East, +Y points South, and +Z points
* Up. However, the directions of "East", "South", and "Up" in Unreal or ECEF
* coordinates vary depending on where on the globe we are talking about.
* That is why this function takes a location, expressed in Unreal
* coordinates, that defines the origin of the East-South-Up frame of
* interest.
*
* The Unreal location and the resulting Rotator should generally not be
* relative to the Unreal _world_, but rather be expressed in some parent
* Actor's reference frame as defined by its Transform. This way, the chain of
* Unreal transforms places and orients the "globe" in the Unreal world.
*/
UFUNCTION(
BlueprintPure,
Category = "Cesium",
meta = (ReturnDisplayName = "UnrealRotator"))
FRotator TransformEastSouthUpRotatorToUnreal(
const FRotator& EastSouthUpRotator,
const FVector& UnrealLocation) const;
/**
* Computes the transformation matrix from the Unreal coordinate system to the
* Earth-Centered, Earth-Fixed (ECEF) coordinate system. The Unreal
* coordinates should generally not be interpreted as Unreal _world_
* coordinates, but rather a coordinate system based on some parent Actor's
* reference frame as defined by its transform. This way, the chain of Unreal
* transforms places and orients the "globe" in the Unreal world.
*/
UFUNCTION(
BlueprintPure,
Category = "Cesium",
meta = (ReturnDisplayName = "UnrealToEarthCenteredEarthFixedMatrix"))
FMatrix ComputeUnrealToEarthCenteredEarthFixedTransformation() const;
/**
* Computes the transformation matrix from the Earth-Centered, Earth-Fixed
* (ECEF) coordinate system to the Unreal coordinate system. The Unreal
* coordinates should generally not be interpreted as Unreal _world_
* coordinates, but rather a coordinate system based on some parent Actor's
* reference frame as defined by its transform. This way, the chain of Unreal
* transforms places and orients the "globe" in the Unreal world.
*/
UFUNCTION(
BlueprintPure,
Category = "Cesium",
meta = (ReturnDisplayName = "EarthCenteredEarthFixedToUnrealMatrix"))
FMatrix ComputeEarthCenteredEarthFixedToUnrealTransformation() const;
/**
* Computes the matrix that transforms from an East-South-Up frame centered at
* a given location to the Unreal frame.
*
* In an East-South-Up frame, +X points East, +Y points South, and +Z points
* Up. However, the directions of "East", "South", and "Up" in Unreal or ECEF
* coordinates vary depending on where on the globe we are talking about.
* That is why this function takes a location, expressed in Unreal
* coordinates, that defines the origin of the East-South-Up frame of
* interest.
*
* The Unreal location and the resulting matrix should generally not be
* relative to the Unreal _world_, but rather be expressed in some parent
* Actor's reference frame as defined by its Transform. This way, the chain of
* Unreal transforms places and orients the "globe" in the Unreal world.
*/
UFUNCTION(
BlueprintPure,
Category = "Cesium",
meta = (ReturnDisplayName = "EastSouthUpToUnrealMatrix"))
FMatrix
ComputeEastSouthUpToUnrealTransformation(const FVector& UnrealLocation) const;
/**
* Computes the matrix that transforms from an East-South-Up frame centered at
* a given location to the Unreal frame. The location is expressed as an
* Earth-Centered, Earth-Fixed (ECEF) position. To use an Unreal position
* instead, use ComputeUnrealToEastSouthUpTransformation.
*
* In an East-South-Up frame, +X points East, +Y points South, and +Z points
* Up. However, the directions of "East", "South", and "Up" in Unreal or ECEF
* coordinates vary depending on where on the globe we are talking about.
* That is why this function takes a location, expressed in ECEF
* coordinates, that defines the origin of the East-South-Up frame of
* interest.
*
* The resulting matrix should generally not be relative to the Unreal
* _world_, but rather be expressed in some parent Actor's reference frame as
* defined by its Transform. This way, the chain of Unreal transforms places
* and orients the "globe" in the Unreal world.
*/
UFUNCTION(
BlueprintPure,
Category = "Cesium",
meta = (ReturnDisplayName = "EastSouthUpToUnrealMatrix"))
FMatrix
ComputeEastSouthUpAtEarthCenteredEarthFixedPositionToUnrealTransformation(
const FVector& EarthCenteredEarthFixedPosition) const;
/**
* Computes the matrix that transforms from the Unreal frame to an
* East-South-Up frame centered at a given location. The location is expressed
* in Unreal coordinates. To use an Earth-Centered, Earth-Fixed position
* instead, use
* ComputeEastSouthUpAtEarthCenteredEarthFixedPositionToUnrealTransformation.
*
* In an East-South-Up frame, +X points East, +Y points South, and +Z points
* Up. However, the directions of "East", "South", and "Up" in Unreal or ECEF
* coordinates vary depending on where on the globe we are talking about.
* That is why this function takes a location, expressed in Unreal
* coordinates, that defines the origin of the East-South-Up frame of
* interest.
*
* The Unreal location and the resulting matrix should generally not be
* relative to the Unreal _world_, but rather be expressed in some parent
* Actor's reference frame as defined by its Transform. This way, the chain of
* Unreal transforms places and orients the "globe" in the Unreal world.
*/
UFUNCTION(
BlueprintPure,
Category = "Cesium",
meta = (ReturnDisplayName = "UnrealToEastSouthUpMatrix"))
FMatrix
ComputeUnrealToEastSouthUpTransformation(const FVector& UnrealLocation) const;
#pragma endregion
#pragma region Editor Support
#if WITH_EDITOR
public:
/**
* Places the georeference origin at the camera's current location. Rotates
* the globe so the current longitude/latitude/height of the camera is at the
* Unreal origin. The camera is also teleported to the new Unreal origin and
* rotated so that the view direction is maintained.
*
* Warning: Before clicking, ensure that all non-Cesium objects in the
* persistent level are georeferenced with the "CesiumGlobeAnchorComponent"
* or attached to an actor with that component. Ensure that static actors only
* exist in georeferenced sub-levels.
*/
UFUNCTION(Category = "Cesium")
void PlaceGeoreferenceOriginHere();
/**
* Creates a new Level Instance Actor at the current viewport location, and
* attaches the Cesium Sub Level Component to it. You will be prompted for
* where to store the new level.
*
* Warning: Before clicking, ensure that all non-Cesium objects in the
* persistent level are georeferenced with the "CesiumGlobeAnchorComponent"
* or attached to an actor with that component. Ensure that static actors only
* exist in georeferenced sub-levels.
*/
UFUNCTION(Category = "Cesium")
void CreateSubLevelHere();
#endif
private:
// This property mirrors RootComponent, and exists only so that the root
// component's transform is editable in the Editor.
UPROPERTY(VisibleAnywhere, Category = "Cesium")
USceneComponent* Root;
#if WITH_EDITOR
/**
* @brief Show the load radius of each sub-level as a sphere.
*
* If this is not called "in-game", and `ShowLoadRadii` is `true`,
* then it will show a sphere indicating the load radius of each
* sub-level.
*/
void _showSubLevelLoadRadii() const;
#endif
#pragma endregion
#pragma region Unreal Lifecycle
protected:
virtual bool ShouldTickIfViewportsOnly() const override;
virtual void Tick(float DeltaTime) override;
virtual void Serialize(FArchive& Ar) override;
virtual void BeginPlay() override;
virtual void OnConstruction(const FTransform& Transform) override;
virtual void PostLoad() override;
#if WITH_EDITOR
virtual void
PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
#endif
#pragma endregion
#pragma region Obsolete
public:
UE_DEPRECATED(
"Cesium For Unreal v2.0",
"Use transformation functions on ACesiumGeoreference and UCesiumEllipsoid instead.")
GeoTransforms GetGeoTransforms() const noexcept;
private:
PRAGMA_DISABLE_DEPRECATION_WARNINGS
UPROPERTY(
Meta =
(DeprecatedProperty,
DeprecationMessage =
"Create sub-levels by adding a UCesiumSubLevelComponent to an ALevelInstance Actor."))
TArray<FCesiumSubLevel> CesiumSubLevels_DEPRECATED;
PRAGMA_ENABLE_DEPRECATION_WARNINGS
#if WITH_EDITOR
void _createSubLevelsFromWorldComposition();
#endif
/**
* Transforms the given longitude in degrees (x), latitude in
* degrees (y), and height above the ellipsoid in meters (z) into
* Earth-Centered, Earth-Fixed (ECEF) coordinates.
*/
UFUNCTION(
BlueprintPure,
Category = "Cesium",
meta =
(DeprecatedFunction,
DeprecationMessage =
"Use LongitudeLatitudeHeightToEllipsoidCenteredEllipsoidFixed on UCesiumEllipsoid instead."))
FVector TransformLongitudeLatitudeHeightToEcef(
const FVector& LongitudeLatitudeHeight) const;
/**
* Transforms the given Earth-Centered, Earth-Fixed (ECEF) coordinates into
* Ellipsoid longitude in degrees (x), latitude in degrees (y), and height
* above the ellipsoid in meters (z).
*/
UFUNCTION(
BlueprintPure,
Category = "Cesium",
meta =
(DeprecatedFunction,
DeprecationMessage =
"Use EllipsoidCenteredEllipsoidFixedToLongitudeLatitudeHeight on UCesiumEllipsoid instead."))
FVector TransformEcefToLongitudeLatitudeHeight(const FVector& Ecef) const;
/**
* Computes the rotation matrix from the local East-North-Up to
* Earth-Centered, Earth-Fixed (ECEF) at the specified ECEF location.
*/
UFUNCTION(
BlueprintPure,
Category = "Cesium",
meta =
(DeprecatedFunction,
DeprecationMessage =
"Use EastNorthUpToEllipsoidCenteredEllipsoidFixed on UCesiumEllipsoid instead."))
FMatrix ComputeEastNorthUpToEcef(const FVector& Ecef) const;
#pragma endregion
private:
#pragma region Implementation Details
public:
ACesiumGeoreference();
const CesiumGeospatial::LocalHorizontalCoordinateSystem&
GetCoordinateSystem() const noexcept {
return this->_coordinateSystem;
}
private:
/**
* Recomputes all world georeference transforms.
*/
void UpdateGeoreference();
/**
* A tag that is assigned to Georeferences when they are created
* as the "default" Georeference for a certain world.
*/
static FName DEFAULT_GEOREFERENCE_TAG;
CesiumGeospatial::LocalHorizontalCoordinateSystem _coordinateSystem{
glm::dmat4(1.0)};
/**
* Updates _geoTransforms based on the current ellipsoid and center, and
* returns the old transforms.
*/
void _updateCoordinateSystem();
friend class FCesiumGeoreferenceCustomization;
#pragma endregion
};

View File

@ -0,0 +1,601 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumGeospatial/GlobeAnchor.h"
#include "Components/ActorComponent.h"
#include "Delegates/IDelegateInstance.h"
#include "CesiumGlobeAnchorComponent.generated.h"
class ACesiumGeoreference;
/**
* This component can be added to a movable actor to anchor it to the globe
* and maintain precise placement. When the owning actor is transformed through
* normal Unreal Engine mechanisms, the internal geospatial coordinates will be
* automatically updated. The actor position can also be set in terms of
* Earth-Centered, Earth-Fixed coordinates (ECEF) or Longitude, Latitude, and
* Height relative to the ellipsoid.
*/
UCLASS(ClassGroup = Cesium, Meta = (BlueprintSpawnableComponent))
class CESIUMRUNTIME_API UCesiumGlobeAnchorComponent : public UActorComponent {
GENERATED_BODY()
#pragma region Properties
private:
/**
* The designated georeference actor controlling how the owning actor's
* coordinate system relates to the coordinate system in this Unreal Engine
* level.
*
* If this is null, the Component 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.
*
* If setting this property changes the CesiumGeoreference, the globe position
* will be maintained and the Actor's transform will be updated according to
* the new CesiumGeoreference.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
BlueprintGetter = GetGeoreference,
BlueprintSetter = SetGeoreference,
Category = "Cesium",
Meta = (AllowPrivateAccess))
TSoftObjectPtr<ACesiumGeoreference> Georeference = nullptr;
/**
* The resolved georeference used by this component. This is not serialized
* because it may point to a Georeference in the PersistentLevel while this
* component is in a sub-level. If the Georeference property is specified,
* however then this property will have the same value.
*
* This property will be null before ResolveGeoreference is called, which
* happens automatically when the component is registered.
*/
UPROPERTY(
Transient,
VisibleAnywhere,
BlueprintReadOnly,
BlueprintGetter = GetResolvedGeoreference,
Category = "Cesium",
Meta = (AllowPrivateAccess))
ACesiumGeoreference* ResolvedGeoreference = nullptr;
/**
* Whether to adjust the Actor's orientation based on globe curvature as the
* Actor moves.
*
* The Earth is not flat, so as we move across its surface, the direction of
* "up" changes. If we ignore this fact and leave an object's orientation
* unchanged as it moves over the globe surface, the object will become
* increasingly tilted and eventually be completely upside-down when we arrive
* at the opposite side of the globe.
*
* When this setting is enabled, this Component will automatically apply a
* rotation to the Actor to account for globe curvature any time the Actor's
* position on the globe changes.
*
* This property should usually be enabled, but it may be useful to disable it
* when your application already accounts for globe curvature itself when it
* updates an Actor's position and orientation, because in that case the Actor
* would be over-rotated.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
BlueprintGetter = GetAdjustOrientationForGlobeWhenMoving,
BlueprintSetter = SetAdjustOrientationForGlobeWhenMoving,
Category = "Cesium",
Meta = (AllowPrivateAccess))
bool AdjustOrientationForGlobeWhenMoving = true;
/**
* Using the teleport flag will move objects to the updated transform
* immediately and without affecting their velocity. This is useful when
* working with physics actors that maintain an internal velocity which we do
* not want to change when updating location.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
BlueprintGetter = GetTeleportWhenUpdatingTransform,
BlueprintSetter = SetTeleportWhenUpdatingTransform,
Category = "Cesium",
Meta = (AllowPrivateAccess))
bool TeleportWhenUpdatingTransform = true;
/**
* The 4x4 transformation matrix from the Actors's local coordinate system to
* the Earth-Centered, Earth-Fixed (ECEF) coordinate system.
*
* The ECEF coordinate system is a right-handed system located at the center
* of the Earth. The +X axis points to the intersection of the Equator and
* Prime Meridian (zero degrees longitude). The +Y axis points to the
* intersection of the Equator and +90 degrees longitude. The +Z axis points
* up through the North Pole.
*
* If `AdjustOrientationForGlobeWhenMoving` is enabled and this property is
* set, the Actor's orientation will also be adjusted to account for globe
* curvature.
*/
UPROPERTY(
BlueprintReadWrite,
BlueprintGetter = GetActorToEarthCenteredEarthFixedMatrix,
BlueprintSetter = SetActorToEarthCenteredEarthFixedMatrix,
Category = "Cesium",
Meta = (AllowPrivateAccess))
FMatrix ActorToEarthCenteredEarthFixedMatrix;
#pragma endregion
#pragma region Property Accessors
public:
/**
* Gets the designated georeference actor controlling how the owning actor's
* coordinate system relates to the coordinate system in this Unreal Engine
* level.
*
* If this is null, the Component 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.
*/
UFUNCTION(BlueprintGetter)
TSoftObjectPtr<ACesiumGeoreference> GetGeoreference() const;
/**
* Sets the designated georeference actor controlling how the owning actor's
* coordinate system relates to the coordinate system in this Unreal Engine
* level.
*
* If this is null, the Component 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.
*/
UFUNCTION(BlueprintSetter)
void SetGeoreference(TSoftObjectPtr<ACesiumGeoreference> NewGeoreference);
/**
* Gets the resolved georeference used by this component. This is not
* serialized because it may point to a Georeference in the PersistentLevel
* while this component is in a sub-level. If the Georeference property is
* manually specified, however, then this property will have the same value.
*
* This property will be null before ResolveGeoreference is called, which
* happens automatically when the component is registered.
*/
UFUNCTION(BlueprintGetter)
ACesiumGeoreference* GetResolvedGeoreference() const;
/**
* Resolves the Cesium Georeference to use with this Component. 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, unless ForceReresolve is true.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
ACesiumGeoreference* ResolveGeoreference(bool bForceReresolve = false);
/**
* Obtains the {@link UCesiumEllipsoid} set on the georeference used by this
* component.
*/
UFUNCTION(BlueprintGetter, Category = "Cesium")
UCesiumEllipsoid* GetEllipsoid() const;
/**
* Gets the 4x4 transformation matrix from the Actors's local coordinate
* system to the Earth-Centered, Earth-Fixed (ECEF) coordinate system.
*
* The ECEF coordinate system is a right-handed system located at the center
* of the Earth. The +X axis points to the intersection of the Equator and
* Prime Meridian (zero degrees longitude). The +Y axis points to the
* intersection of the Equator and +90 degrees longitude. The +Z axis points
* up through the North Pole.
*/
UFUNCTION(BlueprintGetter, Category = "Cesium")
FMatrix GetActorToEarthCenteredEarthFixedMatrix() const;
/**
* Sets the 4x4 transformation matrix from the Actors's local coordinate
* system to the Earth-Centered, Earth-Fixed (ECEF) coordinate system.
*
* The ECEF coordinate system is a right-handed system located at the center
* of the Earth. The +X axis points to the intersection of the Equator and
* Prime Meridian (zero degrees longitude). The +Y axis points to the
* intersection of the Equator and +90 degrees longitude. The +Z axis points
* up through the North Pole.
*
* If `AdjustOrientationForGlobeWhenMoving` is enabled, the Actor's
* orientation will also be adjusted to account for globe curvature.
*/
UFUNCTION(BlueprintSetter, Category = "Cesium")
void SetActorToEarthCenteredEarthFixedMatrix(const FMatrix& Value);
/**
* Gets a flag indicating whether to move objects to the updated transform
* immediately and without affecting their velocity. This is useful when
* working with physics actors that maintain an internal velocity which we do
* not want to change when updating location.
*/
UFUNCTION(BlueprintGetter, Category = "Cesium")
bool GetTeleportWhenUpdatingTransform() const;
/**
* Sets a flag indicating whether to move objects to the updated transform
* immediately and without affecting their velocity. This is useful when
* working with physics actors that maintain an internal velocity which we do
* not want to change when updating location.
*/
UFUNCTION(BlueprintSetter, Category = "Cesium")
void SetTeleportWhenUpdatingTransform(bool Value);
/**
* Gets a flag indicating whether to adjust the Actor's orientation based on
* globe curvature as the Actor moves.
*
* The Earth is not flat, so as we move across its surface, the direction of
* "up" changes. If we ignore this fact and leave an object's orientation
* unchanged as it moves over the globe surface, the object will become
* increasingly tilted and eventually be completely upside-down when we arrive
* at the opposite side of the globe.
*
* When this setting is enabled, this Component will automatically apply a
* rotation to the Actor to account for globe curvature any time the Actor's
* position on the globe changes.
*
* This property should usually be enabled, but it may be useful to disable it
* when your application already accounts for globe curvature itself when it
* updates an Actor's position and orientation, because in that case the Actor
* would be over-rotated.
*/
UFUNCTION(BlueprintGetter, Category = "Cesium")
bool GetAdjustOrientationForGlobeWhenMoving() const;
/**
* Sets a flag indicating whether to adjust the Actor's orientation based on
* globe curvature as the Actor moves.
*
* The Earth is not flat, so as we move across its surface, the direction of
* "up" changes. If we ignore this fact and leave an object's orientation
* unchanged as it moves over the globe surface, the object will become
* increasingly tilted and eventually be completely upside-down when we arrive
* at the opposite side of the globe.
*
* When this setting is enabled, this Component will automatically apply a
* rotation to the Actor to account for globe curvature any time the Actor's
* position on the globe changes.
*
* This property should usually be enabled, but it may be useful to disable it
* when your application already accounts for globe curvature itself when it
* updates an Actor's position and orientation, because in that case the Actor
* would be over-rotated.
*/
UFUNCTION(BlueprintSetter, Category = "Cesium")
void SetAdjustOrientationForGlobeWhenMoving(bool Value);
#pragma endregion
#pragma region Public Methods
public:
/**
* Gets the longitude in degrees (X), latitude in degrees (Y),
* and height in meters above the ellipsoid (Z) of the actor.
*
* Do not confuse the ellipsoid height with a geoid height or height above
* mean sea level, which can be tens of meters higher or lower depending on
* where in the world the object is located.
*/
UFUNCTION(
BlueprintPure,
Category = "Cesium",
Meta = (ReturnDisplayName = "LongitudeLatitudeHeight"))
FVector GetLongitudeLatitudeHeight() const;
/**
* Gets the longitude in degrees.
*/
UFUNCTION(
BlueprintPure,
Category = "Cesium",
Meta = (ReturnDisplayName = "Longitude"))
double GetLongitude() const { return this->GetLongitudeLatitudeHeight().X; }
/**
* Gets the latitude in degrees.
*/
UFUNCTION(
BlueprintPure,
Category = "Cesium",
Meta = (ReturnDisplayName = "Latitude"))
double GetLatitude() const { return this->GetLongitudeLatitudeHeight().Y; }
/**
* Gets the height in meters above the ellipsoid.
*
* Do not confuse the ellipsoid height with a geoid height or height above
* mean sea level, which can be tens of meters higher or lower depending on
* where in the world the object is located.
*/
UFUNCTION(
BlueprintPure,
Category = "Cesium",
Meta = (ReturnDisplayName = "Height"))
double GetHeight() const { return this->GetLongitudeLatitudeHeight().Z; }
/**
* Moves the Actor to which this component is attached to a given longitude in
* degrees (X), latitude in degrees (Y), and height in meters (Z).
*
* The Height (Z) is measured in meters above the ellipsoid. Do not
* confused an ellipsoidal height with a geoid height or height above mean sea
* level, which can be tens of meters higher or lower depending on where in
* the world the object is located.
*
* If `AdjustOrientationForGlobeWhenMoving` is enabled, the Actor's
* orientation will also be adjusted to account for globe curvature.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
void MoveToLongitudeLatitudeHeight(const FVector& LongitudeLatitudeHeight);
/**
* Gets the Earth-Centered, Earth-Fixed (ECEF) coordinates of the Actor in
* meters.
*/
UFUNCTION(
BlueprintPure,
Category = "Cesium",
meta = (ReturnDisplayName = "EarthCenteredEarthFixedPosition"))
FVector GetEarthCenteredEarthFixedPosition() const;
/**
* Moves the Actor to which this component is attached to a given globe
* position in Earth-Centered, Earth-Fixed coordinates in meters.
*
* If AdjustOrientationForGlobeWhenMoving is enabled, this method will
* also update the orientation based on the globe curvature.
*
* @param EarthCenteredEarthFixedPosition The new position.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
void MoveToEarthCenteredEarthFixedPosition(
const FVector& EarthCenteredEarthFixedPosition);
/**
* Gets the rotation of the Actor relative to a local coordinate system
* centered on this object where the +X points in the local East direction,
* the +Y axis points in the local South direction, and the +Z axis points in
* the local Up direction.
*/
UFUNCTION(
BlueprintPure,
Category = "Cesium",
meta = (ReturnDisplayName = "EastSouthUpRotation"))
FQuat GetEastSouthUpRotation() const;
/**
* Sets the rotation of the Actor relative to a local coordinate system
* centered on this object where the +X points in the local East direction,
* the +Y axis points in the local South direction, and the +Z axis points in
* the local Up direction.
*
* When the rotation is set via this method, it is internally converted to
* and stored in the ActorToEarthCenteredEarthFixedMatrix property. As a
* result, getting this property will not necessarily return the exact value
* that was set.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
void SetEastSouthUpRotation(const FQuat& EastSouthUpRotation);
/**
* Gets the rotation of the Actor relative to the Earth-Centered, Earth-Fixed
* (ECEF) coordinate system.
*
* The ECEF coordinate system is a right-handed system located at the center
* of the Earth. The +X axis points from there to the intersection of the
* Equator and Prime Meridian (zero degrees longitude). The +Y axis points to
* the intersection of the Equator and +90 degrees longitude. The +Z axis
* points up through the North Pole.
*/
UFUNCTION(
BlueprintPure,
Category = "Cesium",
meta = (ReturnDisplayName = "EarthCenteredEarthFixedRotation"))
FQuat GetEarthCenteredEarthFixedRotation() const;
/**
* Sets the rotation of the Actor relative to the Earth-Centered, Earth-Fixed
* (ECEF) coordinate system.
*
* The ECEF coordinate system is a right-handed system located at the center
* of the Earth. The +X axis points from there to the intersection of the
* Equator and Prime Meridian (zero degrees longitude). The +Y axis points to
* the intersection of the Equator and +90 degrees longitude. The +Z axis
* points up through the North Pole.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
void SetEarthCenteredEarthFixedRotation(
const FQuat& EarthCenteredEarthFixedRotation);
/**
* Rotates the Actor so that its local +Z axis is aligned with the ellipsoid
* surface normal at its current location.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
void SnapLocalUpToEllipsoidNormal();
/**
* Rotates the Actor so that its +X axis points in the local East direction,
* its +Y axis points in the local South direction, and its +Z axis points in
* the local Up direction.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
void SnapToEastSouthUp();
/**
* Synchronizes the properties of this globe anchor.
*
* It is usually not necessary to call this method because it is called
* automatically when needed.
*
* This method performs the following actions:
*
* - If the ActorToEarthCenteredEarthFixedMatrix has not yet been
* determined, it is computed from the Actor's current root transform.
* - If the Actor's root transform has changed since the last time this
* component was registered, this method updates the
* ActorToEarthCenteredEarthFixedMatrix from the current transform.
* - If the origin of the CesiumGeoreference has changed, the Actor's root
* transform is updated based on the ActorToEarthCenteredEarthFixedMatrix and
* the new georeference origin.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
void Sync();
#pragma endregion
#pragma region Obsolete
public:
/**
* @brief DEPRECATED
* @deprecated The resolved georeference can no longer be explicitly
* invalidated. To change the georeference, call SetGeoreference or
* ReregisterComponent.
*/
UE_DEPRECATED(
"Cesium For Unreal v2.0",
"The resolved georeference can no longer be explicitly invalidated. To change the georeference, call SetGeoreference or ReregisterComponent.")
UFUNCTION(
BlueprintCallable,
Category = "Cesium",
Meta =
(DeprecatedFunction,
DeprecationMessage =
"The resolved georeference can no longer be explicitly invalidated. To change the georeference, call SetGeoreference or ReregisterComponent."))
void InvalidateResolvedGeoreference();
#pragma endregion
#pragma region Unreal Lifecycle
protected:
/**
* Handles reading, writing, and reference collecting using FArchive.
* This implementation handles all FProperty serialization, but can be
* overridden for native variables.
*
* This class overrides this method to ensure internal variables are
* immediately synchronized with newly-loaded values.
*/
virtual void Serialize(FArchive& Ar) override;
/**
* Called when a component is created (not loaded). This can happen in the
* editor or during gameplay.
*
* This method is invoked after this component is pasted and just prior to
* registration. We mark the globe transform invalid here because we can't
* assume the globe transform is still valid when the component is pasted into
* another Actor, or even if the Actor was changed since the Component was
* copied.
*/
virtual void OnComponentCreated() override;
#if WITH_EDITOR
virtual void
PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
#endif
/**
* Called when a component is registered. This can be viewed as "enabling"
* this Component on the Actor to which it is attached.
*
* In the Editor, this is called in a many different situations, such as on
* changes to properties.
*/
virtual void OnRegister() override;
/**
* Called when a component is unregistered. This can be viewed as
* "disabling" this Component on the Actor to which it is attached.
*
* In the Editor, this is called in a many different situations, such as on
* changes to properties.
*/
virtual void OnUnregister() override;
#pragma endregion
#pragma region Implementation Details
private:
CesiumGeospatial::GlobeAnchor _createNativeGlobeAnchor() const;
USceneComponent* _getRootComponent(bool warnIfNull) const;
FTransform _getCurrentRelativeTransform() const;
void _setCurrentRelativeTransform(const FTransform& relativeTransform);
CesiumGeospatial::GlobeAnchor
_createOrUpdateNativeGlobeAnchorFromRelativeTransform(
const FTransform& newRelativeTransform);
CesiumGeospatial::GlobeAnchor
_createOrUpdateNativeGlobeAnchorFromECEF(const FMatrix& newActorToECEFMatrix);
void _updateFromNativeGlobeAnchor(
const CesiumGeospatial::GlobeAnchor& nativeAnchor);
void _setNewActorToECEFFromRelativeTransform();
#if WITH_EDITORONLY_DATA
// This is used only to preserve the transformation saved by old versions of
// Cesium for Unreal. See the Serialize method.
UPROPERTY(Meta = (DeprecatedProperty))
double _actorToECEF_Array_DEPRECATED[16];
#endif
/**
* True if the globe transform is a valid and correct representation of the
* position and orientation of this Actor. False if the globe transform has
* not yet been computed and so the Actor transform is the only valid
* representation of the Actor's position and orientation.
*/
UPROPERTY()
bool _actorToECEFIsValid = false;
/**
* Whether an update of the actor transform is currently in progress,
* and further calls that are received by _onActorTransformChanged
* should be ignored
*/
bool _updatingActorTransform = false;
bool _lastRelativeTransformIsValid = false;
FTransform _lastRelativeTransform{};
/**
* Called when the root transform of the Actor to which this Component is
* attached has changed. So:
* * The globe (ECEF) position and orientation are computed from the new
* transform.
* * When `AdjustOrientationForGlobeWhenMoving` is enabled, the orientation
* will also be adjusted for globe curvature.
*/
void _onActorTransformChanged(
USceneComponent* InRootComponent,
EUpdateTransformFlags UpdateTransformFlags,
ETeleportType Teleport);
/**
* Called when the Component switches to a new Georeference Actor or the
* existing Georeference is given a new origin Longitude, Latitude, or
* Height. The Actor's position and orientation are recomputed from the
* Component's globe (ECEF) position and orientation.
*/
UFUNCTION(CallInEditor)
void _onGeoreferenceChanged();
friend class FCesiumGlobeAnchorCustomization;
#pragma endregion
};

View File

@ -0,0 +1,37 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "Components/ActorComponent.h"
#include "CesiumGlobeAnchoredActorComponent.generated.h"
class UCesiumGlobeAnchorComponent;
UCLASS(ClassGroup = "Cesium", Abstract)
class CESIUMRUNTIME_API UCesiumGlobeAnchoredActorComponent
: public UActorComponent {
GENERATED_BODY()
public:
UFUNCTION(BlueprintGetter)
UCesiumGlobeAnchorComponent* GetGlobeAnchor();
protected:
virtual void OnRegister() override;
virtual void BeginPlay() override;
private:
void ResolveGlobeAnchor();
// The globe anchor attached to the same Actor as this component. Don't
// save/load or copy this. It is set in BeginPlay and OnRegister.
UPROPERTY(
Category = "Cesium",
BlueprintReadOnly,
BlueprintGetter = GetGlobeAnchor,
Transient,
DuplicateTransient,
TextExportTransient,
Meta = (AllowPrivateAccess))
UCesiumGlobeAnchorComponent* GlobeAnchor;
};

View File

@ -0,0 +1,70 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumRasterOverlay.h"
#include "CoreMinimal.h"
#include "CesiumIonRasterOverlay.generated.h"
class UCesiumIonServer;
/**
* A raster overlay that uses an IMAGERY asset from Cesium ion.
*/
UCLASS(
DisplayName = "Cesium ion Raster Overlay",
ClassGroup = (Cesium),
meta = (BlueprintSpawnableComponent))
class CESIUMRUNTIME_API UCesiumIonRasterOverlay : public UCesiumRasterOverlay {
GENERATED_BODY()
public:
/**
* The ID of the Cesium ion asset to use.
*
* If this property is non-zero, the Bing Maps Key and Map Style properties
* are ignored.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
int64 IonAssetID;
/**
* The access token to use to access the Cesium ion resource.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
FString IonAccessToken;
/**
* The URL of the ion asset endpoint. Defaults to Cesium ion but a custom
* endpoint can be specified.
*/
UPROPERTY(
meta =
(DeprecatedProperty,
DeprecationMessage = "Use CesiumIonServer instead."))
FString IonAssetEndpointUrl_DEPRECATED;
/**
* The Cesium ion Server from which this raster overlay is loaded.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium",
AdvancedDisplay)
UCesiumIonServer* CesiumIonServer;
/**
* Check if the Cesium ion token used to access this raster overlay is working
* correctly, and fix it if necessary.
*/
UFUNCTION(CallInEditor, Category = "Cesium")
void TroubleshootToken();
// UActorComponent overrides
virtual void PostLoad() override;
protected:
virtual std::unique_ptr<CesiumRasterOverlays::RasterOverlay> CreateOverlay(
const CesiumRasterOverlays::RasterOverlayOptions& options = {}) override;
};

View File

@ -0,0 +1,135 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "Engine/DataAsset.h"
#include "UObject/Object.h"
#include "CesiumIonServer.generated.h"
namespace CesiumAsync {
template <typename T> class Future;
}
/**
* Defines a Cesium ion Server. This may be the public (SaaS) Cesium ion server
* at ion.cesium.com, or it may be a self-hosted instance.
*/
UCLASS()
class CESIUMRUNTIME_API UCesiumIonServer : public UDataAsset {
GENERATED_BODY()
public:
/**
* Gets the default Cesium ion Server (ion.cesium.com).
*
* It is expected to be found at
* `/Game/CesiumSettings/CesiumIonServers/CesiumIonSaaS`. In the Editor, it
* will be created if it does not already exist, so this method always returns
* a valid instance. At runtime, this method returns nullptr if the object
* does not exist.
*/
static UCesiumIonServer* GetDefaultServer();
/**
* Gets the current server to be assigned to new objects. In the Editor, this
* is the server that is currently selected on the Cesium panel. At runtime,
* this returns `GetDefault`, unless `SetCurrentForNewObjects` has been called
* to set it to something different.
*/
static UCesiumIonServer* GetServerForNewObjects();
/**
* Sets the current server to be assigned to new objects. If set to nullptr,
* the value of `GetDefault` will be returned from `GetCurrentForNewObjects`.
*/
static void SetServerForNewObjects(UCesiumIonServer* Server);
#if WITH_EDITOR
/**
* Gets or creates a server from a given API URL. This is used for backward
* compatibility with the old `IonAssetEndpointUrl` property. The new server,
* if needed, is created in `/Game/CesiumSettings/CesiumIonServers`.
*/
static UCesiumIonServer* GetBackwardCompatibleServer(const FString& apiUrl);
#endif
/**
* The name to display for this server.
*/
UPROPERTY(
EditAnywhere,
AssetRegistrySearchable,
Category = "Cesium",
meta = (DisplayName = "Display Name"))
FString DisplayName = "ion.cesium.com";
/**
* The main URL of the Cesium ion server. For example, the server URL for the
* public Cesium ion is https://ion.cesium.com.
*/
UPROPERTY(
EditAnywhere,
AssetRegistrySearchable,
Category = "Cesium",
meta = (DisplayName = "Server URL"))
FString ServerUrl = "https://ion.cesium.com";
/**
* The URL of the main API endpoint of the Cesium ion server. For example, for
* the default, public Cesium ion server, this is `https://api.cesium.com`. If
* left blank, the API URL is automatically inferred from the Server URL.
*/
UPROPERTY(
EditAnywhere,
AssetRegistrySearchable,
Category = "Cesium",
meta = (DisplayName = "API URL"))
FString ApiUrl = "https://api.cesium.com";
/**
* The application ID to use to log in to this server using OAuth2. This
* OAuth2 application must be configured on the server with the exact URL
* `http://127.0.0.1/cesium-for-unreal/oauth2/callback`.
*/
UPROPERTY(
EditAnywhere,
AssetRegistrySearchable,
Category = "Cesium",
meta = (DisplayName = "OAuth Application ID"))
int64 OAuth2ApplicationID = 190;
/**
* The ID of the default access token to use to access Cesium ion assets at
* runtime. This property may be an empty string, in which case the ID is
* found by searching the logged-in Cesium ion account for the
* DefaultIonAccessToken.
*/
UPROPERTY(
EditAnywhere,
Category = "Cesium",
meta = (DisplayName = "Default Cesium ion Access Token ID"))
FString DefaultIonAccessTokenId;
/**
* The default token used to access Cesium ion assets at runtime. This token
* is embedded in packaged games for use at runtime.
*/
UPROPERTY(
EditAnywhere,
AssetRegistrySearchable,
Category = "Cesium",
meta = (DisplayName = "Default Cesium ion Access Token"))
FString DefaultIonAccessToken;
#if WITH_EDITOR
/**
* If the `ApiUrl` property is blank, this method asynchronously resolves it
* by consulting with the `ServerUrl`. If the `ApiUrl` is not blank, this
* method returns an already-resolved future.
*/
CesiumAsync::Future<void> ResolveApiUrl();
#endif
private:
static UCesiumIonServer* _pDefaultForNewObjects;
};

View File

@ -0,0 +1,114 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumMetadataValueType.h"
#include <cstdlib>
#include <type_traits>
#include "CesiumMetadataEncodingDetails.generated.h"
/**
* @brief The component type that a metadata property's values will be encoded
* as. These correspond to the pixel component types that are supported in
* Unreal textures.
*/
UENUM()
enum class ECesiumEncodedMetadataComponentType : uint8 { None, Uint8, Float };
/**
* @brief The type that a metadata property's values will be encoded as.
*/
UENUM()
enum class ECesiumEncodedMetadataType : uint8 {
None,
Scalar,
Vec2,
Vec3,
Vec4
};
/**
* @brief Indicates how a property value from EXT_structural_metadata should be
* converted to a GPU-accessible type, if possible.
*/
UENUM()
enum class ECesiumEncodedMetadataConversion : uint8 {
/**
* Do nothing. This is typically used for property types that are
* completely unable to be coerced.
*/
None,
/**
* Coerce the components of a property value to the specified component type.
* If the property contains string values, this attempts to parse numbers from
* the strings as uint8s.
*/
Coerce,
/**
* Attempt to parse a color from a string property value. This supports
* the following formats:
* - `rgb(R, G, B)`, where R, G, and B are values in the range [0, 255]
* - hexcode colors, e.g. `#ff0000`
*/
ParseColorFromString
};
/**
* Describes how a property from EXT_structural_metadata will be encoded for
* access in Unreal materials.
*/
USTRUCT()
struct FCesiumMetadataEncodingDetails {
GENERATED_USTRUCT_BODY()
FCesiumMetadataEncodingDetails()
: Type(ECesiumEncodedMetadataType::None),
ComponentType(ECesiumEncodedMetadataComponentType::None),
Conversion(ECesiumEncodedMetadataConversion::None) {}
FCesiumMetadataEncodingDetails(
ECesiumEncodedMetadataType InType,
ECesiumEncodedMetadataComponentType InComponentType,
ECesiumEncodedMetadataConversion InConversion)
: Type(InType),
ComponentType(InComponentType),
Conversion(InConversion) {}
/**
* The GPU-compatible type that this property's values will be encoded as.
*/
UPROPERTY(EditAnywhere, Category = "Cesium")
ECesiumEncodedMetadataType Type;
/**
* The GPU-compatible component type that this property's values will be
* encoded as. These correspond to the pixel component types that are
* supported in Unreal textures.
*/
UPROPERTY(EditAnywhere, Category = "Cesium")
ECesiumEncodedMetadataComponentType ComponentType;
/**
* The method of conversion used for this property. This describes how the
* values will be converted for access in Unreal materials. Note that not all
* property types are compatible with the methods of conversion.
*/
UPROPERTY(EditAnywhere, Category = "Cesium")
ECesiumEncodedMetadataConversion Conversion;
inline bool operator==(const FCesiumMetadataEncodingDetails& Info) const {
return Type == Info.Type && ComponentType == Info.ComponentType &&
Conversion == Info.Conversion;
}
inline bool operator!=(const FCesiumMetadataEncodingDetails& Info) const {
return Type != Info.Type || ComponentType != Info.ComponentType ||
Conversion != Info.Conversion;
}
bool HasValidType() const {
return Type != ECesiumEncodedMetadataType::None &&
ComponentType != ECesiumEncodedMetadataComponentType::None;
}
};

View File

@ -0,0 +1,181 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumMetadataValue.h"
#include "Containers/UnrealString.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "UObject/ObjectMacros.h"
#include "CesiumMetadataPickingBlueprintLibrary.generated.h"
struct FHitResult;
UCLASS()
class CESIUMRUNTIME_API UCesiumMetadataPickingBlueprintLibrary
: public UBlueprintFunctionLibrary {
GENERATED_BODY()
public:
/**
* Compute the UV coordinates from the given line trace hit, assuming it has
* hit a glTF primitive component that contains the specified texture
* coordinate set. The texture coordinate set is specified relative to the
* glTF itself, where the set index N resolves to the "TEXCOORD_N" attribute
* in the glTF primitive.
*
* This function can be used to sample feature ID textures or property
* textures in the primitive. This works similarly to the FindCollisionUV
* Blueprint, except it does not require the texture coordinate sets to be
* present in the model's physics mesh.
*
* Returns false if the given texture coordinate set index does not exist for
* the primitive, or if its accessor is invalid.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|Picking")
static bool FindUVFromHit(
const FHitResult& Hit,
int64 GltfTexCoordSetIndex,
FVector2D& UV);
/**
* Gets the property table values from a given line trace hit, assuming
* that it has hit a feature of a glTF primitive component.
*
* A primitive may have multiple feature ID sets, so this allows a feature ID
* set to be specified by index. This value should index into the array of
* CesiumFeatureIdSets in the component's CesiumPrimitiveFeatures. If the
* feature ID set is associated with a property table, it will return that
* property table's data.
*
* For feature ID textures and implicit feature IDs, the feature ID can vary
* across the face of a primitive. If the specified CesiumFeatureIdSet is one
* of those types, the feature ID of the first vertex on the face will be
* used.
*
* The returned result may be empty for several reasons:
* - if the component is not a Cesium glTF primitive component
* - if the hit's face index is somehow out-of-bounds
* - if the specified feature ID set does not exist on the primitive
* - if the specified feature ID set is not associated with a valid property
* table
*
* Additionally, if any of the property table's properties are invalid, they
* will not be included in the result.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|Picking")
static TMap<FString, FCesiumMetadataValue> GetPropertyTableValuesFromHit(
const FHitResult& Hit,
int64 FeatureIDSetIndex = 0);
/**
* Gets the property texture values from a given line trace hit, assuming it
* has hit a glTF primitive component.
*
* A primitive may use multiple property textures, as indicated by its indices
* in CesiumPrimitiveMetadata. This function allows for selection of which
* property texture to use from those available in CesiumPrimitiveMetadata.
*
* In other words, the "Primitive Property Texture Index" should index into
* the array property texture indices in the CesiumPrimitiveMetadata. The
* primitive metadata will not necessarily contain all of the available
* property textures in the CesiumModelMetadata, nor will it necessarily be
* listed in the same order.
*
* The returned result may be empty for several reasons:
* - if the component is not a Cesium glTF primitive component
* - if the given primitive property texture index is out-of-bounds
* - if the property texture index derived from CesiumPrimitiveMetadata
* is out-of-bounds
*
* Additionally, if any of the property texture's properties are invalid, they
* will not be included in the result.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|Picking")
static TMap<FString, FCesiumMetadataValue> GetPropertyTextureValuesFromHit(
const FHitResult& Hit,
int64 PrimitivePropertyTextureIndex = 0);
PRAGMA_DISABLE_DEPRECATION_WARNINGS
/**
* Gets the metadata values for a face on a glTF primitive component.
*
* A primitive may have multiple feature ID sets, so this allows a feature ID
* set to be specified by index. This value should index into the array of
* CesiumFeatureIdSets in the component's CesiumPrimitiveFeatures. If the
* feature ID set is associated with a property table, it will return that
* property table's data.
*
* For feature ID textures and implicit feature IDs, the feature ID can vary
* across the face of a primitive. If the specified CesiumFeatureIdSet is one
* of those types, the feature ID of the first vertex on the face will be
* used.
*
* The returned result may be empty for several reasons:
* - if the component is not a Cesium glTF primitive component
* - if the given face index is out-of-bounds
* - if the specified feature ID set does not exist on the primitive
* - if the specified feature ID set is not associated with a valid property
* table
*
* Additionally, if any of the property table's properties are invalid, they
* will not be included in the result.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Meta =
(DeprecatedFunction,
DeprecationMessage = "Use GetPropertyTableValuesFromHit instead."))
static TMap<FString, FCesiumMetadataValue> GetMetadataValuesForFace(
const UPrimitiveComponent* Component,
int64 FaceIndex,
int64 FeatureIDSetIndex = 0);
/**
* Gets the metadata values for a face on a glTF primitive component, as
* strings.
*
* A primitive may have multiple feature ID sets, so this allows a feature ID
* set to be specified by index. This value should index into the array of
* CesiumFeatureIdSets in the component's CesiumPrimitiveFeatures. If the
* feature ID set is associated with a property table, it will return that
* property table's data.
*
* For feature ID textures and implicit feature IDs, the feature ID can vary
* across the face of a primitive. If the specified CesiumFeatureIdSet is one
* of those types, the feature ID of the first vertex on the face will be
* used.
*
* The returned result may be empty for several reasons:
* - if the component is not a Cesium glTF primitive component
* - if the given face index is out-of-bounds
* - if the specified feature ID set does not exist on the primitive
* - if the specified feature ID set is not associated with a valid property
* table
*
* Additionally, if any of the property table's properties are invalid, they
* will not be included in the result. Array properties will return empty
* strings.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Meta =
(DeprecatedFunction,
DeprecationMessage =
"Use GetValuesAsStrings to convert the output of GetPropertyTableValuesFromHit instead."))
static TMap<FString, FString> GetMetadataValuesForFaceAsStrings(
const UPrimitiveComponent* Component,
int64 FaceIndex,
int64 FeatureIDSetIndex = 0);
PRAGMA_ENABLE_DEPRECATION_WARNINGS
};

View File

@ -0,0 +1,151 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumModelMetadata.h"
#include "CesiumPrimitiveFeatures.h"
#include "CesiumPrimitiveMetadata.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "UObject/ObjectMacros.h"
#include "CesiumMetadataPrimitive.generated.h"
struct UE_DEPRECATED(
5.0,
"FCesiumMetadataPrimitive is deprecated. Instead, use FCesiumPrimitiveFeatures and FCesiumPrimitiveMetadata to retrieve feature IDs and metadata from a glTF primitive.")
FCesiumMetadataPrimitive;
/**
* A Blueprint-accessible wrapper for a glTF Primitive's EXT_feature_metadata
* extension. This class is deprecated and only exists for backwards
* compatibility.
*/
USTRUCT(BlueprintType)
struct CESIUMRUNTIME_API FCesiumMetadataPrimitive {
GENERATED_USTRUCT_BODY()
public:
/**
* Construct an empty primitive metadata instance.
*/
FCesiumMetadataPrimitive()
: _pPrimitiveFeatures(nullptr),
_pPrimitiveMetadata(nullptr),
_pModelMetadata(nullptr) {}
/**
* Constructs a primitive metadata instance from the new features / metadata
* implementations for backwards compatibility.
*
* This class exists for backwards compatibility, so it requires a
* FCesiumPrimitiveFeatures to have been constructed beforehand. It assumes
* the given FCesiumPrimitiveFeatures will have the same lifetime as this
* instance.
*
* @param PrimitiveFeatures The FCesiumPrimitiveFeatures denoting the feature
* IDs in the glTF mesh primitive.
* @param PrimitiveMetadata The FCesiumPrimitiveMetadata containing references
* to the metadata for the glTF mesh primitive.
* @param ModelMetadata The FCesiumModelMetadata containing the property
* tables and textures contained in a glTF model.
*/
FCesiumMetadataPrimitive(
const FCesiumPrimitiveFeatures& PrimitiveFeatures,
const FCesiumPrimitiveMetadata& PrimitiveMetadata,
const FCesiumModelMetadata& ModelMetadata);
private:
const FCesiumPrimitiveFeatures* _pPrimitiveFeatures;
const FCesiumPrimitiveMetadata* _pPrimitiveMetadata;
const FCesiumModelMetadata* _pModelMetadata;
friend class UCesiumMetadataPrimitiveBlueprintLibrary;
};
UCLASS()
class CESIUMRUNTIME_API UCesiumMetadataPrimitiveBlueprintLibrary
: public UBlueprintFunctionLibrary {
GENERATED_BODY()
public:
PRAGMA_DISABLE_DEPRECATION_WARNINGS
/**
* Get all the feature ID attributes that are associated with the
* primitive.
*
* @param MetadataPrimitive The {@link FCesiumMetadataPrimitive} to obtain the
* feature ID attributes from.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|Primitive",
Meta =
(DeprecatedFunction,
DeprecationMessage =
"CesiumMetadataPrimitive is deprecated. Get feature IDs from CesiumPrimitiveFeatures instead."))
static const TArray<FCesiumFeatureIdAttribute>
GetFeatureIdAttributes(UPARAM(ref)
const FCesiumMetadataPrimitive& MetadataPrimitive);
/**
* Get all the feature ID textures that are associated with the
* primitive.
*
* @param MetadataPrimitive The {@link FCesiumMetadataPrimitive} to obtain the
* feature ID textures from.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|Primitive",
Meta =
(DeprecatedFunction,
DeprecationMessage =
"CesiumMetadataPrimitive is deprecated. Get feature IDs from CesiumPrimitiveFeatures instead."))
static const TArray<FCesiumFeatureIdTexture>
GetFeatureIdTextures(UPARAM(ref)
const FCesiumMetadataPrimitive& MetadataPrimitive);
/**
* @brief Get all the feature textures that are associated with the
* primitive.
*
* @param MetadataPrimitive The {@link FCesiumMetadataPrimitive} to obtain the
* feature texture names from.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|Primitive",
Meta =
(DeprecatedFunction,
DeprecationMessage =
"CesiumMetadataPrimitive is deprecated. Get the associated property texture indices from CesiumPrimitiveMetadata instead."))
static const TArray<FString>
GetFeatureTextureNames(UPARAM(ref)
const FCesiumMetadataPrimitive& MetadataPrimitive);
/**
* Gets the ID of the first vertex that makes up a given face of this
* primitive.
*
* @param MetadataPrimitive The {@link FCesiumMetadataPrimitive} to obtain the
* vertex ID from.
* @param FaceID The ID of the face.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|Primitive",
Meta =
(DeprecatedFunction,
DeprecationMessage =
"CesiumMetadataPrimitive is deprecated. Use GetFirstVertexFromFace with CesiumPrimitiveFeatures instead."))
static int64 GetFirstVertexIDFromFaceID(
UPARAM(ref) const FCesiumMetadataPrimitive& MetadataPrimitive,
int64 FaceID);
PRAGMA_ENABLE_DEPRECATION_WARNINGS
};

View File

@ -0,0 +1,170 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumMetadataValueType.h"
#include "UObject/ObjectMacros.h"
#include "CesiumMetadataPropertyDetails.generated.h"
/**
* Represents information about a metadata property according to how the
* property is defined in EXT_structural_metadata.
*/
USTRUCT(BlueprintType)
struct CESIUMRUNTIME_API FCesiumMetadataPropertyDetails {
GENERATED_USTRUCT_BODY()
FCesiumMetadataPropertyDetails()
: Type(ECesiumMetadataType::Invalid),
ComponentType(ECesiumMetadataComponentType::None),
bIsArray(false) {}
FCesiumMetadataPropertyDetails(
ECesiumMetadataType InType,
ECesiumMetadataComponentType InComponentType,
bool IsArray)
: Type(InType), ComponentType(InComponentType), bIsArray(IsArray) {}
/**
* The type of the metadata property.
*/
UPROPERTY(EditAnywhere, Category = "Cesium")
ECesiumMetadataType Type = ECesiumMetadataType::Invalid;
/**
* The component of the metadata property. Only applies when the type is a
* Scalar, VecN, or MatN type.
*/
UPROPERTY(
EditAnywhere,
Category = "Cesium",
Meta =
(EditCondition =
"Type != ECesiumMetadataType::Invalid && Type != ECesiumMetadataType::Boolean && Type != ECesiumMetadataType::Enum && Type != ECesiumMetadataType::String"))
ECesiumMetadataComponentType ComponentType =
ECesiumMetadataComponentType::None;
/**
* Whether or not this represents an array containing elements of the
* specified types.
*/
UPROPERTY(EditAnywhere, Category = "Cesium")
bool bIsArray = false;
/**
* The size of the arrays in the metadata property. If the property contains
* arrays of varying length, this will be zero even though bIsArray will be
* true> If this property does not contain arrays, this is set to zero.
*/
UPROPERTY(
EditAnywhere,
Category = "Cesium",
Meta = (EditCondition = "bIsArray"))
int64 ArraySize = 0;
/**
* Whether or not the values in this property are normalized. Only applicable
* to scalar, vecN, and matN types with integer components.
*
* For unsigned integer component types, values are normalized between
* [0.0, 1.0]. For signed integer component types, values are normalized
* between [-1.0, 1.0]
*/
UPROPERTY(
EditAnywhere,
Category = "Cesium",
Meta =
(EditCondition =
"Type != ECesiumMetadataType::Invalid && Type != ECesiumMetadataType::Boolean && Type != ECesiumMetadataType::Enum && Type != ECesiumMetadataType::String && ComponentType != ECesiumMetadataComponentType::None && ComponentType != ECesiumMetadataComponentType::Float32 && ComponentType != ECesiumMetadataComponentType::Float64"))
bool bIsNormalized = false;
/**
* Whether or not the property is transformed by an offset. This value is
* defined either in the class property, or in the instance of the property
* itself.
*/
UPROPERTY(
EditAnywhere,
Category = "Cesium",
Meta =
(EditCondition =
"Type != ECesiumMetadataType::Invalid && Type != ECesiumMetadataType::Boolean && Type != ECesiumMetadataType::Enum && Type != ECesiumMetadataType::String"))
bool bHasOffset = false;
/**
* Whether or not the property is transformed by a scale. This value is
* defined either in the class property, or in the instance of the property
* itself.
*/
UPROPERTY(
EditAnywhere,
Category = "Cesium",
Meta =
(EditCondition =
"Type != ECesiumMetadataType::Invalid && Type != ECesiumMetadataType::Boolean && Type != ECesiumMetadataType::Enum && Type != ECesiumMetadataType::String"))
bool bHasScale = false;
/**
* Whether or not the property specifies a "no data" value. This value
* functions a sentinel value, indicating missing data wherever it appears.
*/
UPROPERTY(
EditAnywhere,
Category = "Cesium",
Meta =
(EditCondition =
"Type != ECesiumMetadataType::Invalid && Type != ECesiumMetadataType::Boolean && Type != ECesiumMetadataType::Enum"))
bool bHasNoDataValue = false;
/**
* Whether or not the property specifies a default value. This default value
* is used use when encountering a "no data" value in the property, or when a
* non-required property has been omitted.
*/
UPROPERTY(
EditAnywhere,
Category = "Cesium",
Meta =
(EditCondition =
"Type != ECesiumMetadataType::Invalid && Type != ECesiumMetadataType::Enum"))
bool bHasDefaultValue = false;
inline bool
operator==(const FCesiumMetadataPropertyDetails& ValueType) const {
return Type == ValueType.Type && ComponentType == ValueType.ComponentType &&
bIsArray == ValueType.bIsArray;
}
inline bool
operator!=(const FCesiumMetadataPropertyDetails& ValueType) const {
return !operator==(ValueType);
}
/**
* Returns the internal types as a FCesiumMetadataValueType.
*/
FCesiumMetadataValueType GetValueType() const {
return FCesiumMetadataValueType(Type, ComponentType, bIsArray);
}
/**
* Sets the internal types to the values supplied by the input
* FCesiumMetadataValueType.
*/
void SetValueType(FCesiumMetadataValueType ValueType) {
Type = ValueType.Type;
ComponentType = ValueType.ComponentType;
bIsArray = ValueType.bIsArray;
}
/**
* Whether this property has one or more value transforms. This includes
* normalization, offset, and scale, as well as the "no data" and default
* values.
*/
bool HasValueTransforms() const {
return bIsNormalized || bHasOffset || bHasScale || bHasNoDataValue ||
bHasDefaultValue;
}
};

View File

@ -0,0 +1,84 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumFeatureIdAttribute.h"
#include "CesiumMetadataPrimitive.h"
#include "CesiumMetadataValue.h"
#include "CesiumPrimitiveMetadata.h"
#include "Containers/UnrealString.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "UObject/ObjectMacros.h"
#include "CesiumMetadataUtilityBlueprintLibrary.generated.h"
UCLASS()
class CESIUMRUNTIME_API UCesiumMetadataUtilityBlueprintLibrary
: public UBlueprintFunctionLibrary {
GENERATED_BODY()
public:
PRAGMA_DISABLE_DEPRECATION_WARNINGS
/**
* Gets the primitive metadata of a glTF primitive component. If component is
* not a Cesium glTF primitive component, the returned metadata is empty
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Meta =
(DeprecatedFunction,
DeprecationMessage =
"CesiumMetadataPrimitive is deprecated. Use CesiumPrimitiveFeatures and CesiumPrimitiveMetadata instead."))
static const FCesiumMetadataPrimitive&
GetPrimitiveMetadata(const UPrimitiveComponent* component);
/**
* Gets the metadata of a face of a glTF primitive component. If the component
* is not a Cesium glTF primitive component, the returned metadata is empty.
* If the primitive has multiple feature tables, the metadata in the first
* table is returned.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Meta =
(DeprecatedFunction,
DeprecationMessage =
"The CesiumMetadataUtility blueprint library is deprecated. Use GetMetadataValuesForFace in the CesiumMetadataPicking blueprint library instead."))
static TMap<FString, FCesiumMetadataValue>
GetMetadataValuesForFace(const UPrimitiveComponent* component, int64 faceID);
/**
* Gets the metadata as string of a face of a glTF primitive component. If the
* component is not a Cesium glTF primitive component, the returned metadata
* is empty. If the primitive has multiple feature tables, the metadata in the
* first table is returned.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Meta =
(DeprecatedFunction,
DeprecationMessage =
"The CesiumMetadataUtility blueprint library is deprecated. Use GetMetadataValuesForFaceAsStrings in the CesiumMetadataPicking blueprint library instead."))
static TMap<FString, FString> GetMetadataValuesAsStringForFace(
const UPrimitiveComponent* component,
int64 faceID);
/**
* Gets the feature ID associated with a given face for a feature id
* attribute.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Meta =
(DeprecatedFunction,
DeprecationMessage =
"Use GetFeatureIDFromFace with CesiumPrimitiveFeatures instead."))
static int64 GetFeatureIDFromFaceID(
UPARAM(ref) const FCesiumMetadataPrimitive& Primitive,
UPARAM(ref) const FCesiumFeatureIdAttribute& FeatureIDAttribute,
int64 FaceID);
PRAGMA_ENABLE_DEPRECATION_WARNINGS
};

View File

@ -0,0 +1,846 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumGltf/PropertyTypeTraits.h"
#include "CesiumMetadataValueType.h"
#include "CesiumPropertyArray.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "UObject/ObjectMacros.h"
#include <glm/glm.hpp>
#include <optional>
#include <swl/variant.hpp>
#include "CesiumMetadataValue.generated.h"
/**
* A Blueprint-accessible wrapper for a glTF metadata value.
*/
USTRUCT(BlueprintType)
struct CESIUMRUNTIME_API FCesiumMetadataValue {
GENERATED_USTRUCT_BODY()
private:
#pragma region ValueType declaration
template <typename T> using ArrayView = CesiumGltf::PropertyArrayView<T>;
using ValueType = swl::variant<
swl::monostate,
int8_t,
uint8_t,
int16_t,
uint16_t,
int32_t,
uint32_t,
int64_t,
uint64_t,
float,
double,
bool,
std::string_view,
glm::vec<2, int8_t>,
glm::vec<2, uint8_t>,
glm::vec<2, int16_t>,
glm::vec<2, uint16_t>,
glm::vec<2, int32_t>,
glm::vec<2, uint32_t>,
glm::vec<2, int64_t>,
glm::vec<2, uint64_t>,
glm::vec<2, float>,
glm::vec<2, double>,
glm::vec<3, int8_t>,
glm::vec<3, uint8_t>,
glm::vec<3, int16_t>,
glm::vec<3, uint16_t>,
glm::vec<3, int32_t>,
glm::vec<3, uint32_t>,
glm::vec<3, int64_t>,
glm::vec<3, uint64_t>,
glm::vec<3, float>,
glm::vec<3, double>,
glm::vec<4, int8_t>,
glm::vec<4, uint8_t>,
glm::vec<4, int16_t>,
glm::vec<4, uint16_t>,
glm::vec<4, int32_t>,
glm::vec<4, uint32_t>,
glm::vec<4, int64_t>,
glm::vec<4, uint64_t>,
glm::vec<4, float>,
glm::vec<4, double>,
glm::mat<2, 2, int8_t>,
glm::mat<2, 2, uint8_t>,
glm::mat<2, 2, int16_t>,
glm::mat<2, 2, uint16_t>,
glm::mat<2, 2, int32_t>,
glm::mat<2, 2, uint32_t>,
glm::mat<2, 2, int64_t>,
glm::mat<2, 2, uint64_t>,
glm::mat<2, 2, float>,
glm::mat<2, 2, double>,
glm::mat<3, 3, int8_t>,
glm::mat<3, 3, uint8_t>,
glm::mat<3, 3, int16_t>,
glm::mat<3, 3, uint16_t>,
glm::mat<3, 3, int32_t>,
glm::mat<3, 3, uint32_t>,
glm::mat<3, 3, int64_t>,
glm::mat<3, 3, uint64_t>,
glm::mat<3, 3, float>,
glm::mat<3, 3, double>,
glm::mat<4, 4, int8_t>,
glm::mat<4, 4, uint8_t>,
glm::mat<4, 4, int16_t>,
glm::mat<4, 4, uint16_t>,
glm::mat<4, 4, int32_t>,
glm::mat<4, 4, uint32_t>,
glm::mat<4, 4, int64_t>,
glm::mat<4, 4, uint64_t>,
glm::mat<4, 4, float>,
glm::mat<4, 4, double>,
ArrayView<int8_t>,
ArrayView<uint8_t>,
ArrayView<int16_t>,
ArrayView<uint16_t>,
ArrayView<int32_t>,
ArrayView<uint32_t>,
ArrayView<int64_t>,
ArrayView<uint64_t>,
ArrayView<float>,
ArrayView<double>,
ArrayView<bool>,
ArrayView<std::string_view>,
ArrayView<glm::vec<2, int8_t>>,
ArrayView<glm::vec<2, uint8_t>>,
ArrayView<glm::vec<2, int16_t>>,
ArrayView<glm::vec<2, uint16_t>>,
ArrayView<glm::vec<2, int32_t>>,
ArrayView<glm::vec<2, uint32_t>>,
ArrayView<glm::vec<2, int64_t>>,
ArrayView<glm::vec<2, uint64_t>>,
ArrayView<glm::vec<2, float>>,
ArrayView<glm::vec<2, double>>,
ArrayView<glm::vec<3, int8_t>>,
ArrayView<glm::vec<3, uint8_t>>,
ArrayView<glm::vec<3, int16_t>>,
ArrayView<glm::vec<3, uint16_t>>,
ArrayView<glm::vec<3, int32_t>>,
ArrayView<glm::vec<3, uint32_t>>,
ArrayView<glm::vec<3, int64_t>>,
ArrayView<glm::vec<3, uint64_t>>,
ArrayView<glm::vec<3, float>>,
ArrayView<glm::vec<3, double>>,
ArrayView<glm::vec<4, int8_t>>,
ArrayView<glm::vec<4, uint8_t>>,
ArrayView<glm::vec<4, int16_t>>,
ArrayView<glm::vec<4, uint16_t>>,
ArrayView<glm::vec<4, int32_t>>,
ArrayView<glm::vec<4, uint32_t>>,
ArrayView<glm::vec<4, int64_t>>,
ArrayView<glm::vec<4, uint64_t>>,
ArrayView<glm::vec<4, float>>,
ArrayView<glm::vec<4, double>>,
ArrayView<glm::mat<2, 2, int8_t>>,
ArrayView<glm::mat<2, 2, uint8_t>>,
ArrayView<glm::mat<2, 2, int16_t>>,
ArrayView<glm::mat<2, 2, uint16_t>>,
ArrayView<glm::mat<2, 2, int32_t>>,
ArrayView<glm::mat<2, 2, uint32_t>>,
ArrayView<glm::mat<2, 2, int64_t>>,
ArrayView<glm::mat<2, 2, uint64_t>>,
ArrayView<glm::mat<2, 2, float>>,
ArrayView<glm::mat<2, 2, double>>,
ArrayView<glm::mat<3, 3, int8_t>>,
ArrayView<glm::mat<3, 3, uint8_t>>,
ArrayView<glm::mat<3, 3, int16_t>>,
ArrayView<glm::mat<3, 3, uint16_t>>,
ArrayView<glm::mat<3, 3, int32_t>>,
ArrayView<glm::mat<3, 3, uint32_t>>,
ArrayView<glm::mat<3, 3, int64_t>>,
ArrayView<glm::mat<3, 3, uint64_t>>,
ArrayView<glm::mat<3, 3, float>>,
ArrayView<glm::mat<3, 3, double>>,
ArrayView<glm::mat<4, 4, int8_t>>,
ArrayView<glm::mat<4, 4, uint8_t>>,
ArrayView<glm::mat<4, 4, int16_t>>,
ArrayView<glm::mat<4, 4, uint16_t>>,
ArrayView<glm::mat<4, 4, int32_t>>,
ArrayView<glm::mat<4, 4, uint32_t>>,
ArrayView<glm::mat<4, 4, int64_t>>,
ArrayView<glm::mat<4, 4, uint64_t>>,
ArrayView<glm::mat<4, 4, float>>,
ArrayView<glm::mat<4, 4, double>>>;
#pragma endregion
public:
/**
* Constructs an empty metadata value with unknown type.
*/
FCesiumMetadataValue() : _value(swl::monostate{}), _valueType(), _storage() {}
/**
* Constructs a metadata value with the given input.
*
* @param Value The value to be stored in this struct.
*/
template <typename T>
explicit FCesiumMetadataValue(const T& Value)
: _value(Value), _valueType(), _storage() {
ECesiumMetadataType type;
ECesiumMetadataComponentType componentType;
bool isArray;
if constexpr (CesiumGltf::IsMetadataArray<T>::value) {
using ArrayType = typename CesiumGltf::MetadataArrayType<T>::type;
type =
ECesiumMetadataType(CesiumGltf::TypeToPropertyType<ArrayType>::value);
componentType = ECesiumMetadataComponentType(
CesiumGltf::TypeToPropertyType<ArrayType>::component);
isArray = true;
} else {
type = ECesiumMetadataType(CesiumGltf::TypeToPropertyType<T>::value);
componentType = ECesiumMetadataComponentType(
CesiumGltf::TypeToPropertyType<T>::component);
isArray = false;
}
_valueType = {type, componentType, isArray};
}
template <typename ArrayType>
explicit FCesiumMetadataValue(
const CesiumGltf::PropertyArrayCopy<ArrayType>& Copy)
: FCesiumMetadataValue(CesiumGltf::PropertyArrayCopy<ArrayType>(Copy)) {}
template <typename ArrayType>
explicit FCesiumMetadataValue(CesiumGltf::PropertyArrayCopy<ArrayType>&& Copy)
: _value(), _valueType(), _storage() {
this->_value = std::move(Copy).toViewAndExternalBuffer(this->_storage);
ECesiumMetadataType type =
ECesiumMetadataType(CesiumGltf::TypeToPropertyType<ArrayType>::value);
ECesiumMetadataComponentType componentType = ECesiumMetadataComponentType(
CesiumGltf::TypeToPropertyType<ArrayType>::component);
bool isArray = true;
this->_valueType = {type, componentType, isArray};
}
/**
* Constructs a metadata value with the given optional input.
*
* @param MaybeValue The optional value to be stored in this struct.
*/
template <typename T>
explicit FCesiumMetadataValue(const std::optional<T>& MaybeValue)
: _value(), _valueType(), _storage() {
if (!MaybeValue) {
return;
}
FCesiumMetadataValue temp(*MaybeValue);
this->_value = std::move(temp._value);
this->_valueType = std::move(temp._valueType);
this->_storage = std::move(temp._storage);
}
FCesiumMetadataValue(FCesiumMetadataValue&& rhs);
FCesiumMetadataValue& operator=(FCesiumMetadataValue&& rhs);
FCesiumMetadataValue(const FCesiumMetadataValue& rhs);
FCesiumMetadataValue& operator=(const FCesiumMetadataValue& rhs);
private:
ValueType _value;
FCesiumMetadataValueType _valueType;
std::vector<std::byte> _storage;
friend class UCesiumMetadataValueBlueprintLibrary;
};
UCLASS()
class CESIUMRUNTIME_API UCesiumMetadataValueBlueprintLibrary
: public UBlueprintFunctionLibrary {
GENERATED_BODY()
public:
/**
* Gets the best-fitting Blueprints type for this value. For the most precise
* representation of the value possible from Blueprints, you should retrieve
* it using this type.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|Value")
static ECesiumMetadataBlueprintType
GetBlueprintType(UPARAM(ref) const FCesiumMetadataValue& Value);
/**
* Gets the best-fitting Blueprints type for the elements of this array value.
* If the given value is not of an array type, this returns None.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|Value")
static ECesiumMetadataBlueprintType
GetArrayElementBlueprintType(UPARAM(ref) const FCesiumMetadataValue& Value);
/**
* Gets the type of the metadata value as defined in the
* EXT_structural_metadata extension. Many of these types are not accessible
* from Blueprints, but can be converted to a Blueprint-accessible type.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|Value")
static FCesiumMetadataValueType
GetValueType(UPARAM(ref) const FCesiumMetadataValue& Value);
PRAGMA_DISABLE_DEPRECATION_WARNINGS
/**
* Gets true type of the value. Many of these types are not accessible
* from Blueprints, but can be converted to a Blueprint-accessible type.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Meta =
(DeprecatedFunction,
DeprecationMessage =
"CesiumMetadataTrueType is deprecated. Use GetValueType to get the CesiumMetadataValueType instead."))
static ECesiumMetadataTrueType_DEPRECATED
GetTrueType(UPARAM(ref) const FCesiumMetadataValue& Value);
/**
* Gets true type of the elements in the array. If this value is not an array,
* the component type will be None. Many of these types are not accessible
* from Blueprints, but can be converted to a Blueprint-accessible type.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Meta =
(DeprecatedFunction,
DeprecationMessage =
"CesiumMetadataTrueType is deprecated. Use GetValueType to get the CesiumMetadataValueType instead."))
static ECesiumMetadataTrueType_DEPRECATED
GetTrueComponentType(UPARAM(ref) const FCesiumMetadataValue& Value);
PRAGMA_ENABLE_DEPRECATION_WARNINGS
/**
* Attempts to retrieve the value as a boolean.
*
* If the value is a boolean, it is returned as-is.
*
* If the value is a scalar, zero is converted to false, while any other
* value is converted to true.
*
* If the value is a string, "0", "false", and "no" (case-insensitive) are
* converted to false, while "1", "true", and "yes" are converted to true.
* All other strings, including strings that can be converted to numbers,
* will return the default value.
*
* All other types return the default value.
*
* @param value The metadata value to retrieve.
* @param DefaultValue The default value to use if the given value cannot
* be converted to a Boolean.
* @return The value as a Boolean.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|Value")
static bool
GetBoolean(UPARAM(ref) const FCesiumMetadataValue& value, bool DefaultValue);
/**
* Attempts to retrieve the value as an unsigned 8-bit integer.
*
* If the value is an integer between 0 and 255, it is returned
* as-is.
*
* If the value is a floating-point number in the aforementioned range, it is
* truncated (rounded toward zero) and returned.
*
* If the value is a boolean, 1 is returned for true and 0 for false.
*
* If the value is a string and the entire string can be parsed as an
* integer between 0 and 255, the parsed value is returned. The string is
* parsed in a locale-independent way and does not support the use of commas
* or other delimiters to group digits together.
*
* In all other cases, the default value is returned.
*
* @param Value The metadata value to retrieve.
* @param DefaultValue The default value to use if the given value cannot
* be converted to a Byte.
* @return The value as a Byte.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|Value")
static uint8
GetByte(UPARAM(ref) const FCesiumMetadataValue& Value, uint8 DefaultValue);
/**
* Attempts to retrieve the value as a signed 32-bit integer.
*
* If the value is an integer between -2,147,483,648 and 2,147,483,647,
* it is returned as-is.
*
* If the value is a floating-point number in the aforementioned range, it is
* truncated (rounded toward zero) and returned;
*
* If the value is a boolean, 1 is returned for true and 0 for false.
*
* If the value is a string and the entire string can be parsed as an
* integer in the valid range, the parsed value is returned. If it can be
* parsed as a floating-point number, the parsed value is truncated (rounded
* toward zero). In either case, the string is parsed in a locale-independent
* way and does not support the use of commas or other delimiters to group
* digits together.
*
* In all other cases, the default value is returned.
*
* @param Value The metadata value to retrieve.
* @param DefaultValue The default value to use if the given value cannot
* be converted to an Integer.
* @return The value as an Integer.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|Value")
static int32
GetInteger(UPARAM(ref) const FCesiumMetadataValue& Value, int32 DefaultValue);
/**
* Attempts to retrieve the value as a signed 64-bit integer.
*
* If the value is an integer and between -2^63 and (2^63 - 1),
* it is returned as-is.
*
* If the value is a floating-point number in the aforementioned range, it
* is truncated (rounded toward zero) and returned;
*
* If the value is a boolean, 1 is returned for true and 0 for false.
*
* If the value is a string and the entire string can be parsed as an
* integer in the valid range, the parsed value is returned. If it can be
* parsed as a floating-point number, the parsed value is truncated (rounded
* toward zero). In either case, the string is parsed in a locale-independent
* way and does not support the use of commas or other delimiters to group
* digits together.
*
* In all other cases, the default value is returned.
*
* @param Value The metadata value to retrieve.
* @param DefaultValue The default value to use if the given value cannot
* be converted to an Integer64.
* @return The value as an Integer64.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|Value")
static int64 GetInteger64(
UPARAM(ref) const FCesiumMetadataValue& Value,
int64 DefaultValue);
/**
* Attempts to retrieve the value as a single-precision floating-point number.
*
* If the value is already a single-precision floating-point number, it is
* returned as-is.
*
* If the value is a scalar of any other type within the range of values that
* a single-precision float can represent, it is converted to its closest
* representation as a single-precision float and returned.
*
* If the value is a boolean, 1.0f is returned for true and 0.0f for false.
*
* If the value is a string, and the entire string can be parsed as a
* number, the parsed value is returned. The string is parsed in a
* locale-independent way and does not support the use of a comma or other
* delimiter to group digits togther.
*
* In all other cases, the default value is returned.
*
* @param Value The metadata value to retrieve.
* @param DefaultValue The default value to use if the given value cannot
* be converted to a Float.
* @return The value as a Float.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|Value")
static float
GetFloat(UPARAM(ref) const FCesiumMetadataValue& Value, float DefaultValue);
/**
* Attempts to retrieve the value as a double-precision floating-point number.
*
* If the value is a single- or double-precision floating-point number, it is
* returned as-is.
*
* If the value is an integer, it is converted to the closest representable
* double-precision floating-point number.
*
* If the value is a boolean, 1.0 is returned for true and 0.0 for false.
*
* If the value is a string and the entire string can be parsed as a
* number, the parsed value is returned. The string is parsed in a
* locale-independent way and does not support the use of commas or other
* delimiters to group digits together.
*
* In all other cases, the default value is returned.
*
* @param Value The metadata value to retrieve.
* @param DefaultValue The default value to use if the given value cannot
* be converted to a Float64.
* @return The value as a Float64.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|Value")
static double GetFloat64(
UPARAM(ref) const FCesiumMetadataValue& Value,
double DefaultValue);
/**
* Attempts to retrieve the value as a FIntPoint.
*
* If the value is a 2-dimensional vector, its components will be converted to
* 32-bit signed integers if possible.
*
* If the value is a 3- or 4-dimensional vector, it will use the first two
* components to construct the FIntPoint.
*
* If the value is a scalar that can be converted to a 32-bit signed integer,
* the resulting FIntPoint will have this value in both of its components.
*
* If the value is a boolean, (1, 1) is returned for true, while (0, 0) is
* returned for false.
*
* If the value is a string that can be parsed as a FIntPoint, the parsed
* value is returned. The string must be formatted as "X=... Y=...".
*
* In all other cases, the default value is returned. In all vector cases, if
* any of the relevant components cannot be represented as a 32-bit signed,
* the default value is returned.
*
* @param Value The metadata value to retrieve.
* @param DefaultValue The default value to use if the given value cannot
* be converted to a FIntPoint.
* @return The value as a FIntPoint.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|Value")
static FIntPoint GetIntPoint(
UPARAM(ref) const FCesiumMetadataValue& Value,
const FIntPoint& DefaultValue);
/**
* Attempts to retrieve the value as a FVector2D.
*
* If the value is a 2-dimensional vector, its components will be converted to
* double-precision floating-point numbers.
*
* If the value is a 3- or 4-dimensional vector, it will use the first two
* components to construct the FVector2D.
*
* If the value is a scalar, the resulting FVector2D will have this value in
* both of its components.
*
* If the value is a boolean, (1.0, 1.0) is returned for true, while (0.0,
* 0.0) is returned for false.
*
* If the value is a string that can be parsed as a FVector2D, the parsed
* value is returned. The string must be formatted as "X=... Y=...".
*
* In all other cases, the default value is returned.
*
* @param Value The metadata value to retrieve.
* @param DefaultValue The default value to use if the given value cannot
* be converted to a FIntPoint.
* @return The value as a FIntPoint.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|Value")
static FVector2D GetVector2D(
UPARAM(ref) const FCesiumMetadataValue& Value,
const FVector2D& DefaultValue);
/**
* Attempts to retrieve the value as a FIntVector.
*
* If the value is a 3-dimensional vector, its components will be converted to
* 32-bit signed integers if possible.
*
* If the value is a 4-dimensional vector, it will use the first three
* components to construct the FIntVector.
*
* If the value is a 2-dimensional vector, it will become the XY-components of
* the FIntVector. The Z component will be set to zero.
*
* If the value is a scalar that can be converted to a 32-bit signed integer,
* the resulting FIntVector will have this value in all of its components.
*
* If the value is a boolean, (1, 1, 1) is returned for true, while (0, 0, 0)
* is returned for false.
*
* If the value is a string that can be parsed as a FIntVector, the parsed
* value is returned. The string must be formatted as "X=... Y=... Z=".
*
* In all other cases, the default value is returned. In all vector cases, if
* any of the relevant components cannot be represented as a 32-bit signed
* integer, the default value is returned.
*
* @param Value The metadata value to retrieve.
* @param DefaultValue The default value to use if the given value cannot
* be converted to a FIntVector.
* @return The value as a FIntVector.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|Value")
static FIntVector GetIntVector(
UPARAM(ref) const FCesiumMetadataValue& Value,
const FIntVector& DefaultValue);
/**
* Attempts to retrieve the value as a FVector3f.
*
* If the value is a 3-dimensional vector, its components will be converted to
* the closest representable single-precision floats, if possible.
*
* If the value is a 4-dimensional vector, a FVector3f containing the first
* three components will be returned.
*
* If the value is a 2-dimensional vector, it will become the XY-components of
* the FVector3f. The Z-component will be set to zero.
*
* If the value is a scalar that can be converted to a single-precision
* floating-point number, then the resulting FVector3f will have this value in
* all of its components.
*
* If the value is a boolean, (1.0f, 1.0f, 1.0f) is returned for true, while
* (0.0f, 0.0f, 0.0f) is returned for false.
*
* If the value is a string that can be parsed as a FVector3f, the parsed
* value is returned. The string must be formatted as "X=... Y=... Z=".
*
* In all other cases, the default value is returned. In all vector cases, if
* any of the relevant components cannot be represented as a single-precision
* float, the default value is returned.
*
* @param Value The metadata value to retrieve.
* @param DefaultValue The default value to use if the given value cannot
* be converted to a FVector3f.
* @return The value as a FVector3f.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|Value")
static FVector3f GetVector3f(
UPARAM(ref) const FCesiumMetadataValue& Value,
const FVector3f& DefaultValue);
/**
* Attempts to retrieve the value as a FVector.
*
* If the value is a 3-dimensional vector, its components will be converted to
* double-precision floating-point numbers.
*
* If the value is a 4-dimensional vector, a FVector containing the first
* three components will be returned.
*
* If the value is a 2-dimensional vector, it will become the XY-components of
* the FVector. The Z-component will be set to zero.
*
* If the value is a scalar, then the resulting FVector will have this value
* as a double-precision floating-point number in all of its components.
*
* If the value is a boolean, (1.0, 1.0, 1.0) is returned for true, while
* (0.0, 0.0, 0.0) is returned for false.
*
* If the value is a string that can be parsed as a FVector, the parsed
* value is returned. The string must be formatted as "X=... Y=... Z=".
*
* In all other cases, the default value is returned.
*
* @param Value The metadata value to retrieve.
* @param DefaultValue The default value to use if the given value cannot
* be converted to a FVector.
* @return The value as a FVector.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|Value")
static FVector GetVector(
UPARAM(ref) const FCesiumMetadataValue& Value,
const FVector& DefaultValue);
/**
* Attempts to retrieve the value as a FVector4.
*
* If the value is a 4-dimensional vector, its components will be converted to
* double-precision floating-point numbers.
*
* If the value is a 3-dimensional vector, it will become the XYZ-components
* of the FVector4. The W-component will be set to zero.
*
* If the value is a 2-dimensional vector, it will become the XY-components of
* the FVector4. The Z- and W-components will be set to zero.
*
* If the value is a scalar, then the resulting FVector4 will have this value
* as a double-precision floating-point number in all of its components.
*
* If the value is a boolean, (1.0, 1.0, 1.0, 1.0) is returned for true, while
* (0.0, 0.0, 0.0, 0.0) is returned for false.
*
* If the value is a string that can be parsed as a FVector4, the parsed
* value is returned. This follows the rules of FVector4::InitFromString. The
* string must be formatted as "X=... Y=... Z=... W=...". The W-component is
* optional; if absent, it will be set to 1.0.
*
* In all other cases, the default value is returned.
*
* @param Value The metadata value to retrieve.
* @param DefaultValue The default value to use if the given value cannot
* be converted to a FVector4.
* @return The value as a FVector4.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|Value")
static FVector4 GetVector4(
UPARAM(ref) const FCesiumMetadataValue& Value,
const FVector4& DefaultValue);
/**
* Attempts to retrieve the value as a FMatrix.
*
* If the value is a 4-by-4 matrix, its components will be converted to
* double-precision floating-point numbers.
*
* If the value is a 3-by-3 matrix, it will initialize the corresponding
* entries of the FMatrix, while all other entries are set to zero. In other
* words, the 3-by-3 matrix is returned in an FMatrix where the fourth row and
* column are filled with zeroes.
*
* If the value is a 2-by-2 matrix, it will initialize the corresponding
* entries of the FMatrix, while all other entries are set to zero. In other
* words, the 2-by-2 matrix is returned in an FMatrix where the third and
* fourth rows / columns are filled with zeroes.
*
* If the value is a scalar, then the resulting FMatrix will have this value
* along its diagonal, including the very last component. All other entries
* will be zero.
*
* If the value is a boolean, it is converted to 1.0 for true and 0.0 for
* false. Then, the resulting FMatrix will have this value along its diagonal,
* including the very last component. All other entries will be zero.
*
* In all other cases, the default value is returned.
*
* @param Value The metadata value to retrieve.
* @param DefaultValue The default value to use if the given value cannot
* be converted to a FMatrix.
* @return The value as a FMatrix.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|Value")
static FMatrix GetMatrix(
UPARAM(ref) const FCesiumMetadataValue& Value,
const FMatrix& DefaultValue);
/**
* Attempts to retrieve the value as a FString.
*
* String properties are returned as-is.
*
* Scalar values are converted to a string with `std::to_string`.
*
* Boolean properties are converted to "true" or "false".
*
* Vector properties are returned as strings in the format "X=... Y=... Z=...
* W=..." depending on how many components they have.
*
* Matrix properties are returned as strings row-by-row, where each row's
* values are printed between square brackets. For example, a 2-by-2 matrix
* will be printed out as "[A B] [C D]".
*
* Array properties return the default value.
*
* @param Value The metadata value to retrieve.
* @param DefaultValue The default value to use if the given value cannot
* be converted to a FString.
* @return The value as a FString.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|Value")
static FString GetString(
UPARAM(ref) const FCesiumMetadataValue& Value,
const FString& DefaultValue);
/**
* Attempts to retrieve the value as a FCesiumPropertyArray. If the property
* is not an array type, this returns an empty array.
*
* @param Value The metadata value to retrieve.
* @return The value as a FCesiumPropertyArray.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|Value")
static FCesiumPropertyArray GetArray(UPARAM(ref)
const FCesiumMetadataValue& Value);
/**
* Whether the value is empty, i.e., whether it does not actually represent
* any data. An empty value functions as a null value, and can be compared to
* a std::nullopt in C++. For example, when the raw value of a property
* matches the property's specified "no data" value, it will return an empty
* FCesiumMetadataValue.
*
* @param Value The metadata value to retrieve.
* @return Whether the value is empty.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|Value")
static bool IsEmpty(UPARAM(ref) const FCesiumMetadataValue& Value);
/**
* Gets the given map of metadata values as a new map of strings, mapped by
* name. This is useful for displaying the values from a property table or
* property texture as strings in a user interface.
*
* Array properties cannot be converted to strings, so empty strings
* will be returned for their values.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|Value")
static TMap<FString, FString>
GetValuesAsStrings(const TMap<FString, FCesiumMetadataValue>& Values);
};

View File

@ -0,0 +1,253 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumGltf/PropertyArrayView.h"
#include "CesiumGltf/PropertyType.h"
#include "CesiumGltf/PropertyTypeTraits.h"
#include "CesiumMetadataValueType.generated.h"
/**
* The Blueprint type that can losslessly represent values of a given property.
*/
UENUM(BlueprintType)
enum class ECesiumMetadataBlueprintType : uint8 {
/* Indicates a value cannot be represented in Blueprints. */
None,
/* Indicates a value is best represented as a Boolean. */
Boolean,
/* Indicates a value is best represented as a Byte (8-bit unsigned integer).
*/
Byte,
/* Indicates a value is best represented as a Integer (32-bit signed). */
Integer,
/* Indicates a value is best represented as a Integer64 (64-bit signed). */
Integer64,
/* Indicates a value is best represented as a Float (32-bit). */
Float,
/* Indicates a value is best represented as a Float64 (64-bit). */
Float64,
/* Indicates a value is best represented as a FVector2D (2-dimensional
integer vector). */
IntPoint,
/* Indicates a value is best represented as a FVector2D (2-dimensional
double-precision vector). */
Vector2D,
/* Indicates a value is best represented as a FIntVector (3-dimensional
integer vector). */
IntVector,
/* Indicates a value is best represented as a FVector3f (3-dimensional
single-precision vector). */
Vector3f,
/* Indicates a value is best represented as a FVector3 (3-dimensional
double-precision vector). */
Vector3,
/* Indicates a value is best represented as a FVector4 (4-dimensional
double-precision vector). */
Vector4,
/* Indicates a value is best represented as a FMatrix (4-by-4 double-precision
matrix). */
Matrix,
/* Indicates a value is best represented as a FString. This can be used as a
fallback for types with no proper Blueprints representation. */
String,
/* Indicates a value is best represented as a CesiumPropertyArray. */
Array
};
// UE requires us to have an enum with the value 0.
// Invalid / None should have that value, but just make sure.
static_assert(int(CesiumGltf::PropertyType::Invalid) == 0);
static_assert(int(CesiumGltf::PropertyComponentType::None) == 0);
/**
* The type of a metadata property in EXT_feature_metadata. This has been
* deprecated; use FCesiumMetadataValueType to get the complete type information
* of a metadata property instead.
*/
UENUM(BlueprintType)
enum class ECesiumMetadataTrueType_DEPRECATED : uint8 {
None_DEPRECATED = 0,
Int8_DEPRECATED,
Uint8_DEPRECATED,
Int16_DEPRECATED,
Uint16_DEPRECATED,
Int32_DEPRECATED,
Uint32_DEPRECATED,
Int64_DEPRECATED,
Uint64_DEPRECATED,
Float32_DEPRECATED,
Float64_DEPRECATED,
Boolean_DEPRECATED,
Enum_DEPRECATED,
String_DEPRECATED,
Array_DEPRECATED
};
// True types are cast, reintepreted, or parsed before being packed into gpu
// types when encoding into a texture.
enum class ECesiumMetadataPackedGpuType_DEPRECATED : uint8 {
None_DEPRECATED,
Uint8_DEPRECATED,
Float_DEPRECATED
};
/**
* The type of a metadata property in EXT_structural_metadata.
*/
UENUM(BlueprintType)
enum class ECesiumMetadataType : uint8 {
Invalid = 0,
Scalar = int(CesiumGltf::PropertyType::Scalar),
Vec2 = int(CesiumGltf::PropertyType::Vec2),
Vec3 = int(CesiumGltf::PropertyType::Vec3),
Vec4 = int(CesiumGltf::PropertyType::Vec4),
Mat2 = int(CesiumGltf::PropertyType::Mat2),
Mat3 = int(CesiumGltf::PropertyType::Mat3),
Mat4 = int(CesiumGltf::PropertyType::Mat4),
Boolean = int(CesiumGltf::PropertyType::Boolean),
Enum = int(CesiumGltf::PropertyType::Enum),
String = int(CesiumGltf::PropertyType::String),
};
/**
* The component type of a metadata property in EXT_structural_metadata. Only
* applicable if the property has a Scalar, VecN, or MatN type.
*/
UENUM(BlueprintType)
enum class ECesiumMetadataComponentType : uint8 {
None = 0,
Int8 = int(CesiumGltf::PropertyComponentType::Int8),
Uint8 = int(CesiumGltf::PropertyComponentType::Uint8),
Int16 = int(CesiumGltf::PropertyComponentType::Int16),
Uint16 = int(CesiumGltf::PropertyComponentType::Uint16),
Int32 = int(CesiumGltf::PropertyComponentType::Int32),
Uint32 = int(CesiumGltf::PropertyComponentType::Uint32),
Int64 = int(CesiumGltf::PropertyComponentType::Int64),
Uint64 = int(CesiumGltf::PropertyComponentType::Uint64),
Float32 = int(CesiumGltf::PropertyComponentType::Float32),
Float64 = int(CesiumGltf::PropertyComponentType::Float64),
};
/**
* Represents the true value type of a metadata value, akin to the property
* types in EXT_structural_metadata.
*/
USTRUCT(BlueprintType)
struct CESIUMRUNTIME_API FCesiumMetadataValueType {
GENERATED_USTRUCT_BODY()
FCesiumMetadataValueType()
: Type(ECesiumMetadataType::Invalid),
ComponentType(ECesiumMetadataComponentType::None),
bIsArray(false) {}
FCesiumMetadataValueType(
ECesiumMetadataType InType,
ECesiumMetadataComponentType InComponentType,
bool IsArray = false)
: Type(InType), ComponentType(InComponentType), bIsArray(IsArray) {}
/**
* The type of the metadata property or value.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
ECesiumMetadataType Type;
/**
* The component of the metadata property or value. Only applies when the type
* is a Scalar, VecN, or MatN type.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium",
Meta =
(EditCondition =
"Type != ECesiumMetadataType::Invalid && Type != ECesiumMetadataType::Boolean && Type != ECesiumMetadataType::Enum && Type != ECesiumMetadataType::String"))
ECesiumMetadataComponentType ComponentType;
/**
* Whether or not this represents an array containing elements of the
* specified types.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
bool bIsArray;
inline bool operator==(const FCesiumMetadataValueType& ValueType) const {
return Type == ValueType.Type && ComponentType == ValueType.ComponentType &&
bIsArray == ValueType.bIsArray;
}
inline bool operator!=(const FCesiumMetadataValueType& ValueType) const {
return Type != ValueType.Type || ComponentType != ValueType.ComponentType ||
bIsArray != ValueType.bIsArray;
}
};
template <typename T>
static FCesiumMetadataValueType TypeToMetadataValueType() {
ECesiumMetadataType type;
ECesiumMetadataComponentType componentType;
bool isArray;
if constexpr (CesiumGltf::IsMetadataArray<T>::value) {
using ArrayType = typename CesiumGltf::MetadataArrayType<T>::type;
type =
ECesiumMetadataType(CesiumGltf::TypeToPropertyType<ArrayType>::value);
componentType = ECesiumMetadataComponentType(
CesiumGltf::TypeToPropertyType<ArrayType>::component);
isArray = true;
} else {
type = ECesiumMetadataType(CesiumGltf::TypeToPropertyType<T>::value);
componentType = ECesiumMetadataComponentType(
CesiumGltf::TypeToPropertyType<T>::component);
isArray = false;
}
return {type, componentType, isArray};
}
/**
* Gets the size in bytes of the represented metadata type. Returns 0 for enums
* and strings.
*/
static size_t GetMetadataTypeByteSize(
ECesiumMetadataType Type,
ECesiumMetadataComponentType ComponentType) {
size_t componentByteSize = 0;
if (ComponentType != ECesiumMetadataComponentType::None)
componentByteSize = CesiumGltf::getSizeOfComponentType(
CesiumGltf::PropertyComponentType(ComponentType));
size_t byteSize = componentByteSize;
switch (Type) {
case ECesiumMetadataType::Boolean:
byteSize = sizeof(bool);
break;
case ECesiumMetadataType::Scalar:
break;
case ECesiumMetadataType::Vec2:
byteSize *= 2;
break;
case ECesiumMetadataType::Vec3:
byteSize *= 3;
break;
case ECesiumMetadataType::Vec4:
byteSize *= 4;
break;
case ECesiumMetadataType::Mat2:
byteSize *= 4;
break;
case ECesiumMetadataType::Mat3:
byteSize *= 9;
break;
case ECesiumMetadataType::Mat4:
byteSize *= 16;
break;
default:
return 0;
}
return byteSize;
}

View File

@ -0,0 +1,158 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumPropertyTable.h"
#include "CesiumPropertyTexture.h"
#include "Containers/Array.h"
#include "Containers/Map.h"
#include "Containers/UnrealString.h"
#include "CesiumModelMetadata.generated.h"
namespace CesiumGltf {
struct ExtensionModelExtStructuralMetadata;
struct Model;
} // namespace CesiumGltf
/**
* @brief A blueprint-accessible wrapper for metadata contained in a glTF model.
* Provides access to views of property tables, property textures, and property
* attributes available on the glTF.
*/
USTRUCT(BlueprintType)
struct CESIUMRUNTIME_API FCesiumModelMetadata {
GENERATED_USTRUCT_BODY()
public:
FCesiumModelMetadata() {}
FCesiumModelMetadata(
const CesiumGltf::Model& InModel,
const CesiumGltf::ExtensionModelExtStructuralMetadata& Metadata);
private:
TArray<FCesiumPropertyTable> _propertyTables;
TArray<FCesiumPropertyTexture> _propertyTextures;
// TODO: property attributes
friend class UCesiumModelMetadataBlueprintLibrary;
};
UCLASS()
class CESIUMRUNTIME_API UCesiumModelMetadataBlueprintLibrary
: public UBlueprintFunctionLibrary {
GENERATED_BODY()
public:
/**
* Gets the model metadata of a glTF primitive component. If component is
* not a Cesium glTF primitive component, the returned metadata is empty.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Model|Metadata")
static const FCesiumModelMetadata&
GetModelMetadata(const UPrimitiveComponent* component);
PRAGMA_DISABLE_DEPRECATION_WARNINGS
/**
* @brief Get all the feature tables for this model metadata.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|Model",
Meta =
(DeprecatedFunction,
DeprecationMessage =
"Use GetPropertyTables to get an array of property tables instead."))
static const TMap<FString, FCesiumPropertyTable>
GetFeatureTables(UPARAM(ref) const FCesiumModelMetadata& ModelMetadata);
/**
* @brief Get all the feature textures for this model metadata.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|Model",
Meta =
(DeprecatedFunction,
DeprecationMessage =
"Use GetPropertyTextures to get an array of property textures instead."))
static const TMap<FString, FCesiumPropertyTexture>
GetFeatureTextures(UPARAM(ref) const FCesiumModelMetadata& ModelMetadata);
PRAGMA_ENABLE_DEPRECATION_WARNINGS
/**
* Gets an array of all the property tables for this model metadata.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Model|Metadata")
static const TArray<FCesiumPropertyTable>&
GetPropertyTables(UPARAM(ref) const FCesiumModelMetadata& ModelMetadata);
/**
* Gets the property table at the specified index for this model metadata. If
* the index is out-of-bounds, this returns an invalid property table.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Model|Metadata")
static const FCesiumPropertyTable& GetPropertyTable(
UPARAM(ref) const FCesiumModelMetadata& ModelMetadata,
const int64 Index);
/**
* Gets the property table at the specified indices for this model metadata.
* An invalid property table will be returned for any out-of-bounds index.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Model|Metadata")
static const TArray<FCesiumPropertyTable> GetPropertyTablesAtIndices(
UPARAM(ref) const FCesiumModelMetadata& ModelMetadata,
const TArray<int64>& Indices);
/**
* Gets an array of all the property textures for this model metadata.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Model|Metadata")
static const TArray<FCesiumPropertyTexture>&
GetPropertyTextures(UPARAM(ref) const FCesiumModelMetadata& ModelMetadata);
/**
* Gets the property table at the specified index for this model metadata. If
* the index is out-of-bounds, this returns an invalid property table.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Model|Metadata")
static const FCesiumPropertyTexture& GetPropertyTexture(
UPARAM(ref) const FCesiumModelMetadata& ModelMetadata,
const int64 Index);
/**
* Gets an array of the property textures at the specified indices for this
* model metadata.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Model|Metadata")
static const TArray<FCesiumPropertyTexture> GetPropertyTexturesAtIndices(
UPARAM(ref) const FCesiumModelMetadata& ModelMetadata,
const TArray<int64>& Indices);
};

View File

@ -0,0 +1,151 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumGlobeAnchoredActorComponent.h"
#include "CoreMinimal.h"
#include "CesiumOriginShiftComponent.generated.h"
class UCesiumGlobeAnchorComponent;
/**
* Indicates how to shift the origin as the Actor to which a
* CesiumOriginShiftComponent is attached moves.
*/
UENUM(BlueprintType)
enum class ECesiumOriginShiftMode : uint8 {
/**
* This component is disabled and will have no effect.
*/
Disabled,
/**
* The origin of the CesiumGeoreference will be changed when the Actor enters
* a new sub-level, but it will otherwise not be modified as the Actor moves.
* Any objects that are not anchored to the globe with a
* CesiumGlobeAnchorComponent will appear to move when the Actor enters a
* sub-level.
*/
SwitchSubLevelsOnly,
/**
* The origin of the CesiumGeoreference will change as the Actor moves in
* order to maintain small, precise coordinate values near the Actor, as well
* as to keep the globe's local "up" direction aligned with the +Z axis. Any
* objects that are not anchored to the globe with a
* CesiumGlobeAnchorComponent will appear to move whenever the origin changes.
*
* When using this mode, all Cesium3DTileset instances as well as any Actors
* with a CesiumGlobeAnchorComponent need to be marked Movable, because these
* objects _will_ be moved when the origin is shifted.
*/
ChangeCesiumGeoreference,
};
/**
* Automatically shifts the origin of the Unreal world coordinate system as the
* object to which this component is attached moves. This improves rendering
* precision by keeping coordinate values small, and can also help world
* building by keeping the globe's local up direction aligned with the +Z axis.
*
* This component is typically attached to a camera or Pawn. By default, it only
* shifts the origin when entering a new sub-level (a Level Instance Actor with
* a CesiumSubLevelComponent attached to it). By changing the Mode and Distance
* properties, it can also shift the origin continually when in between
* sub-levels (or when not using sub-levels at all).
*
* It is essential to add a CesiumGlobeAnchorComponent to all other non-globe
* aware objects in the level; otherwise, they will appear to move when the
* origin is shifted. It is not necessary to anchor objects that are in
* sub-levels, because the origin remains constant for the entire time that a
* sub-level is active.
*/
UCLASS(ClassGroup = "Cesium", Meta = (BlueprintSpawnableComponent))
class CESIUMRUNTIME_API UCesiumOriginShiftComponent
: public UCesiumGlobeAnchoredActorComponent {
GENERATED_BODY()
#pragma region Properties
private:
/**
* Indicates how to shift the origin as the Actor to which this component is
* attached moves.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
BlueprintGetter = GetMode,
BlueprintSetter = SetMode,
Category = "Cesium",
Meta = (AllowPrivateAccess))
ECesiumOriginShiftMode Mode = ECesiumOriginShiftMode::SwitchSubLevelsOnly;
/**
* The maximum distance between the origin of the Unreal coordinate system and
* the Actor to which this component is attached. When this distance is
* exceeded, the origin is shifted to bring it close to the Actor. This
* property is ignored if the Mode property is set to "Disabled" or "Switch
* Sub Levels Only".
*
* When the value of this property is 0.0, the origin is shifted continuously.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
BlueprintGetter = GetDistance,
BlueprintSetter = SetDistance,
Category = "Cesium",
Meta = (AllowPrivateAccess))
double Distance = 0.0;
#pragma endregion
#pragma region Property Accessors
public:
/**
* Gets a value indicating how to shift the origin as the Actor to which this
* component is attached moves.
*/
UFUNCTION(BlueprintGetter)
ECesiumOriginShiftMode GetMode() const;
/**
* Sets a value indicating how to shift the origin as the Actor to which this
* component is attached moves.
*/
UFUNCTION(BlueprintSetter)
void SetMode(ECesiumOriginShiftMode NewMode);
/**
* Gets the maximum distance between the origin of the Unreal coordinate
* system and the Actor to which this component is attached. When this
* distance is exceeded, the origin is shifted to bring it close to the Actor.
* This property is ignored if the Mode property is set to "Disabled" or
* "Switch Sub Levels Only".
*
* When the value of this property is 0.0, the origin is shifted continuously.
*/
UFUNCTION(BlueprintGetter)
double GetDistance() const;
/**
* Sets the maximum distance between the origin of the Unreal coordinate
* system and the Actor to which this component is attached. When this
* distance is exceeded, the origin is shifted to bring it close to the Actor.
* This property is ignored if the Mode property is set to "Disabled" or
* "Switch Sub Levels Only".
*
* When the value of this property is 0.0, the origin is shifted continuously.
*/
UFUNCTION(BlueprintSetter)
void SetDistance(double NewDistance);
#pragma endregion
public:
UCesiumOriginShiftComponent();
protected:
virtual void TickComponent(
float DeltaTime,
ELevelTick TickType,
FActorComponentTickFunction* ThisTickFunction) override;
};

View File

@ -0,0 +1,74 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CoreMinimal.h"
#include "CesiumPointCloudShading.generated.h"
/**
* Options for adjusting how point clouds are rendered using 3D Tiles.
*/
USTRUCT(BlueprintType)
struct CESIUMRUNTIME_API FCesiumPointCloudShading {
GENERATED_USTRUCT_BODY()
/**
* Whether or not to perform point attenuation. Attenuation controls the size
* of the points rendered based on the geometric error of their tile.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
bool Attenuation = false;
/**
* The scale to be applied to the tile's geometric error before it is used
* to compute attenuation. Larger values will result in larger points.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium",
meta = (ClampMin = 0.0))
float GeometricErrorScale = 1.0f;
/**
* The maximum point attenuation in pixels. If this is zero, the
* Cesium3DTileset's maximumScreenSpaceError will be used as the maximum point
* attenuation.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium",
meta = (ClampMin = 0.0))
float MaximumAttenuation = 0.0f;
/**
* The average base resolution for the dataset in meters. For example,
* a base resolution of 0.05 assumes an original capture resolution of
* 5 centimeters between neighboring points.
*
* This is used in place of geometric error when the tile's geometric error is
* 0. If this value is zero, each tile with a geometric error of 0 will have
* its geometric error approximated instead.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium",
meta = (ClampMin = 0.0))
float BaseResolution = 0.0f;
bool
operator==(const FCesiumPointCloudShading& OtherPointCloudShading) const {
return Attenuation == OtherPointCloudShading.Attenuation &&
GeometricErrorScale == OtherPointCloudShading.GeometricErrorScale &&
MaximumAttenuation == OtherPointCloudShading.MaximumAttenuation &&
BaseResolution == OtherPointCloudShading.BaseResolution;
}
bool
operator!=(const FCesiumPointCloudShading& OtherPointCloudShading) const {
return !(*this == OtherPointCloudShading);
}
};

View File

@ -0,0 +1,71 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumRasterOverlay.h"
#include "CoreMinimal.h"
#include "CesiumPolygonRasterOverlay.generated.h"
class ACesiumCartographicPolygon;
namespace Cesium3DTilesSelection {
class RasterizedPolygonsTileExcluder;
}
/**
* A raster overlay that rasterizes polygons and drapes them over the tileset.
* This is useful for clipping out parts of a tileset, for adding a water effect
* in an area, and for many other purposes.
*/
UCLASS(ClassGroup = (Cesium), meta = (BlueprintSpawnableComponent))
class CESIUMRUNTIME_API UCesiumPolygonRasterOverlay
: public UCesiumRasterOverlay {
GENERATED_BODY()
public:
UCesiumPolygonRasterOverlay();
/**
* The polygons to rasterize for this overlay.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
TArray<TSoftObjectPtr<ACesiumCartographicPolygon>> Polygons;
/**
* Whether to invert the selection specified by the polygons.
*
* If this is true, only the areas outside of all the polygons will be
* rasterized.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
bool InvertSelection = false;
/**
* Whether tiles that fall entirely within the rasterized selection should be
* excluded from loading and rendering. For better performance, this should be
* enabled when this overlay will be used for clipping. But when this overlay
* is used for other effects, this option should be disabled to avoid missing
* tiles.
*
* Note that if InvertSelection is true, this will cull tiles that are
* outside of all the polygons. If it is false, this will cull tiles that are
* completely inside at least one polygon.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
bool ExcludeSelectedTiles = true;
protected:
virtual std::unique_ptr<CesiumRasterOverlays::RasterOverlay> CreateOverlay(
const CesiumRasterOverlays::RasterOverlayOptions& options = {}) override;
virtual void OnAdd(
Cesium3DTilesSelection::Tileset* pTileset,
CesiumRasterOverlays::RasterOverlay* pOverlay) override;
virtual void OnRemove(
Cesium3DTilesSelection::Tileset* pTileset,
CesiumRasterOverlays::RasterOverlay* pOverlay) override;
private:
std::shared_ptr<Cesium3DTilesSelection::RasterizedPolygonsTileExcluder>
_pExcluder;
};

View File

@ -0,0 +1,196 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumFeatureIdSet.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "UObject/ObjectMacros.h"
#include <CesiumGltf/AccessorUtility.h>
#include "CesiumPrimitiveFeatures.generated.h"
namespace CesiumGltf {
struct ExtensionExtMeshFeatures;
struct ExtensionExtInstanceFeatures;
} // namespace CesiumGltf
/**
* A Blueprint-accessible wrapper for a glTF Primitive's mesh features. It holds
* views of the feature ID sets associated with this primitive. The collection
* of features in the EXT_instance_features is very similar to that in
* EXT_mesh_features, so FCesiumPrimitiveFeatures can be used to handle those
* features too.
*/
USTRUCT(BlueprintType)
struct CESIUMRUNTIME_API FCesiumPrimitiveFeatures {
GENERATED_USTRUCT_BODY()
public:
/**
* Constructs an empty primitive features instance.
*/
FCesiumPrimitiveFeatures() : _vertexCount(0) {}
/**
* Constructs a primitive features instance.
*
* @param Model The model that contains the EXT_mesh_features extension
* @param Primitive The mesh primitive that stores EXT_mesh_features
* extension
* @param Features The EXT_mesh_features of the glTF mesh primitive
*/
FCesiumPrimitiveFeatures(
const CesiumGltf::Model& Model,
const CesiumGltf::MeshPrimitive& Primitive,
const CesiumGltf::ExtensionExtMeshFeatures& Features);
/**
* Constructs an instance feature object.
*
* @param Model The model that contains the EXT_instance_features extension
* @param Node The node that stores EXT_instance_features
* extension
* @param InstanceFeatures The EXT_Instance_features of the glTF mesh
* primitive
*/
FCesiumPrimitiveFeatures(
const CesiumGltf::Model& Model,
const CesiumGltf::Node& Node,
const CesiumGltf::ExtensionExtInstanceFeatures& InstanceFeatures);
private:
TArray<FCesiumFeatureIdSet> _featureIdSets;
CesiumGltf::IndexAccessorType _indexAccessor;
// Vertex count = 0 and _primitiveMode = -1 indicates instance features
int64_t _vertexCount;
int32_t _primitiveMode;
friend class UCesiumPrimitiveFeaturesBlueprintLibrary;
};
UCLASS()
class CESIUMRUNTIME_API UCesiumPrimitiveFeaturesBlueprintLibrary
: public UBlueprintFunctionLibrary {
GENERATED_BODY()
public:
/**
* Gets the primitive features of a glTF primitive component. If `component`
* is not a Cesium glTF primitive component, the returned features are empty.
*
* @param component The component to get the features of.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Primitive|Features")
static const FCesiumPrimitiveFeatures&
GetPrimitiveFeatures(const UPrimitiveComponent* component);
/**
* Gets all the feature ID sets that are associated with the
* primitive.
*
* @param PrimitiveFeatures The primitive.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Primitive|Features")
static const TArray<FCesiumFeatureIdSet>&
GetFeatureIDSets(UPARAM(ref)
const FCesiumPrimitiveFeatures& PrimitiveFeatures);
/**
* Gets all the feature ID sets of the given type.
*
* @param PrimitiveFeatures The primitive.
* @param Type The type of feature ID set to obtain. If the primitive has no
* sets of that type, the returned array will be empty.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Primitive|Features")
static const TArray<FCesiumFeatureIdSet> GetFeatureIDSetsOfType(
UPARAM(ref) const FCesiumPrimitiveFeatures& PrimitiveFeatures,
ECesiumFeatureIdSetType Type);
/**
* Get the number of vertices in the primitive.
*
* @param PrimitiveFeatures The primitive.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Primitive|Features")
static int64
GetVertexCount(UPARAM(ref) const FCesiumPrimitiveFeatures& PrimitiveFeatures);
/**
* Gets the index of the first vertex that makes up a given face of this
* primitive.
*
* @param PrimitiveFeatures The primitive.
* @param FaceIndex The index of the face.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Primitive|Features")
static int64 GetFirstVertexFromFace(
UPARAM(ref) const FCesiumPrimitiveFeatures& PrimitiveFeatures,
int64 FaceIndex);
/**
* Gets the feature ID associated with the given face.
*
* @param PrimitiveFeatures The primitive.
* @param FaceIndex The index of the face to obtain the feature ID of.
* @param FeatureIDSetIndex A primitive may have multiple feature ID sets, so
* this allows a feature ID set to be specified by index. This value should
* index into the array of CesiumFeatureIdSets in the CesiumPrimitiveFeatures.
* If the specified feature ID set index is invalid, this returns -1.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Primitive|Features")
static int64 GetFeatureIDFromFace(
UPARAM(ref) const FCesiumPrimitiveFeatures& PrimitiveFeatures,
int64 FaceIndex,
int64 FeatureIDSetIndex = 0);
/**
* Gets the feature ID associated with the instance at the given index.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Primitive|Features")
static int64 GetFeatureIDFromInstance(
UPARAM(ref) const FCesiumPrimitiveFeatures& InstanceFeatures,
int64 InstanceIndex,
int64 FeatureIDSetIndex = 0);
/**
* Gets the feature ID from the given line trace hit, assuming it
* has hit a glTF primitive component containing this CesiumPrimitiveFeatures.
*
* @param PrimitiveFeatures The primitive.
* @param Hit The line trace hit to try to obtain a feature ID from.
* @param FeatureIDSetIndex A primitive may have multiple feature ID sets, so
* this allows a feature ID set to be specified by index. This value should
* index into the array of CesiumFeatureIdSets in the CesiumPrimitiveFeatures.
* If the specified feature ID set index is invalid, this returns -1.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Primitive|Features")
static int64 GetFeatureIDFromHit(
UPARAM(ref) const FCesiumPrimitiveFeatures& PrimitiveFeatures,
const FHitResult& Hit,
int64 FeatureIDSetIndex = 0);
};

View File

@ -0,0 +1,91 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "Kismet/BlueprintFunctionLibrary.h"
#include "UObject/ObjectMacros.h"
#include "CesiumPrimitiveMetadata.generated.h"
namespace CesiumGltf {
struct Model;
struct MeshPrimitive;
struct ExtensionModelExtStructuralMetadata;
struct ExtensionMeshPrimitiveExtStructuralMetadata;
} // namespace CesiumGltf
/**
* A Blueprint-accessible wrapper for a glTF Primitive's EXT_structural_metadata
* extension. It holds the indices of the property textures / attributes
* associated with this primitive, which index into the respective arrays in the
* model's EXT_structural_metadata extension.
*/
USTRUCT(BlueprintType)
struct CESIUMRUNTIME_API FCesiumPrimitiveMetadata {
GENERATED_USTRUCT_BODY()
public:
/**
* Construct an empty primitive metadata.
*/
FCesiumPrimitiveMetadata() {}
/**
* Constructs a primitive metadata instance.
*
* @param Primitive The mesh primitive containing the EXT_structural_metadata
* extension
* @param Metadata The EXT_structural_metadata of the glTF mesh primitive.
*/
FCesiumPrimitiveMetadata(
const CesiumGltf::MeshPrimitive& Primitive,
const CesiumGltf::ExtensionMeshPrimitiveExtStructuralMetadata& Metadata);
private:
TArray<int64> _propertyTextureIndices;
TArray<int64> _propertyAttributeIndices;
friend class UCesiumPrimitiveMetadataBlueprintLibrary;
};
UCLASS()
class CESIUMRUNTIME_API UCesiumPrimitiveMetadataBlueprintLibrary
: public UBlueprintFunctionLibrary {
GENERATED_BODY()
public:
/**
* Gets the primitive metadata of a glTF primitive component. If component is
* not a Cesium glTF primitive component, the returned metadata is empty.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Primitive|Metadata")
static const FCesiumPrimitiveMetadata&
GetPrimitiveMetadata(const UPrimitiveComponent* component);
/**
* Get the indices of the property textures that are associated with the
* primitive. This can be used to retrieve the actual property textures from
* the model's FCesiumModelMetadata.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Primitive|Metadata")
static const TArray<int64>& GetPropertyTextureIndices(
UPARAM(ref) const FCesiumPrimitiveMetadata& PrimitiveMetadata);
/**
* Get the indices of the property attributes that are associated with the
* primitive. This can be used to retrieve the actual property attributes from
* the model's FCesiumModelMetadata.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Primitive|Metadata")
static const TArray<int64>& GetPropertyAttributeIndices(
UPARAM(ref) const FCesiumPrimitiveMetadata& PrimitiveMetadata);
};

View File

@ -0,0 +1,155 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumGltf/PropertyArrayView.h"
#include "CesiumGltf/PropertyTypeTraits.h"
#include "CesiumMetadataValueType.h"
#include "UObject/ObjectMacros.h"
#include <swl/variant.hpp>
#include "CesiumPropertyArray.generated.h"
/**
* A Blueprint-accessible wrapper for an array property in glTF metadata.
*/
USTRUCT(BlueprintType)
struct CESIUMRUNTIME_API FCesiumPropertyArray {
GENERATED_USTRUCT_BODY()
private:
#pragma region ArrayType
template <typename T>
using ArrayPropertyView = CesiumGltf::PropertyArrayView<T>;
using ArrayType = swl::variant<
ArrayPropertyView<int8_t>,
ArrayPropertyView<uint8_t>,
ArrayPropertyView<int16_t>,
ArrayPropertyView<uint16_t>,
ArrayPropertyView<int32_t>,
ArrayPropertyView<uint32_t>,
ArrayPropertyView<int64_t>,
ArrayPropertyView<uint64_t>,
ArrayPropertyView<float>,
ArrayPropertyView<double>,
ArrayPropertyView<bool>,
ArrayPropertyView<std::string_view>,
ArrayPropertyView<glm::vec<2, int8_t>>,
ArrayPropertyView<glm::vec<2, uint8_t>>,
ArrayPropertyView<glm::vec<2, int16_t>>,
ArrayPropertyView<glm::vec<2, uint16_t>>,
ArrayPropertyView<glm::vec<2, int32_t>>,
ArrayPropertyView<glm::vec<2, uint32_t>>,
ArrayPropertyView<glm::vec<2, int64_t>>,
ArrayPropertyView<glm::vec<2, uint64_t>>,
ArrayPropertyView<glm::vec<2, float>>,
ArrayPropertyView<glm::vec<2, double>>,
ArrayPropertyView<glm::vec<3, int8_t>>,
ArrayPropertyView<glm::vec<3, uint8_t>>,
ArrayPropertyView<glm::vec<3, int16_t>>,
ArrayPropertyView<glm::vec<3, uint16_t>>,
ArrayPropertyView<glm::vec<3, int32_t>>,
ArrayPropertyView<glm::vec<3, uint32_t>>,
ArrayPropertyView<glm::vec<3, int64_t>>,
ArrayPropertyView<glm::vec<3, uint64_t>>,
ArrayPropertyView<glm::vec<3, float>>,
ArrayPropertyView<glm::vec<3, double>>,
ArrayPropertyView<glm::vec<4, int8_t>>,
ArrayPropertyView<glm::vec<4, uint8_t>>,
ArrayPropertyView<glm::vec<4, int16_t>>,
ArrayPropertyView<glm::vec<4, uint16_t>>,
ArrayPropertyView<glm::vec<4, int32_t>>,
ArrayPropertyView<glm::vec<4, uint32_t>>,
ArrayPropertyView<glm::vec<4, int64_t>>,
ArrayPropertyView<glm::vec<4, uint64_t>>,
ArrayPropertyView<glm::vec<4, float>>,
ArrayPropertyView<glm::vec<4, double>>,
ArrayPropertyView<glm::mat<2, 2, int8_t>>,
ArrayPropertyView<glm::mat<2, 2, uint8_t>>,
ArrayPropertyView<glm::mat<2, 2, int16_t>>,
ArrayPropertyView<glm::mat<2, 2, uint16_t>>,
ArrayPropertyView<glm::mat<2, 2, int32_t>>,
ArrayPropertyView<glm::mat<2, 2, uint32_t>>,
ArrayPropertyView<glm::mat<2, 2, int64_t>>,
ArrayPropertyView<glm::mat<2, 2, uint64_t>>,
ArrayPropertyView<glm::mat<2, 2, float>>,
ArrayPropertyView<glm::mat<2, 2, double>>,
ArrayPropertyView<glm::mat<3, 3, int8_t>>,
ArrayPropertyView<glm::mat<3, 3, uint8_t>>,
ArrayPropertyView<glm::mat<3, 3, int16_t>>,
ArrayPropertyView<glm::mat<3, 3, uint16_t>>,
ArrayPropertyView<glm::mat<3, 3, int32_t>>,
ArrayPropertyView<glm::mat<3, 3, uint32_t>>,
ArrayPropertyView<glm::mat<3, 3, int64_t>>,
ArrayPropertyView<glm::mat<3, 3, uint64_t>>,
ArrayPropertyView<glm::mat<3, 3, float>>,
ArrayPropertyView<glm::mat<3, 3, double>>,
ArrayPropertyView<glm::mat<4, 4, int8_t>>,
ArrayPropertyView<glm::mat<4, 4, uint8_t>>,
ArrayPropertyView<glm::mat<4, 4, int16_t>>,
ArrayPropertyView<glm::mat<4, 4, uint16_t>>,
ArrayPropertyView<glm::mat<4, 4, int32_t>>,
ArrayPropertyView<glm::mat<4, 4, uint32_t>>,
ArrayPropertyView<glm::mat<4, 4, int64_t>>,
ArrayPropertyView<glm::mat<4, 4, uint64_t>>,
ArrayPropertyView<glm::mat<4, 4, float>>,
ArrayPropertyView<glm::mat<4, 4, double>>>;
#pragma endregion
public:
/**
* Constructs an empty array instance with an unknown element type.
*/
FCesiumPropertyArray() : _value(), _elementType() {}
/**
* Constructs an array instance.
* @param value The property array view that will be stored in this struct
*/
template <typename T>
FCesiumPropertyArray(CesiumGltf::PropertyArrayCopy<T>&& value)
: _value(), _elementType(), _storage() {
this->_value = std::move(value).toViewAndExternalBuffer(this->_storage);
ECesiumMetadataType type =
ECesiumMetadataType(CesiumGltf::TypeToPropertyType<T>::value);
ECesiumMetadataComponentType componentType = ECesiumMetadataComponentType(
CesiumGltf::TypeToPropertyType<T>::component);
bool isArray = false;
_elementType = {type, componentType, isArray};
}
template <typename T>
FCesiumPropertyArray(const CesiumGltf::PropertyArrayCopy<T>& value)
: FCesiumPropertyArray(CesiumGltf::PropertyArrayCopy<T>(value)) {}
template <typename T>
FCesiumPropertyArray(const CesiumGltf::PropertyArrayView<T>& value)
: _value(value), _elementType() {
ECesiumMetadataType type =
ECesiumMetadataType(CesiumGltf::TypeToPropertyType<T>::value);
ECesiumMetadataComponentType componentType = ECesiumMetadataComponentType(
CesiumGltf::TypeToPropertyType<T>::component);
bool isArray = false;
_elementType = {type, componentType, isArray};
}
FCesiumPropertyArray(FCesiumPropertyArray&& rhs);
FCesiumPropertyArray& operator=(FCesiumPropertyArray&& rhs);
FCesiumPropertyArray(const FCesiumPropertyArray& rhs);
FCesiumPropertyArray& operator=(const FCesiumPropertyArray& rhs);
private:
template <typename T, typename... VariantType>
static bool
holdsArrayAlternative(const swl::variant<VariantType...>& variant) {
return swl::holds_alternative<CesiumGltf::PropertyArrayView<T>>(variant);
}
ArrayType _value;
FCesiumMetadataValueType _elementType;
std::vector<std::byte> _storage;
friend class UCesiumPropertyArrayBlueprintLibrary;
};

View File

@ -0,0 +1,377 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumMetadataValue.h"
#include "CesiumPropertyArray.h"
#include "CesiumPropertyArrayBlueprintLibrary.generated.h"
/**
* Blueprint library functions for acting on an array property in
* EXT_structural_metadata.
*/
UCLASS()
class CESIUMRUNTIME_API UCesiumPropertyArrayBlueprintLibrary
: public UBlueprintFunctionLibrary {
GENERATED_BODY()
public:
/**
* Gets the best-fitting Blueprints type for the elements of this array.
*
* @param array The array.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyArray")
static ECesiumMetadataBlueprintType
GetElementBlueprintType(UPARAM(ref) const FCesiumPropertyArray& array);
/**
* Gets the true value type of the elements in the array. Many of these types
* are not accessible from Blueprints, but can be converted to a
* Blueprint-accessible type.
*
* @param array The array.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyArray")
static FCesiumMetadataValueType
GetElementValueType(UPARAM(ref) const FCesiumPropertyArray& array);
/**
* Gets the number of elements in the array. Returns 0 if the elements have
* an unknown type.
*
* @param Array The array.
* @return The number of elements in the array.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyArray")
static int64 GetArraySize(UPARAM(ref) const FCesiumPropertyArray& Array);
/**
* Retrieves an element from the array as a FCesiumMetadataValue. The value
* can then be retrieved as a specific Blueprints type.
*
* If the index is out-of-bounds, this returns a bogus FCesiumMetadataValue of
* an unknown type.
*
* @param Array The array.
* @param Index The index of the array element to retrieve.
* @return The element as a FCesiumMetadataValue.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyArray")
static FCesiumMetadataValue
GetValue(UPARAM(ref) const FCesiumPropertyArray& Array, int64 Index);
PRAGMA_DISABLE_DEPRECATION_WARNINGS
/**
* Gets the best-fitting Blueprints type for the elements of this array.
*
* @param array The array.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Meta =
(DeprecatedFunction,
DeprecationMessage = "Use GetElementBlueprintType instead."))
static ECesiumMetadataBlueprintType
GetBlueprintComponentType(UPARAM(ref) const FCesiumPropertyArray& array);
/**
* Gets true type of the elements in the array. Many of these types are not
* accessible from Blueprints, but can be converted to a Blueprint-accessible
* type.
*
* @param array The array.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Meta =
(DeprecatedFunction,
DeprecationMessage =
"CesiumMetadataTrueType is deprecated. Use GetElementValueType instead."))
static ECesiumMetadataTrueType_DEPRECATED
GetTrueComponentType(UPARAM(ref) const FCesiumPropertyArray& array);
/**
* Gets the number of elements in the array. Returns 0 if the elements have
* an unknown type.
*
* @param Array The array.
* @return The number of elements in the array.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Meta =
(DeprecatedFunction,
DeprecationMessage = "Use GetArraySize instead."))
static int64 GetSize(UPARAM(ref) const FCesiumPropertyArray& Array);
/**
* Retrieves an element from the array and attempts to convert it to a Boolean
* value.
*
* If the element is boolean, it is returned directly.
*
* If the element is numeric, zero is converted to false, while any other
* value is converted to true.
*
* If the element is a string, "0", "false", and "no" (case-insensitive) are
* converted to false, while "1", "true", and "yes" are converted to true.
* All other strings, including strings that can be converted to numbers,
* will return the default value.
*
* Other types of elements will return the default value.
*
* @param Array The array.
* @param Index The index of the array element to retrieve.
* @param DefaultValue The default value to use if the index is invalid
* or the element's value cannot be converted.
* @return The element value.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Meta =
(DeprecatedFunction,
DeprecationMessage =
"GetBoolean is deprecated for metadata arrays. Use GetValue instead."))
static bool GetBoolean(
UPARAM(ref) const FCesiumPropertyArray& Array,
int64 Index,
bool DefaultValue = false);
/**
* Retrieves an element from the array and attempts to convert it to an
* unsigned 8-bit integer value.
*
* If the element is an integer and between 0 and 255, it is returned
* directly.
*
* If the element is a floating-point number, it is truncated (rounded
* toward zero).
*
* If the element is a boolean, 0 is returned for false and 1 for true.
*
* If the element is a string and the entire string can be parsed as an
* integer between 0 and 255, the parsed value is returned. The string is
* parsed in a locale-independent way and does not support use of a comma or
* other character to group digits.
*
* Otherwise, the default value is returned.
*
* @param Array The array.
* @param Index The index of the array element to retrieve.
* @param DefaultValue The default value to use if the index is invalid
* or the element's value cannot be converted.
* @return The element value.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Meta =
(DeprecatedFunction,
DeprecationMessage =
"GetByte is deprecated on arrays. Use GetValue instead."))
static uint8 GetByte(
UPARAM(ref) const FCesiumPropertyArray& Array,
int64 Index,
uint8 DefaultValue = 0);
/**
* Retrieves an element from the array and attempts to convert it to a signed
* 32-bit integer value.
*
* If the element is an integer and between -2,147,483,647 and 2,147,483,647,
* it is returned directly.
*
* If the element is a floating-point number, it is truncated (rounded
* toward zero).
*
* If the element is a boolean, 0 is returned for false and 1 for true.
*
* If the element is a string and the entire string can be parsed as an
* integer in the valid range, the parsed value is returned. If it can be
* parsed as a floating-point number, the parsed value is truncated (rounded
* toward zero). In either case, the string is parsed in a locale-independent
* way and does not support use of a comma or other character to group digits.
*
* Otherwise, the default value is returned.
*
* @param Array The array.
* @param Index The index of the array element to retrieve.
* @param DefaultValue The default value to use if the index is invalid
* or the element's value cannot be converted.
* @return The element value.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Meta =
(DeprecatedFunction,
DeprecationMessage =
"GetInteger is deprecated for metadata arrays. Use GetValue instead."))
static int32 GetInteger(
UPARAM(ref) const FCesiumPropertyArray& Array,
int64 Index,
int32 DefaultValue = 0);
/**
* This function is deprecated. Use Cesium > Metadata > Property Array >
* GetValue instead.
*
* Retrieves an element from the array and attempts to convert it to a signed
* 64-bit integer value.
*
* If the element is an integer and between -2^63-1 and 2^63-1, it is returned
* directly.
*
* If the element is a floating-point number, it is truncated (rounded
* toward zero).
*
* If the element is a boolean, 0 is returned for false and 1 for true.
*
* If the element is a string and the entire string can be parsed as an
* integer in the valid range, the parsed value is returned. If it can be
* parsed as a floating-point number, the parsed value is truncated (rounded
* toward zero). In either case, the string is parsed in a locale-independent
* way and does not support use of a comma or other character to group digits.
*
* Otherwise, the default value is returned.
*
* @param Array The array.
* @param Index The index of the array element to retrieve.
* @param DefaultValue The default value to use if the index is invalid
* or the element's value cannot be converted.
* @return The element value.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Meta =
(DeprecatedFunction,
DeprecationMessage =
"GetInteger64 is deprecated for metadata arrays. Use GetValue instead."))
static int64 GetInteger64(
UPARAM(ref) const FCesiumPropertyArray& Array,
int64 Index,
int64 DefaultValue = 0);
/**
* Retrieves an element from the array and attempts to convert it to a 32-bit
* floating-point value.
*
* If the element is a single-precision floating-point number, is is returned.
*
* If the element is an integer or double-precision floating-point number,
* it is converted to the closest representable single-precision
* floating-point number.
*
* If the element is a boolean, 0.0 is returned for false and 1.0 for true.
*
* If the element is a string and the entire string can be parsed as a
* number, the parsed value is returned. The string is parsed in a
* locale-independent way and does not support use of a comma or other
* character to group digits.
*
* Otherwise, the default value is returned.
*
* @param array The array.
* @param index The index of the array element to retrieve.
* @param DefaultValue The default value to use if the index is invalid
* or the element's value cannot be converted.
* @return The element value.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Meta =
(DeprecatedFunction,
DeprecationMessage =
"GetFloat is deprecated for metadata arrays. Use GetValue instead."))
static float GetFloat(
UPARAM(ref) const FCesiumPropertyArray& array,
int64 index,
float DefaultValue = 0.0f);
/**
* Retrieves an element from the array and attempts to convert it to a 64-bit
* floating-point value.
*
* If the element is a single- or double-precision floating-point number, is
* is returned.
*
* If the element is an integer, it is converted to the closest representable
* double-precision floating-point number.
*
* If the element is a boolean, 0.0 is returned for false and 1.0 for true.
*
* If the element is a string and the entire string can be parsed as a
* number, the parsed value is returned. The string is parsed in a
* locale-independent way and does not support use of a comma or other
* character to group digits.
*
* Otherwise, the default value is returned.
*
* @param array The array.
* @param index The index of the array element to retrieve.
* @param DefaultValue The default value to use if the index is invalid
* or the element's value cannot be converted.
* @return The element value.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Meta =
(DeprecatedFunction,
DeprecationMessage =
"GetFloat64 is deprecated for metadata arrays. Use GetValue instead."))
static double GetFloat64(
UPARAM(ref) const FCesiumPropertyArray& array,
int64 index,
double DefaultValue);
/**
* Retrieves an element from the array and attempts to convert it to a string
* value.
*
* Numeric elements are converted to a string with `FString::Format`, which
* uses the current locale.
*
* Boolean elements are converted to "true" or "false".
*
* String elements are returned directly.
*
* @param Array The array.
* @param Index The index of the array element to retrieve.
* @param DefaultValue The default value to use if the index is invalid
* or the element's value cannot be converted.
* @return The element value.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Meta =
(DeprecatedFunction,
DeprecationMessage =
"GetString is deprecated for metadata arrays. Use GetValue instead."))
static FString GetString(
UPARAM(ref) const FCesiumPropertyArray& Array,
int64 Index,
const FString& DefaultValue = "");
PRAGMA_ENABLE_DEPRECATION_WARNINGS
};

View File

@ -0,0 +1,204 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumMetadataValue.h"
#include "CesiumPropertyTableProperty.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "UObject/ObjectMacros.h"
#include "CesiumPropertyTable.generated.h"
namespace CesiumGltf {
struct Model;
struct PropertyTable;
} // namespace CesiumGltf
/**
* @brief Reports the status of a FCesiumPropertyTable. If the property table
* cannot be accessed, this briefly indicates why.
*/
UENUM(BlueprintType)
enum class ECesiumPropertyTableStatus : uint8 {
/* The property table is valid. */
Valid = 0,
/* The property table instance was not initialized from an actual glTF
property table. */
ErrorInvalidPropertyTable,
/* The property table's class could be found in the schema of the metadata
extension. */
ErrorInvalidPropertyTableClass
};
/**
* A Blueprint-accessible wrapper for a glTF property table. A property table is
* a collection of properties for the features in a mesh. It knows how to
* look up the metadata values associated with a given feature ID.
*/
USTRUCT(BlueprintType)
struct CESIUMRUNTIME_API FCesiumPropertyTable {
GENERATED_USTRUCT_BODY()
public:
/**
* Construct an empty property table instance.
*/
FCesiumPropertyTable()
: _status(ECesiumPropertyTableStatus::ErrorInvalidPropertyTable){};
/**
* Constructs a property table from a glTF Property Table.
*
* @param Model The model that stores EXT_structural_metadata.
* @param PropertyTable The target property table.
*/
FCesiumPropertyTable(
const CesiumGltf::Model& Model,
const CesiumGltf::PropertyTable& PropertyTable);
/**
* Gets the name of the metadata class that this property table conforms to.
*/
FString getClassName() const { return _className; }
private:
ECesiumPropertyTableStatus _status;
FString _name;
FString _className;
int64 _count;
TMap<FString, FCesiumPropertyTableProperty> _properties;
friend class UCesiumPropertyTableBlueprintLibrary;
};
UCLASS()
class CESIUMRUNTIME_API UCesiumPropertyTableBlueprintLibrary
: public UBlueprintFunctionLibrary {
GENERATED_BODY()
public:
/**
* Gets the status of the property table. If an error occurred while parsing
* the property table from the glTF extension, this briefly conveys why.
*
* @param PropertyTable The property table.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTable")
static ECesiumPropertyTableStatus
GetPropertyTableStatus(UPARAM(ref) const FCesiumPropertyTable& PropertyTable);
/**
* Gets the name of the property table. If no name was specified in the glTF
* extension, this returns an empty string.
*
* @param PropertyTable The property table.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTable")
static const FString&
GetPropertyTableName(UPARAM(ref) const FCesiumPropertyTable& PropertyTable);
/**
* Gets the number of values each property in the table is expected to have.
* If an error occurred while parsing the property table, this returns zero.
*
* @param PropertyTable The property table.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTable")
static int64
GetPropertyTableCount(UPARAM(ref) const FCesiumPropertyTable& PropertyTable);
/**
* Gets all the properties of the property table, mapped by property name.
*
* @param PropertyTable The property table.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTable")
static const TMap<FString, FCesiumPropertyTableProperty>&
GetProperties(UPARAM(ref) const FCesiumPropertyTable& PropertyTable);
/**
* Gets the names of the properties in this property table.
*
* @param PropertyTable The property table.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTable")
static const TArray<FString>
GetPropertyNames(UPARAM(ref) const FCesiumPropertyTable& PropertyTable);
/**
* Retrieve a FCesiumPropertyTableProperty by name. If the property table
* does not contain a property with that name, this returns an invalid
* FCesiumPropertyTableProperty.
*
* @param PropertyTable The property table.
* @param PropertyName The name of the property to find.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTable")
static const FCesiumPropertyTableProperty& FindProperty(
UPARAM(ref) const FCesiumPropertyTable& PropertyTable,
const FString& PropertyName);
/**
* Gets all of the property values for a given feature, mapped by property
* name. This will only include values from valid property table properties.
*
* If the feature ID is out-of-bounds, the returned map will be empty.
*
* @param PropertyTable The property table.
* @param FeatureID The ID of the feature.
* @return The property values mapped by property name.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTable")
static TMap<FString, FCesiumMetadataValue> GetMetadataValuesForFeature(
UPARAM(ref) const FCesiumPropertyTable& PropertyTable,
int64 FeatureID);
PRAGMA_DISABLE_DEPRECATION_WARNINGS
/**
* Gets all of the property values for a given feature as strings, mapped by
* property name. This will only include values from valid property table
* properties.
*
* Array properties cannot be converted to strings, so empty strings
* will be returned for their values.
*
* If the feature ID is out-of-bounds, the returned map will be empty.
*
* @param PropertyTable The property table.
* @param FeatureID The ID of the feature.
* @return The property values as strings mapped by property name.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTable",
Meta =
(DeprecatedFunction,
DeprecationMessage =
"Use GetValuesAsStrings to convert the output of GetMetadataValuesForFeature instead."))
static TMap<FString, FString> GetMetadataValuesForFeatureAsStrings(
UPARAM(ref) const FCesiumPropertyTable& PropertyTable,
int64 FeatureID);
PRAGMA_ENABLE_DEPRECATION_WARNINGS
};

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,178 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumGltf/PropertyTextureView.h"
#include "CesiumPropertyTextureProperty.h"
#include "Containers/Array.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "Kismet/GameplayStatics.h"
#include "CesiumPropertyTexture.generated.h"
namespace CesiumGltf {
struct Model;
struct PropertyTexture;
}; // namespace CesiumGltf
UENUM(BlueprintType)
enum class ECesiumPropertyTextureStatus : uint8 {
/* The property texture is valid. */
Valid = 0,
/* The property texture instance was not initialized from an actual glTF
property texture. */
ErrorInvalidPropertyTexture,
/* The property texture's class could be found in the schema of the metadata
extension. */
ErrorInvalidPropertyTextureClass
};
/**
* @brief A blueprint-accessible wrapper of a property texture from a glTF.
* Provides access to {@link FCesiumPropertyTextureProperty} views of texture
* metadata.
*/
USTRUCT(BlueprintType)
struct CESIUMRUNTIME_API FCesiumPropertyTexture {
GENERATED_USTRUCT_BODY()
public:
FCesiumPropertyTexture()
: _status(ECesiumPropertyTextureStatus::ErrorInvalidPropertyTexture) {}
FCesiumPropertyTexture(
const CesiumGltf::Model& model,
const CesiumGltf::PropertyTexture& PropertyTexture);
/**
* Gets the name of the metadata class that this property table conforms to.
*/
FString getClassName() const { return _className; }
private:
ECesiumPropertyTextureStatus _status;
FString _name;
FString _className;
TMap<FString, FCesiumPropertyTextureProperty> _properties;
friend class UCesiumPropertyTextureBlueprintLibrary;
};
UCLASS()
class CESIUMRUNTIME_API UCesiumPropertyTextureBlueprintLibrary
: public UBlueprintFunctionLibrary {
GENERATED_BODY()
public:
/**
* Gets the status of the property texture. If the property texture is invalid
* in any way, this briefly indicates why.
*
* @param PropertyTexture The property texture.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTexture")
static const ECesiumPropertyTextureStatus
GetPropertyTextureStatus(UPARAM(ref)
const FCesiumPropertyTexture& PropertyTexture);
/**
* Gets the name of the property texture.
*
* @param PropertyTexture The property texture.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTexture")
static const FString&
GetPropertyTextureName(UPARAM(ref)
const FCesiumPropertyTexture& PropertyTexture);
/**
* Gets all the properties of the property texture, mapped by property name.
*
* @param PropertyTexture The property texture.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTexture")
static const TMap<FString, FCesiumPropertyTextureProperty>
GetProperties(UPARAM(ref) const FCesiumPropertyTexture& PropertyTexture);
/**
* Gets the names of the properties in this property texture. If the property
* texture is invalid, this returns an empty array.
*
* @param PropertyTexture The property texture.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTexture")
static const TArray<FString>
GetPropertyNames(UPARAM(ref) const FCesiumPropertyTexture& PropertyTexture);
/**
* Retrieve a FCesiumPropertyTextureProperty by name. If the property texture
* does not contain a property with that name, this returns an invalid
* FCesiumPropertyTextureProperty.
*
* @param PropertyTexture The property texture.
* @param PropertyName The name of the property to find.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTexture")
static const FCesiumPropertyTextureProperty& FindProperty(
UPARAM(ref) const FCesiumPropertyTexture& PropertyTexture,
const FString& PropertyName);
/**
* Gets all of the property values at the given texture coordinates, mapped by
* property name. This will only include values from valid property texture
* properties.
*
* In EXT_structural_metadata, individual properties can specify different
* texture coordinate sets to be sampled from. This method uses the same
* coordinates to sample each property, regardless of its intended texture
* coordinate set. Use GetMetadataValuesForHit instead to sample the property
* texture's properties with their respective texture coordinate sets.
*
* @param PropertyTexture The property texture.
* @param UV The texture coordinates.
* @return The property values mapped by property name.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTexture")
static TMap<FString, FCesiumMetadataValue> GetMetadataValuesForUV(
UPARAM(ref) const FCesiumPropertyTexture& PropertyTexture,
const FVector2D& UV);
/**
* Given a trace hit result, gets all of the property values from property
* texture on the hit component, mapped by property name. This will only
* include values from valid property texture properties.
*
* In EXT_structural_metadata, individual properties can specify different
* texture coordinate sets to be sampled from. This method uses the
* corresponding texture coordinate sets to sample each property.
*
* @param PropertyTexture The property texture.
* @param Hit The trace hit result
* @return The property values mapped by property name.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTexture")
static TMap<FString, FCesiumMetadataValue> GetMetadataValuesFromHit(
UPARAM(ref) const FCesiumPropertyTexture& PropertyTexture,
const FHitResult& Hit);
};

View File

@ -0,0 +1,842 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumMetadataValue.h"
#include "GenericPlatform/GenericPlatform.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include <CesiumGltf/KhrTextureTransform.h>
#include <CesiumGltf/PropertyTexturePropertyView.h>
#include <any>
#include <optional>
#include "CesiumPropertyTextureProperty.generated.h"
/**
* @brief Reports the status of a FCesiumPropertyTextureProperty. If the
* property texture property cannot be accessed, this briefly indicates why.
*/
UENUM(BlueprintType)
enum class ECesiumPropertyTexturePropertyStatus : uint8 {
/* The property texture property is valid. */
Valid = 0,
/* The property texture property is empty but has a specified default value.
*/
EmptyPropertyWithDefault,
/* The property texture property does not exist in the glTF, or the property
definition itself contains errors. */
ErrorInvalidProperty,
/* The data associated with the property texture property is malformed and
cannot be retrieved. */
ErrorInvalidPropertyData,
/* The type of this property texture property is not supported. */
ErrorUnsupportedProperty
};
/**
* @brief A blueprint-accessible wrapper for a property texture property from a
* glTF. Provides per-pixel access to metadata encoded in a property texture.
*/
USTRUCT(BlueprintType)
struct CESIUMRUNTIME_API FCesiumPropertyTextureProperty {
GENERATED_USTRUCT_BODY()
public:
FCesiumPropertyTextureProperty()
: _status(ECesiumPropertyTexturePropertyStatus::ErrorInvalidProperty),
_property(),
_valueType(),
_normalized(false) {}
template <typename T, bool Normalized>
FCesiumPropertyTextureProperty(
const CesiumGltf::PropertyTexturePropertyView<T, Normalized>& Property)
: _status(ECesiumPropertyTexturePropertyStatus::ErrorInvalidProperty),
_property(Property),
_valueType(),
_normalized(Normalized) {
switch (Property.status()) {
case CesiumGltf::PropertyTexturePropertyViewStatus::Valid:
_status = ECesiumPropertyTexturePropertyStatus::Valid;
break;
case CesiumGltf::PropertyTexturePropertyViewStatus::
EmptyPropertyWithDefault:
_status = ECesiumPropertyTexturePropertyStatus::EmptyPropertyWithDefault;
break;
case CesiumGltf::PropertyTexturePropertyViewStatus::
ErrorUnsupportedProperty:
_status = ECesiumPropertyTexturePropertyStatus::ErrorUnsupportedProperty;
return;
case CesiumGltf::PropertyTexturePropertyViewStatus::
ErrorInvalidPropertyTexture:
case CesiumGltf::PropertyTexturePropertyViewStatus::
ErrorNonexistentProperty:
case CesiumGltf::PropertyTexturePropertyViewStatus::ErrorTypeMismatch:
case CesiumGltf::PropertyTexturePropertyViewStatus::
ErrorComponentTypeMismatch:
case CesiumGltf::PropertyTexturePropertyViewStatus::ErrorArrayTypeMismatch:
case CesiumGltf::PropertyTexturePropertyViewStatus::
ErrorInvalidNormalization:
case CesiumGltf::PropertyTexturePropertyViewStatus::
ErrorNormalizationMismatch:
case CesiumGltf::PropertyTexturePropertyViewStatus::ErrorInvalidOffset:
case CesiumGltf::PropertyTexturePropertyViewStatus::ErrorInvalidScale:
case CesiumGltf::PropertyTexturePropertyViewStatus::ErrorInvalidMax:
case CesiumGltf::PropertyTexturePropertyViewStatus::ErrorInvalidMin:
case CesiumGltf::PropertyTexturePropertyViewStatus::ErrorInvalidNoDataValue:
case CesiumGltf::PropertyTexturePropertyViewStatus::
ErrorInvalidDefaultValue:
// The status was already set in the initializer list.
return;
default:
_status = ECesiumPropertyTexturePropertyStatus::ErrorInvalidPropertyData;
return;
}
_valueType = TypeToMetadataValueType<T>();
_normalized = Normalized;
}
const int64 getTexCoordSetIndex() const;
const CesiumGltf::Sampler* getSampler() const;
const CesiumGltf::ImageAsset* getImage() const;
const std::optional<CesiumGltf::KhrTextureTransform>
getTextureTransform() const;
private:
ECesiumPropertyTexturePropertyStatus _status;
std::any _property;
FCesiumMetadataValueType _valueType;
bool _normalized;
friend class UCesiumPropertyTexturePropertyBlueprintLibrary;
};
UCLASS()
class CESIUMRUNTIME_API UCesiumPropertyTexturePropertyBlueprintLibrary
: public UBlueprintFunctionLibrary {
GENERATED_BODY()
public:
/**
* Gets the status of the property texture property. If this property texture
* property is invalid in any way, this will briefly indicate why.
*
* @param Property The property texture property.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTextureProperty")
static ECesiumPropertyTexturePropertyStatus GetPropertyTexturePropertyStatus(
UPARAM(ref) const FCesiumPropertyTextureProperty& Property);
/**
* Gets the best-fitting type for the property that is accessible from
* Blueprints. For the most precise representation of the values possible in
* Blueprints, you should retrieve it using this type.
*
* @param Property The property texture property.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTextureProperty")
static ECesiumMetadataBlueprintType
GetBlueprintType(UPARAM(ref) const FCesiumPropertyTextureProperty& Property);
/**
* Gets the best-fitting Blueprints type for the elements in this property's
* array values. If the given property does not contain array values, this
* returns None.
*
* @param Property The property texture property.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTextureProperty")
static ECesiumMetadataBlueprintType GetArrayElementBlueprintType(
UPARAM(ref) const FCesiumPropertyTextureProperty& Property);
/**
* Gets the type of the metadata value as defined in the
* EXT_structural_metadata extension. Many of these types are not accessible
* from Blueprints, but can be converted to a Blueprint-accessible type.
*
* @param Property The property texture property.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTextureProperty")
static FCesiumMetadataValueType
GetValueType(UPARAM(ref) const FCesiumPropertyTextureProperty& Property);
/**
* Gets the number of elements in an array of this property. Only
* applicable when the property is a fixed-length array type.
*
* @param Property The property texture property.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTextureProperty")
static int64 GetArraySize(UPARAM(ref)
const FCesiumPropertyTextureProperty& Property);
/**
* Gets the glTF texture coordinate set index used by the property texture
* property. This is the index N corresponding to the "TEXCOORD_N" attribute
* on the glTF primitive that samples this texture.
*
* If the property texture property is invalid, this returns -1.
*
* @param Property The property texture property.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTextureProperty")
static int64 GetGltfTextureCoordinateSetIndex(
UPARAM(ref) const FCesiumPropertyTextureProperty& Property);
/**
* Gets the UV channel containing the texture coordinate set that is used by
* the property texture property on the given component. This refers to the UV
* channel it uses on the primitive's static mesh, which is not necessarily
* equal to value of GetGltfTextureCoordinateSetIndex.
*
* This function may be used with FindCollisionUV to get the feature ID from a
* line trace hit. However, in order for this function to work, the feature ID
* texture should be listed under the CesiumFeaturesMetadataComponent of the
* owner Cesium3DTileset. Otherwise, its texture coordinate set may not be
* included in the Unreal mesh data. To avoid using
* CesiumFeaturesMetadataComponent, use GetFeatureIDFromHit instead.
*
* This returns -1 if the property texture property is invalid, or if the
* specified texture coordinate set is not present in the component's mesh
* data.
*
* @param Component The component to get the texture coordinate set from.
* @param Property The property texture property.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTextureProperty")
static int64 GetUnrealUVChannel(
const UPrimitiveComponent* Component,
UPARAM(ref) const FCesiumPropertyTextureProperty& Property);
/**
* @brief Get the channels array of this property. This contains the indices
* of the meaningful texel channels that will be used when sampling the
* property texture.
*
* @param Property The property texture property.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTextureProperty")
static TArray<int64>
GetChannels(UPARAM(ref) const FCesiumPropertyTextureProperty& Property);
/**
* Attempts to retrieve the value at the given texture coordinates as an
* unsigned 8-bit integer.
*
* For numeric properties, the raw value for the given coordinates will be
* transformed by the property's normalization, scale, and offset before it is
* further converted. If the raw value is equal to the property's "no data"
* value, then the property's default value will be converted if possible. If
* the property-defined default value cannot be converted, or does not exist,
* then the user-defined default value is returned.
*
* Property values are converted as follows:
*
* - If the value is an integer between 0 and 255, it is returned as-is.
* - If the value is a floating-point number in the aforementioned range, it
* is truncated (rounded toward zero) and returned.
*
* In all other cases, the user-defined default value is returned. If the
* property texture property is somehow invalid, the user-defined default
* value is returned.
*
* @param Property The property texture property.
* @param UV The texture coordinates.
* @param DefaultValue The default value to fall back on.
* @return The property value as a Byte.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTextureProperty")
static uint8 GetByte(
UPARAM(ref) const FCesiumPropertyTextureProperty& Property,
const FVector2D& UV,
uint8 DefaultValue = 0);
/**
* Attempts to retrieve the value at the given texture coordinates as a signed
* 32-bit integer.
*
* For numeric properties, the raw value for the given coordinates will be
* transformed by the property's normalization, scale, and offset before it is
* further converted. If the raw value is equal to the property's "no data"
* value, then the property's default value will be converted if
* possible. If the property-defined default value cannot be converted, or
* does not exist, then the user-defined default value is returned.
*
* Property values are converted as follows:
*
* - If the value is an integer between -2,147,483,648 and 2,147,483,647, it
* is returned as-is.
* - If the value is a floating-point number in the aforementioned range, it
* is truncated (rounded toward zero) and returned.
*
* In all other cases, the user-defined default value is returned. If the
* property texture property is somehow invalid, the user-defined default
* value is returned.
*
* @param Property The property texture property.
* @param UV The texture coordinates.
* @param DefaultValue The default value to fall back on.
* @return The property value as an Integer.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTextureProperty")
static int32 GetInteger(
UPARAM(ref) const FCesiumPropertyTextureProperty& Property,
const FVector2D& UV,
int32 DefaultValue = 0);
/**
* Attempts to retrieve the value at the given texture coordinates as a
* single-precision floating-point number.
*
* For numeric properties, the raw value for the given coordinates will be
* transformed by the property's normalization, scale, and offset before it is
* further converted. If the raw value is equal to the property's "no data"
* value, then the property's default value will be converted if possible. If
* the property-defined default value cannot be converted, or does not exist,
* then the user-defined default value is returned.
*
* Property values are converted as follows:
*
* - If the value is already a single-precision floating-point
* number, it is returned as-is.
*
* - If the value is a scalar of any other type within the range of values
* that a single-precision float can represent, it is converted to its closest
* representation as a single-precision float and returned.
*
* In all other cases, the user-defined default value is returned. If the
* property texture property is somehow invalid, the user-defined default
* value is returned.
*
* @param Property The property texture property.
* @param UV The texture coordinates.
* @param DefaultValue The default value to fall back on.
* @return The property value as a Float.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTextureProperty")
static float GetFloat(
UPARAM(ref) const FCesiumPropertyTextureProperty& Property,
const FVector2D& UV,
float DefaultValue = 0.0f);
/**
* Attempts to retrieve the value at the given texture coordinates as a
* double-precision floating-point number.
*
* For numeric properties, the raw value for the given coordinates will be
* transformed by the property's normalization, scale, and offset before it is
* further converted. If the raw value is equal to the property's "no data"
* value, then the property's default value will be converted if possible. If
* the property-defined default value cannot be converted, or does not exist,
* then the user-defined default value is returned.
*
* Property values are converted as follows:
*
* - If the value is a single- or double-precision floating-point number, it
* is returned as-is.
*
* - If the value is an integer, it is converted to the closest representable
* double-precision floating-point number.
*
* In all other cases, the user-defined default value is returned. If the
* property texture property is somehow invalid, the user-defined default
* value is returned.
*
* @param Property The property texture property.
* @param UV The texture coordinates.
* @param DefaultValue The default value to fall back on.
* @return The property value as a Float.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTextureProperty")
static double GetFloat64(
UPARAM(ref) const FCesiumPropertyTextureProperty& Property,
const FVector2D& UV,
double DefaultValue = 0.0);
/**
* Attempts to retrieve the value at the given texture coordinates as a
* FIntPoint.
*
* For numeric properties, the raw value for the given coordinates will be
* transformed by the property's normalization, scale, and offset before it is
* further converted. If the raw value is equal to the property's "no data"
* value, then the property's default value will be converted if possible. If
* the property-defined default value cannot be converted, or does not exist,
* then the user-defined default value is returned.
*
* Property values are converted as follows:
*
* - If the value is a 2-dimensional vector, its components will be converted
* to 32-bit signed integers if possible.
*
* - If the value is a 3- or 4-dimensional vector, it will use the first two
* components to construct the FIntPoint.
*
* - If the value is a scalar that can be converted to a 32-bit signed
* integer, the resulting FIntPoint will have this value in both of its
* components.
*
* In all other cases, the user-defined default value is returned. In all
* vector cases, if any of the relevant components cannot be represented as a
* 32-bit signed, the default value is returned.
*
* If the property texture property is somehow invalid, the user-defined
* default value is returned.
*
* @param Property The property texture property.
* @param UV The texture coordinates.
* @param DefaultValue The default value to fall back on.
* @return The property value as a FIntPoint.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTextureProperty")
static FIntPoint GetIntPoint(
UPARAM(ref) const FCesiumPropertyTextureProperty& Property,
const FVector2D& UV,
const FIntPoint& DefaultValue);
/**
* Attempts to retrieve the value at the given texture coordinates as a
* FVector2D.
*
* For numeric properties, the raw value for the given coordinates will be
* transformed by the property's normalization, scale, and offset before it is
* further converted. If the raw value is equal to the property's "no data"
* value, then the property's default value will be converted if possible. If
* the property-defined default value cannot be converted, or does not exist,
* then the user-defined default value is returned.
*
* Property values are converted as follows:
*
* - If the value is a 2-dimensional vector, its components will be converted
* to double-precision floating-point numbers.
*
* - If the value is a 3- or 4-dimensional vector, it will use the first two
* components to construct the FVector2D.
*
* - If the value is a scalar that can be converted to a 32-bit signed
* integer, the resulting FVector2D will have this value in both of its
* components.
*
* In all other cases, the user-defined default value is returned. If the
* property texture property is somehow invalid, the user-defined default
* value is returned.
*
* @param Property The property texture property.
* @param UV The texture coordinates.
* @param DefaultValue The default value to fall back on.
* @return The property value as a FVector2D.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTextureProperty")
static FVector2D GetVector2D(
UPARAM(ref) const FCesiumPropertyTextureProperty& Property,
const FVector2D& UV,
const FVector2D& DefaultValue);
/**
* Attempts to retrieve the value at the given texture coordinates as a
* FIntVector.
*
* For numeric properties, the raw value for the given coordinates will be
* transformed by the property's normalization, scale, and offset before it is
* further converted. If the raw value is equal to the property's "no data"
* value, then the property's default value will be converted if possible. If
* the property-defined default value cannot be converted, or does not exist,
* then the user-defined default value is returned.
*
* Property values are converted as follows:
*
* - If the value is a 3-dimensional vector, its components will be converted
* to 32-bit signed integers if possible.
*
* - If the value is a 4-dimensional vector, it will use the first three
* components to construct the FIntVector.
*
* - If the value is a 2-dimensional vector, it will become the XY-components
* of the FIntVector. The Z component will be set to zero.
*
* - If the value is a scalar that can be converted to a 32-bit signed
* integer, the resulting FIntVector will have this value in all of its
* components.
*
* In all other cases, the user-defined default value is returned. In all
* vector cases, if any of the relevant components cannot be represented as a
* 32-bit signed integer, the default value is returned.
*
* If the property texture property is somehow invalid, the user-defined
* default value is returned.
*
* @param Property The property texture property.
* @param UV The texture coordinates.
* @param DefaultValue The default value to fall back on.
* @return The property value as a FIntVector.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTextureProperty")
static FIntVector GetIntVector(
UPARAM(ref) const FCesiumPropertyTextureProperty& Property,
const FVector2D& UV,
const FIntVector& DefaultValue);
/**
* Attempts to retrieve the value at the given texture coordinates as a
* FVector.
*
* For numeric properties, the raw value for the given coordinates will be
* transformed by the property's normalization, scale, and offset before it is
* further converted. If the raw value is equal to the property's "no data"
* value, then the property's default value will be converted if possible. If
* the property-defined default value cannot be converted, or does not exist,
* then the user-defined default value is returned.
*
* Property values are converted as follows:
*
* - If the value is a 3-dimensional vector, its components will be converted
* to double-precision floating-point numbers.
*
* - If the value is a 4-dimensional vector, a FVector containing the first
* three components will be returned.
*
* - If the value is a 2-dimensional vector, it will become the XY-components
* of the FVector. The Z-component will be set to zero.
*
* - If the value is a scalar, then the resulting FVector will have this value
* as a double-precision floating-point number in all of its components.
*
* In all other cases, the user-defined default value is returned. In all
* vector cases, if any of the relevant components cannot be represented as a
* single-precision float, the default value is returned.
*
* If the property texture property is somehow invalid, the user-defined
* default value is returned.
*
* @param Property The property texture property.
* @param UV The texture coordinates.
* @param DefaultValue The default value to fall back on.
* @return The property value as a FVector.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTextureProperty")
static FVector GetVector(
UPARAM(ref) const FCesiumPropertyTextureProperty& Property,
const FVector2D& UV,
const FVector& DefaultValue);
/**
* Attempts to retrieve the value at the given texture coordinates as a
* FVector4.
*
* For numeric properties, the raw value for the given coordinates will be
* transformed by the property's normalization, scale, and offset before it is
* further converted. If the raw value is equal to the property's "no data"
* value, then the property's default value will be converted if possible. If
* the property-defined default value cannot be converted, or does not exist,
* then the user-defined default value is returned.
*
* Property values are converted as follows:
*
* - If the value is a 4-dimensional vector, its components will be converted
* to double-precision floating-point numbers.
*
* - If the value is a 3-dimensional vector, it will become the XYZ-components
* of the FVector4. The W-component will be set to zero.
*
* - If the value is a 2-dimensional vector, it will become the XY-components
* of the FVector4. The Z- and W-components will be set to zero.
*
* - If the value is a scalar, then the resulting FVector4 will have this
* value as a double-precision floating-point number in all of its components.
*
* In all other cases, the user-defined default value is returned. If the
* property texture property is somehow invalid, the user-defined default
* value is returned.
*
* @param Property The property texture property.
* @param UV The texture coordinates.
* @param DefaultValue The default value to fall back on.
* @return The property value as a FVector4.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTextureProperty")
static FVector4 GetVector4(
UPARAM(ref) const FCesiumPropertyTextureProperty& Property,
const FVector2D& UV,
const FVector4& DefaultValue);
/**
* Attempts to retrieve the value for the given texture coordinates as a
* FCesiumPropertyArray. If the property is not an array type, this returns an
* empty array.
*
* For numeric array properties, the raw array value for a given coordinates
* will be transformed by the property's normalization, scale, and offset
* before it is further converted. If the raw value is equal to the property's
* "no data" value, then the property's default value will be converted if
* possible. If the property-defined default value cannot be converted, or
* does not exist, then the user-defined default value is returned.
*
* @param Property The property texture property.
* @param UV The texture coordinates.
* @return The property value as a FCesiumPropertyArray.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTextureProperty")
static FCesiumPropertyArray GetArray(
UPARAM(ref) const FCesiumPropertyTextureProperty& Property,
const FVector2D& UV);
/**
* Retrieves the value of the property for the given texture coordinates. This
* allows the value to be acted on more generically; its true value can be
* retrieved later as a specific Blueprints type.
*
* For numeric properties, the raw value for a given feature will be
* transformed by the property's normalization, scale, and offset before it is
* returned. If the raw value is equal to the property's "no data" value, an
* empty value will be returned. However, if the property itself specifies a
* default value, then the property-defined default value will be returned.
*
* @param Property The property texture property.
* @param UV The texture coordinates.
* @return The property value.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTextureProperty")
static FCesiumMetadataValue GetValue(
UPARAM(ref) const FCesiumPropertyTextureProperty& Property,
const FVector2D& UV);
/**
* Retrieves the raw value of the property for the given feature. This is the
* value of the property without normalization, offset, or scale applied.
*
* If this property specifies a "no data" value, and the raw value is equal to
* this "no data" value, the value is returned as-is.
*
* @param Property The property texture property.
* @param UV The texture coordinates.
* @return The raw property value.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTextureProperty")
static FCesiumMetadataValue GetRawValue(
UPARAM(ref) const FCesiumPropertyTextureProperty& Property,
const FVector2D& UV);
/**
* Whether this property is normalized. Only applicable when this property
* has an integer component type.
*
* @param Property The property texture property.
* @return Whether this property is normalized.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTextureProperty")
static bool IsNormalized(UPARAM(ref)
const FCesiumPropertyTextureProperty& Property);
/**
* Gets the offset of this property. This can be defined by the class property
* that it implements, or overridden by the instance of the property itself.
*
* This is only applicable to properties with floating-point or normalized
* integer component types. If an offset is not defined or applicable, this
* returns an empty value.
*
* @param Property The property texture property.
* @return The offset of the property.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTextureProperty")
static FCesiumMetadataValue
GetOffset(UPARAM(ref) const FCesiumPropertyTextureProperty& Property);
/**
* Gets the scale of this property. This can be defined by the class property
* that it implements, or overridden by the instance of the property itself.
*
* This is only applicable to properties with floating-point or normalized
* integer component types. If a scale is not defined or applicable, this
* returns an empty value.
*
* @param Property The property texture property.
* @return The scale of the property.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTextureProperty")
static FCesiumMetadataValue
GetScale(UPARAM(ref) const FCesiumPropertyTextureProperty& Property);
/**
* Gets the minimum value of this property. This can be defined by the class
* property that it implements, or overridden by the instance of the property
* itself.
*
* This is only applicable to scalar, vecN and matN properties. It represents
* the component-wise minimum of all property values with normalization,
* offset, and scale applied. If a minimum value is not defined or
* applicable, this returns an empty value.
*
* @param Property The property texture property.
* @return The minimum value of the property.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTextureProperty")
static FCesiumMetadataValue
GetMinimumValue(UPARAM(ref) const FCesiumPropertyTextureProperty& Property);
/**
* Gets the maximum value of this property. This can be defined by the class
* property that it implements, or overridden by the instance of the property
* itself.
*
* This is only applicable to scalar, vecN and matN properties. It represents
* the component-wise maximum of all property values with normalization,
* offset, and scale applied. If a maximum value is not defined or applicable,
* this returns an empty value.
*
* @param Property The property texture property.
* @return The maximum value of the property.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTextureProperty")
static FCesiumMetadataValue
GetMaximumValue(UPARAM(ref) const FCesiumPropertyTextureProperty& Property);
/**
* Gets the "no data" value of this property, as defined by its class
* property. This value functions a sentinel value, indicating missing data
* wherever it appears. The value is compared against the property's raw data,
* without normalization, offset, or scale applied.
*
* This is not applicable to boolean properties. If a "no data" value is
* not defined or applicable, this returns an empty value.
*
* @param Property The property texture property.
* @return The "no data" value of the property.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTextureProperty")
static FCesiumMetadataValue
GetNoDataValue(UPARAM(ref) const FCesiumPropertyTextureProperty& Property);
/**
* Gets the default value of this property, as defined by its class
* property. This default value is used use when encountering a "no data"
* value in the property.
*
* If a default value is not defined, this returns an empty value.
*
* @param Property The property texture property.
* @return The default value of the property.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Category = "Cesium|Metadata|PropertyTextureProperty")
static FCesiumMetadataValue
GetDefaultValue(UPARAM(ref) const FCesiumPropertyTextureProperty& Property);
PRAGMA_DISABLE_DEPRECATION_WARNINGS
/**
* @brief Get the string representing how the metadata is encoded into a
* pixel color. This is useful to unpack the correct order of the metadata
* components from the pixel color.
*
* @param Property The property texture property.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Meta =
(DeprecatedFunction,
DeprecationMessage =
"Swizzles are no longer hardcoded in Unreal materials. To see what channels the property uses, use GetChannels instead."))
static FString GetSwizzle(UPARAM(ref)
const FCesiumPropertyTextureProperty& Property);
/**
* @brief Get the component count of this property. Since the metadata is
* encoded as pixel color, this is also the number of meaningful channels
* it will use.
*
* @param Property The property texture property.
*/
UFUNCTION(
BlueprintCallable,
BlueprintPure,
Meta =
(DeprecatedFunction,
DeprecationMessage =
"Use GetChannels to get the channels array of a property texture property instead."))
static int64
GetComponentCount(UPARAM(ref) const FCesiumPropertyTextureProperty& Property);
PRAGMA_ENABLE_DEPRECATION_WARNINGS
};

View File

@ -0,0 +1,260 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumRasterOverlayLoadFailureDetails.h"
#include "CesiumRasterOverlays/RasterOverlay.h"
#include "Components/ActorComponent.h"
#include "CoreMinimal.h"
#include "Engine/Texture.h"
#include "Engine/TextureDefines.h"
#include <memory>
#include "CesiumRasterOverlay.generated.h"
namespace Cesium3DTilesSelection {
class Tileset;
}
/**
* The delegate for OnCesiumRasterOverlayLoadFailure, which is triggered when
* the raster overlay encounters a load error.
*/
DECLARE_MULTICAST_DELEGATE_OneParam(
FCesiumRasterOverlayLoadFailure,
const FCesiumRasterOverlayLoadFailureDetails&);
CESIUMRUNTIME_API extern FCesiumRasterOverlayLoadFailure
OnCesiumRasterOverlayLoadFailure;
/**
* This struct is passed through the raster overlay options and is used when
* `prepareRasterInLoadThread` is called.
*/
USTRUCT(BlueprintType)
struct FRasterOverlayRendererOptions {
GENERATED_BODY()
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
TEnumAsByte<TextureFilter> filter = TextureFilter::TF_Default;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
TEnumAsByte<TextureGroup> group = TextureGroup::TEXTUREGROUP_World;
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
bool useMipmaps = true;
};
/**
* A quadtree pyramid of 2D raster images meant to be draped over a Cesium 3D
* Tileset. Raster overlays are commonly used for satellite imagery, street
* maps, and more.
*/
UCLASS(Abstract)
class CESIUMRUNTIME_API UCesiumRasterOverlay : public UActorComponent {
GENERATED_BODY()
public:
/**
* The key to use to match this overlay to a material layer.
*
* When using Material Layers, any material layers inside a "Cesium" layer
* stack with a name that matches this name will have their Texture,
* TranslationScale, and TextureCoordinateIndex properties set automatically
* so that a ML_CesiumOverlay layer function (or similar) will correctly
* sample from this overlay.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
FString MaterialLayerKey = "Overlay0";
/**
* Sets the texture filter and texture group of raster tile images. Depending
* on the project settings, the default texture filter, TF_Default, should
* have the best quality.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
FRasterOverlayRendererOptions rendererOptions;
// Sets default values for this component's properties
UCesiumRasterOverlay();
/**
* Displays this raster overlay on its owning Cesium 3D Tileset Actor, without
* changing its activation state. It is usually better to call Activate
* rather than this function, in order to ensure that the component is also
* activated. Otherwise, if the Cesium3DTileset is reloaded for any reason,
* this overlay will no longer be shown.
*
* If the overlay is already added or if this component's Owner is not a
* Cesium 3D Tileset, this method does nothing.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
void AddToTileset();
/**
* Stops displaying this raster overlay on its owning Cesium 3D Tileset Actor.
* It is usually better to call Deactivate rather than this function, in order
* to ensure that the component is also deactivated. Otherwise, if the
* component remains active and the Cesium3DTileset is reloaded for any
* reason, this overlay will reappear.
*
* If the overlay is not yet added or if this component's Owner is not a
* Cesium 3D Tileset, this method does nothing.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
void RemoveFromTileset();
/**
* Refreshes this overlay by removing from its owning Cesium 3D Tileset Actor
* and re-adding it. If this component's Owner is not a Cesium 3D Tileset
* Actor, this method does nothing. If this component is not active, the
* overlay will be removed from the Cesium3DTileset if already present but not
* re-added.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
void Refresh();
UFUNCTION(BlueprintCallable, Category = "Cesium")
double GetMaximumScreenSpaceError() const;
UFUNCTION(BlueprintCallable, Category = "Cesium")
void SetMaximumScreenSpaceError(double Value);
UFUNCTION(BlueprintCallable, Category = "Cesium")
int32 GetMaximumTextureSize() const;
UFUNCTION(BlueprintCallable, Category = "Cesium")
void SetMaximumTextureSize(int32 Value);
UFUNCTION(BlueprintCallable, Category = "Cesium")
int32 GetMaximumSimultaneousTileLoads() const;
UFUNCTION(BlueprintCallable, Category = "Cesium")
void SetMaximumSimultaneousTileLoads(int32 Value);
UFUNCTION(BlueprintCallable, Category = "Cesium")
int64 GetSubTileCacheBytes() const;
UFUNCTION(BlueprintCallable, Category = "Cesium")
void SetSubTileCacheBytes(int64 Value);
/**
* Activates this raster overlay, which will display it on the Cesium3DTileset
* to which the component is attached, if it isn't already displayed. The
* overlay will continue to be shown on the tileset until it is deactivated.
*
* If the overlay is already displayed on the Cesium3DTileset, calling this
* function will not cause it to pick up any new values for properties that
* have been modified since it was added. To do that, call Refresh.
*
* If you created this overlay component via Blueprints, consider setting the
* "Auto Activate" property to false on the "Add Component" node and calling
* Activate after setting all the desired properties. This will avoid the need
* to call Refresh, and will ensure the overlay is not loaded multiple times.
*
* @param bReset Whether the activation should happen even if ShouldActivate
* returns false.
*/
virtual void Activate(bool bReset) override;
/**
* Deactivates this raster overlay. This will stop displaying it on the
* Cesium3DTileset to which the component is attached. The overlay will not be
* shown again until the component is re-activated.
*/
virtual void Deactivate() override;
virtual void OnComponentDestroyed(bool bDestroyingHierarchy) override;
virtual bool IsReadyForFinishDestroy() override;
protected:
/**
* The maximum number of pixels of error when rendering this overlay.
* This is used to select an appropriate level-of-detail.
*
* When this property has its default value, 2.0, it means that raster overlay
* images will be sized so that, when zoomed in closest, a single pixel in
* the raster overlay maps to approximately 2x2 pixels on the screen.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
BlueprintGetter = GetMaximumScreenSpaceError,
BlueprintSetter = SetMaximumScreenSpaceError,
Category = "Cesium")
double MaximumScreenSpaceError = 2.0;
/**
* The maximum texel size of raster overlay textures, in either
* direction.
*
* Images created by this overlay will be no more than this number of texels
* in either direction. This may result in reduced raster overlay detail in
* some cases.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
BlueprintGetter = GetMaximumTextureSize,
BlueprintSetter = SetMaximumTextureSize,
Category = "Cesium")
int32 MaximumTextureSize = 2048;
/**
* The maximum number of overlay tiles that may simultaneously be in
* the process of loading.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
BlueprintGetter = GetMaximumSimultaneousTileLoads,
BlueprintSetter = SetMaximumSimultaneousTileLoads,
Category = "Cesium")
int32 MaximumSimultaneousTileLoads = 20;
/**
* The maximum number of bytes to use to cache sub-tiles in memory.
*
* This is used by provider types that have an underlying tiling scheme that
* may not align with the tiling scheme of the geometry tiles on which the
* raster overlay tiles are draped. Because a single sub-tile may overlap
* multiple geometry tiles, it is useful to cache loaded sub-tiles in memory
* in case they're needed again soon. This property controls the maximum size
* of that cache.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
BlueprintGetter = GetSubTileCacheBytes,
BlueprintSetter = SetSubTileCacheBytes,
Category = "Cesium")
int64 SubTileCacheBytes = 16 * 1024 * 1024;
/**
* Whether or not to show credits of this raster overlay on screen.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
bool ShowCreditsOnScreen;
#if WITH_EDITOR
// Called when properties are changed in the editor
virtual void
PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
#endif
Cesium3DTilesSelection::Tileset* FindTileset() const;
virtual std::unique_ptr<CesiumRasterOverlays::RasterOverlay>
CreateOverlay(const CesiumRasterOverlays::RasterOverlayOptions& options = {})
PURE_VIRTUAL(UCesiumRasterOverlay::CreateOverlay, return nullptr;);
virtual void OnAdd(
Cesium3DTilesSelection::Tileset* pTileset,
CesiumRasterOverlays::RasterOverlay* pOverlay) {}
virtual void OnRemove(
Cesium3DTilesSelection::Tileset* pTileset,
CesiumRasterOverlays::RasterOverlay* pOverlay) {}
private:
CesiumRasterOverlays::RasterOverlay* _pOverlay;
int32 _overlaysBeingDestroyed;
};

View File

@ -0,0 +1,58 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CoreMinimal.h"
#include "CesiumRasterOverlayLoadFailureDetails.generated.h"
class UCesiumRasterOverlay;
UENUM(BlueprintType)
enum class ECesiumRasterOverlayLoadType : uint8 {
/**
* An unknown load error.
*/
Unknown,
/**
* A Cesium ion asset endpoint.
*/
CesiumIon,
/**
* @brief An initial load needed to create the overlay's tile provider.
*/
TileProvider
};
USTRUCT(BlueprintType)
struct CESIUMRUNTIME_API FCesiumRasterOverlayLoadFailureDetails {
GENERATED_BODY()
/**
* The overlay that encountered the load failure.
*/
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Cesium")
TWeakObjectPtr<UCesiumRasterOverlay> Overlay = nullptr;
/**
* The type of request that failed to load.
*/
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Cesium")
ECesiumRasterOverlayLoadType Type = ECesiumRasterOverlayLoadType::Unknown;
/**
* The HTTP status code of the response that led to the failure.
*
* If there was no response or the failure did not follow from a request, then
* the value of this property will be 0.
*/
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Cesium")
int32 HttpStatusCode = 0;
/**
* A human-readable explanation of what failed.
*/
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Cesium")
FString Message;
};

View File

@ -0,0 +1,54 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CoreMinimal.h"
#include "Modules/ModuleManager.h"
#include <memory>
class ACesium3DTileset;
class UCesiumRasterOverlay;
namespace CesiumAsync {
class AsyncSystem;
class IAssetAccessor;
class ICacheDatabase;
} // namespace CesiumAsync
DECLARE_LOG_CATEGORY_EXTERN(LogCesium, Log, All);
class FCesiumRuntimeModule : public IModuleInterface {
public:
/** IModuleInterface implementation */
virtual void StartupModule() override;
virtual void ShutdownModule() override;
};
/**
* The delegate for the OnCesium3DTilesetIonTroubleshooting, which is triggered
* when the tileset encounters a load error.
*/
DECLARE_MULTICAST_DELEGATE_OneParam(
FCesium3DTilesetIonTroubleshooting,
ACesium3DTileset*);
CESIUMRUNTIME_API extern FCesium3DTilesetIonTroubleshooting
OnCesium3DTilesetIonTroubleshooting;
/**
* The delegate for the OnCesiumRasterOverlayIonTroubleshooting, which is
* triggered when the tileset encounters a load error.
*/
DECLARE_MULTICAST_DELEGATE_OneParam(
FCesiumRasterOverlayIonTroubleshooting,
UCesiumRasterOverlay*);
CESIUMRUNTIME_API extern FCesiumRasterOverlayIonTroubleshooting
OnCesiumRasterOverlayIonTroubleshooting;
CESIUMRUNTIME_API CesiumAsync::AsyncSystem& getAsyncSystem() noexcept;
CESIUMRUNTIME_API const std::shared_ptr<CesiumAsync::IAssetAccessor>&
getAssetAccessor();
CESIUMRUNTIME_API std::shared_ptr<CesiumAsync::ICacheDatabase>&
getCacheDatabase();

View File

@ -0,0 +1,69 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CoreMinimal.h"
#include "Engine/DeveloperSettings.h"
#include "CesiumRuntimeSettings.generated.h"
/**
* Stores runtime settings for the Cesium plugin.
*/
UCLASS(Config = Engine, DefaultConfig, meta = (DisplayName = "Cesium"))
class CESIUMRUNTIME_API UCesiumRuntimeSettings : public UDeveloperSettings {
GENERATED_UCLASS_BODY()
public:
UPROPERTY(
Config,
meta =
(DeprecatedProperty,
DeprecationMessage =
"Tokens are now configured on CesiumIonServer data assets."))
FString DefaultIonAccessTokenId_DEPRECATED;
UPROPERTY(
Config,
meta =
(DeprecatedProperty,
DeprecationMessage =
"Tokens are now configured on CesiumIonServer data assets."))
FString DefaultIonAccessToken_DEPRECATED;
UPROPERTY(
Config,
EditAnywhere,
Category = "Level of Detail",
meta = (DisplayName = "Scale Level-of-Detail by Display DPI"))
bool ScaleLevelOfDetailByDPI = true;
/**
* Uses Unreal's occlusion culling engine to drive Cesium 3D Tiles selection,
* reducing the detail of tiles that are occluded by other objects in the
* scene so that less data overall needs to be loaded and rendered.
*/
UPROPERTY(Config, EditAnywhere, Category = "Experimental Feature Flags")
bool EnableExperimentalOcclusionCullingFeature = false;
/**
* The number of requests to handle before each prune of old cached results
* from the database.
*/
UPROPERTY(
Config,
EditAnywhere,
Category = "Cache",
meta = (ConfigRestartRequired = true))
int RequestsPerCachePrune = 10000;
/**
* The maximum number of items that should be kept in the Sqlite database
* after pruning.
*/
UPROPERTY(
Config,
EditAnywhere,
Category = "Cache",
meta = (ConfigRestartRequired = true))
int MaxCacheItems = 4096;
};

View File

@ -0,0 +1,71 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumSampleHeightResult.h"
#include "Kismet/BlueprintAsyncActionBase.h"
#include "CesiumSampleHeightMostDetailedAsyncAction.generated.h"
class ACesium3DTileset;
/**
* The delegate used to asynchronously return sampled heights.
* @param Result The result of the height sampling. This array contains the
* outputs for each input cartographic position. Each result has a HeightSampled
* property indicating whether the height was successfully sampled at that
* position, and a LongitudeLatitudeHeight property with the complete position,
* including the sampled height. If the sample was unsuccessful, the original
* position is returned.
* @param Warnings Provides information about problems, if any, that were
* encountered while sampling heights.
*/
DECLARE_DYNAMIC_MULTICAST_DELEGATE_TwoParams(
FCesiumSampleHeightMostDetailedComplete,
const TArray<FCesiumSampleHeightResult>&,
Result,
const TArray<FString>&,
Warnings);
UCLASS()
class CESIUMRUNTIME_API UCesiumSampleHeightMostDetailedAsyncAction
: public UBlueprintAsyncActionBase {
GENERATED_BODY()
public:
/**
* Asynchronously samples the height of the tileset at a list of cartographic
* positions, each expressed as a Longitude (X) and Latitude (Y) in degrees.
* The Height (Z) provided on input is ignored unless the sampling fails at
* that position, in which case it is passed through to the output.
* @param Tileset The tileset from which to query heights.
* @param LongitudeLatitudeHeightArray The array of cartographic positions at
* which to query heights, with Longitude in the X component and Latitude in
* the Y component.
*/
UFUNCTION(
BlueprintCallable,
Category = "Cesium",
meta = (BlueprintInternalUseOnly = true))
static UCesiumSampleHeightMostDetailedAsyncAction* SampleHeightMostDetailed(
ACesium3DTileset* Tileset,
const TArray<FVector>& LongitudeLatitudeHeightArray);
/**
* Called when height has been sampled at all of the given positions. The
* Result property contains an element for each input position and in the same
* order. The Warnings property provides information about problems that were
* encountered while sampling heights.
*/
UPROPERTY(BlueprintAssignable)
FCesiumSampleHeightMostDetailedComplete OnHeightsSampled;
virtual void Activate() override;
private:
void RaiseOnHeightsSampled(
ACesium3DTileset* Tileset,
const TArray<FCesiumSampleHeightResult>& Result,
const TArray<FString>& Warnings);
ACesium3DTileset* _pTileset;
TArray<FVector> _longitudeLatitudeHeightArray;
};

View File

@ -0,0 +1,32 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumSampleHeightResult.generated.h"
/**
* The result of sampling the height on a tileset at the given cartographic
* position.
*/
USTRUCT(BlueprintType)
struct CESIUMRUNTIME_API FCesiumSampleHeightResult {
GENERATED_BODY()
/**
* The Longitude (X) and Latitude (Y) are the same values provided on input.
* The Height (Z) is the height sampled from the tileset if the SampleSuccess
* property is true, or the original height provided on input if SampleSuccess
* is false.
*/
UPROPERTY(BlueprintReadWrite, Category = "Cesium")
FVector LongitudeLatitudeHeight = {0.0, 0.0, 0.0};
/**
* True if the height as sampled from the tileset successfully. False if the
* tileset doesn't have any height at that position, or if something went
* wrong. If something went wrong, the Warnings pin of the sampling function
* will have more information about the problem.
*/
UPROPERTY(BlueprintReadWrite, Category = "Cesium")
bool SampleSuccess = false;
};

View File

@ -0,0 +1,87 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "CesiumSubLevel.generated.h"
class ULevelStreaming;
struct UE_DEPRECATED(
5.0,
"The FCesiumSubLevel struct has been deprecated. Use Level Instance Actors and UCesiumSubLevelComponent instead.")
FCesiumSubLevel;
/*
* Sublevels can be georeferenced to the globe by filling out this struct.
*/
USTRUCT()
struct FCesiumSubLevel {
GENERATED_BODY()
/**
* The plain name of the sub level, without any prefixes.
*/
UPROPERTY(VisibleAnywhere, Category = "Cesium")
FString LevelName;
/**
* Whether this sub-level is enabled. An enabled sub-level will be
* automatically loaded when the camera moves within its LoadRadius and
* no other levels are closer, and the Georeference will be updated so that
* this level's Longitude, Latitude, and Height bcome (0, 0, 0) in the Unreal
* World. A sub-level that is not enabled will be ignored by Cesium.
*
* If this option is greyed out, check that World Composition is enabled
* in the World Settings and that this sub-level is in a Layer that has
* Distance-based streaming DISABLED.
*/
UPROPERTY(
EditAnywhere,
Category = "Cesium",
Meta = (EditCondition = "CanBeEnabled"))
bool Enabled = true;
/**
* The WGS84 latitude in degrees of where this level should sit on the globe,
* in the range [-90, 90]
*/
UPROPERTY(
EditAnywhere,
Category = "Cesium",
meta = (ClampMin = -90.0, ClampMax = 90.0, EditCondition = "Enabled"))
double LevelLatitude = 0.0;
/**
* The WGS84 longitude in degrees of where this level should sit on the
* globe, in the range [-180, 180]
*/
UPROPERTY(
EditAnywhere,
Category = "Cesium",
meta = (ClampMin = -180.0, ClampMax = 180.0, EditCondition = "Enabled"))
double LevelLongitude = 0.0;
/**
* The height in meters above the WGS84 globe this level should sit.
*/
UPROPERTY(
EditAnywhere,
Category = "Cesium",
meta = (EditCondition = "Enabled"))
double LevelHeight = 0.0;
/**
* How far in meters from the sublevel local origin the camera needs to be to
* load the level.
*/
UPROPERTY(
EditAnywhere,
Category = "Cesium",
meta = (ClampMin = 0.0, EditCondition = "Enabled"))
double LoadRadius = 0.0;
UPROPERTY(VisibleDefaultsOnly, Category = "Cesium")
bool CanBeEnabled = false;
};

View File

@ -0,0 +1,408 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "Components/ActorComponent.h"
#include "UObject/ObjectMacros.h"
#include "CesiumSubLevelComponent.generated.h"
class ACesiumGeoreference;
class ALevelInstance;
class UCesiumSubLevelSwitcherComponent;
/**
* A component intended to be attached to a Level Instance Actor that turns that
* Level Instance into a Cesium sub-level. Only a single Cesium sub-level can be
* active (visible) at any given time.
*
* A globe (like the planet Earth) is an unusual sort of level in Unreal in that
* it has truly massive coordinate values and the "up" direction depends on
* where exactly on the globe you're located. Many things in the Unreal
* ecosystem, such as the gravity system, don't expect this situation and will
* have incorrect and surprising behavior when used on a globe.
*
* Cesium sub-levels help to mitigate this. Only one sub-level can be active at
* any given time, and when it is, that sub-level's origin becomes the origin of
* the Unreal world. Furthermore, at the origin location, Unreal's +X axis
* points East, its +Y axis points South, and its +Z axis points Up. Thus,
* within a sub-level, gravity works in the normal way that Unreal objects
* expect, and coordinate values stay relatively small. This allows you to use
* just about any Unreal object within a sub-level without worrying about
* surprising behavior.
*
* Globe-aware objects, particularly those with a "Cesium Globe Anchor"
* component attached to them, are allowed to exist outside sub-levels and even
* move between them. If all your objects are globe aware, there's no need to
* use sub-levels at all.
*
* In the Editor, the currently-active sub-level is selected by clicking the
* "Eye" icon next to the Level Instance in the Outliner.
*
* At runtime, the currently-active sub-level is selected by the Actor with a
* CesiumOriginShiftComponent attached to it. If this Actor is inside a
* sub-level's "Load Radius" that sub-level will be activated. If multiple
* sub-levels are in range, only the closest one will be activated.
*/
UCLASS(ClassGroup = (Cesium), meta = (BlueprintSpawnableComponent))
class CESIUMRUNTIME_API UCesiumSubLevelComponent : public UActorComponent {
GENERATED_BODY()
public:
/**
* Gets whether this sub-level is enabled. An enabled sub-level will be
* automatically loaded when the camera moves within its LoadRadius and
* no other levels are closer, and the Georeference will be updated so that
* this level's Longitude, Latitude, and Height become (0, 0, 0) in the Unreal
* World. A sub-level that is not enabled will be ignored by Cesium at
* runtime.
*/
UFUNCTION(BlueprintGetter, Category = "Cesium")
bool GetEnabled() const;
/**
* Sets whether this sub-level is enabled. An enabled sub-level will be
* automatically loaded when the camera moves within its LoadRadius and
* no other levels are closer, and the Georeference will be updated so that
* this level's Longitude, Latitude, and Height become (0, 0, 0) in the Unreal
* World. A sub-level that is not enabled will be ignored by Cesium at
* runtime.
*/
UFUNCTION(BlueprintSetter, Category = "Cesium")
void SetEnabled(bool value);
/**
* Gets the longitude of the georeference origin for this sub-level in
* degrees, in the range [-180, 180]. When this sub-level is active, the
* CesiumGeoreference will adopt this origin.
*/
UFUNCTION(BlueprintGetter, Category = "Cesium")
double GetOriginLongitude() const;
/**
* Sets the longitude of the georeference origin for this sub-level in
* degrees, in the range [-180, 180]. When this sub-level is active, the
* CesiumGeoreference will adopt this origin.
*/
UFUNCTION(BlueprintSetter, Category = "Cesium")
void SetOriginLongitude(double value);
/**
* Gets the latitude of the georeference origin for this sub-level in degrees,
* in the range [-90, 90]. When this sub-level is active, the
* CesiumGeoreference will adopt this origin.
*/
UFUNCTION(BlueprintGetter, Category = "Cesium")
double GetOriginLatitude() const;
/**
* Sets the latitude of the georeference origin for this sub-level in degrees,
* in the range [-90, 90]. When this sub-level is active, the
* CesiumGeoreference will adopt this origin.
*/
UFUNCTION(BlueprintSetter, Category = "Cesium")
void SetOriginLatitude(double value);
/**
* Gets the height of the georeference origin for this sub-level in meters
* above the ellipsoid. This height should not be confused with a height
* above Mean Sea Level. When this sub-level is active, the CesiumGeoreference
* will adopt this origin.
*/
UFUNCTION(BlueprintGetter, Category = "Cesium")
double GetOriginHeight() const;
/**
* Sets the height of the georeference origin for this sub-level in meters
* above the ellipsoid. This height should not be confused with a height
* above Mean Sea Level. When this sub-level is active, the CesiumGeoreference
* will adopt this origin.
*/
UFUNCTION(BlueprintSetter, Category = "Cesium")
void SetOriginHeight(double value);
/**
* Gets how close to the sub-level local origin, in meters, the camera needs
* to be to load the level.
*/
UFUNCTION(BlueprintGetter, Category = "Cesium")
double GetLoadRadius() const;
/**
* Sets how close to the sub-level local origin, in meters, the camera needs
* to be to load the level.
*/
UFUNCTION(BlueprintSetter, Category = "Cesium")
void SetLoadRadius(double value);
/**
* Gets 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 sub-level 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.
*/
UFUNCTION(BlueprintGetter, Category = "Cesium")
TSoftObjectPtr<ACesiumGeoreference> GetGeoreference() const;
/**
* Sets 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 sub-level 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.
*/
UFUNCTION(BlueprintSetter, Category = "Cesium")
void SetGeoreference(TSoftObjectPtr<ACesiumGeoreference> NewGeoreference);
/**
* Gets the resolved georeference, just like calling the ResolveGeoreference
* property, except that it will return null if a georeference has not yet
* been resolved.
*/
UFUNCTION(BlueprintGetter, Category = "Cesium")
ACesiumGeoreference* GetResolvedGeoreference() const;
/**
* Resolves the Cesium Georeference to use with this components. 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, unless ForceReresolve is true.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
ACesiumGeoreference* ResolveGeoreference(bool bForceReresolve = false);
/**
* Sets the longitude (X), latitude (Y), and height (Z) of this sub-level's
* georeference origin. When this sub-level is active, the CesiumGeoreference
* will adopt this origin. Longitude and latitude are in degrees. Height is in
* meters above the ellipsoid, which should not be confused with meters
* above Mean Sea Level.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
void SetOriginLongitudeLatitudeHeight(const FVector& longitudeLatitudeHeight);
#if WITH_EDITOR
/**
* Places the georeference origin at the origin of the sub-level and sets the
* Level Instance's Location to (0,0,0). This improves the precision of the
* objects in the sub-level as well as makes the Load Radius more sensible.
*
* If your sub-level has any Cesium3DTilesets, Cesium for Unreal will enter
* Edit mode for the sub-level and the Cesium3DTilesets' transformations will
* be updated based on the new georeference origin. You should Commit this
* change.
*
* Warning: Before clicking, ensure that all non-Cesium objects in the
* persistent level are georeferenced with the "CesiumGeoreferenceComponent"
* or attached to an actor with that component. Ensure that static actors only
* exist in georeferenced sub-levels.
*/
UFUNCTION(CallInEditor, Category = "Cesium")
void PlaceGeoreferenceOriginAtSubLevelOrigin();
/**
* Places the sub-level's origin at the camera's current location. Rotates
* the globe so the current longitude/latitude/height of the camera is at the
* Unreal origin of this sub-level. The camera is also teleported to the new
* Unreal origin and rotated so that the view direction is maintained.
*
* This function is similar to "Place Georeference Origin Here" on the
* CesiumGeoreference, except that this moves the georeference origin while
* also ensuring that the sub-level content stays in the same place on the
* globe by adjusting the Level Instance's transform.
*
* If your sub-level has any Cesium3DTilesets, Cesium for Unreal will enter
* Edit mode for the sub-level and the Cesium3DTilesets' transformations will
* be updated based on the new georeference origin. You should Commit this
* change.
*
* Warning: Before clicking, ensure that all non-Cesium objects in the
* persistent level are georeferenced with the "CesiumGlobeAnchorComponent"
* or attached to an actor with that component. Ensure that static actors only
* exist in georeferenced sub-levels.
*/
UFUNCTION(CallInEditor, Category = "Cesium")
void PlaceGeoreferenceOriginHere();
#endif
/**
* If this sub-level is currently the active one, this method will copy its
* origin to the georeference's origin. Otherwise, it does nothing.
*/
void UpdateGeoreferenceIfSubLevelIsActive();
virtual void BeginDestroy() override;
virtual void OnComponentCreated() override;
#if WITH_EDITOR
virtual void
PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
#endif
protected:
virtual void BeginPlay() override;
/**
* Called when a component is registered. This can be viewed as "enabling"
* this Component on the Actor to which it is attached.
*
* In the Editor, this is called in a many different situations, such as on
* changes to properties.
*/
virtual void OnRegister() override;
/**
* Called when a component is unregistered. This can be viewed as
* "disabling" this Component on the Actor to which it is attached.
*
* In the Editor, this is called in a many different situations, such as on
* changes to properties.
*/
virtual void OnUnregister() override;
#if WITH_EDITOR
/**
* Called by the Editor to check if it's ok to edit a property on this object.
* Used to disable all fields on this component when editing the sub-level
* instance that this component is attached to.
*/
virtual bool CanEditChange(const FProperty* InProperty) const override;
#endif
private:
/**
* Whether this sub-level is enabled. An enabled sub-level will be
* automatically loaded when the camera moves within its LoadRadius and
* no other levels are closer, and the Georeference will be updated so that
* this level's Longitude, Latitude, and Height become (0, 0, 0) in the Unreal
* World. A sub-level that is not enabled will be ignored by Cesium at
* runtime.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium",
BlueprintGetter = GetEnabled,
BlueprintSetter = SetEnabled,
meta = (AllowPrivateAccess = true))
bool Enabled = true;
/**
* The latitude of the georeference origin for this sub-level in degrees, in
* the range [-90, 90]. When this sub-level is active, the CesiumGeoreference
* will adopt this origin.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium",
BlueprintGetter = GetOriginLatitude,
BlueprintSetter = SetOriginLatitude,
meta = (ClampMin = -90.0, ClampMax = 90.0, AllowPrivateAccess = true))
double OriginLatitude = 39.736401;
/**
* The longitude of the georeference origin for this sub-level in degrees, in
* the range [-180, 180]. When this sub-level is active, the
* CesiumGeoreference will adopt this origin.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium",
BlueprintGetter = GetOriginLongitude,
BlueprintSetter = SetOriginLongitude,
meta = (ClampMin = -180.0, ClampMax = 180.0, AllowPrivateAccess = true))
double OriginLongitude = -105.25737;
/**
* The height of the georeference origin for this sub-level in meters above
* the ellipsoid. This height should not be confused with a height above
* Mean Sea Level. When this sub-level is active, the CesiumGeoreference will
* adopt this origin.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium",
BlueprintGetter = GetOriginHeight,
BlueprintSetter = SetOriginHeight,
meta = (AllowPrivateAccess = true))
double OriginHeight = 2250.0;
/**
* How close to the sub-level local origin, in meters, the camera needs to be
* to load the level.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium",
BlueprintGetter = GetLoadRadius,
BlueprintSetter = SetLoadRadius,
meta = (ClampMin = 0.0, AllowPrivateAccess = true))
double LoadRadius = 1000.0;
/**
* 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 sub-level 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 sub-level. This is not serialized
* because it may point to a Georeference in the PersistentLevel while this
* Actor is in a sub-level. 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,
BlueprintGetter = GetResolvedGeoreference,
Category = "Cesium",
Meta = (AllowPrivateAccess))
ACesiumGeoreference* ResolvedGeoreference = nullptr;
/**
* Gets the sub-level switch component with which this sub-level is
* associated. Calling this method will call ResolveGeoreference to resolve
* the georeference, if it's not already resolved.
*/
UCesiumSubLevelSwitcherComponent* _getSwitcher() noexcept;
/**
* Gets the Level Instance Actor to which this component is attached. If this
* component is not attached to a Level Instance Actor, this method logs a
* warning and returns nullptr.
*/
ALevelInstance* _getLevelInstance() const noexcept;
/**
* 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.
*/
void _invalidateResolvedGeoreference();
void PlaceOriginAtEcef(const FVector& NewOriginEcef);
};

View File

@ -0,0 +1,112 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "Components/ActorComponent.h"
#include "CesiumSubLevelSwitcherComponent.generated.h"
class ACesiumGeoreference;
class ALevelInstance;
class ULevelStreaming;
class UWorld;
/**
* Manages the asynchronous switching between sub-levels, making sure that a
* previous sub-level is hidden before the CesiumGeoreference is switched to a
* new location and the next sub-level is loaded.
*/
UCLASS(ClassGroup = "Cesium")
class CESIUMRUNTIME_API UCesiumSubLevelSwitcherComponent
: public UActorComponent {
GENERATED_BODY()
public:
UCesiumSubLevelSwitcherComponent();
/**
* Gets the list of sub-levels that are currently registered with this
* switcher.
*/
UFUNCTION(BlueprintPure, Category = "Cesium|Sub-levels")
TArray<ALevelInstance*> GetRegisteredSubLevels() const noexcept;
/**
* Gets the list of sub-levels that are currently registered with this
* switcher. This is slightly more efficient than GetRegisteredSubLevels but
* is not accessible from Blueprints.
*/
const TArray<TWeakObjectPtr<ALevelInstance>>&
GetRegisteredSubLevelsWeak() const noexcept {
return this->_sublevels;
}
/**
* Gets the sub-level that is currently active, or nullptr if none are active.
*/
UFUNCTION(BlueprintPure, Category = "Cesium|Sub-levels")
ALevelInstance* GetCurrentSubLevel() const noexcept;
/**
* Gets the sub-level that is in the process of becoming active. If nullptr,
* the target is a state where no sub-levels are active.
*/
UFUNCTION(BlueprintPure, Category = "Cesium|Sub-levels")
ALevelInstance* GetTargetSubLevel() const noexcept;
/**
* Sets the sub-level that should be active. The switcher will asynchronously
* load and show this sub-level.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium|Sub-levels")
void SetTargetSubLevel(ALevelInstance* LevelInstance) noexcept;
private:
// To allow the sub-level to register/unregister itself with the functions
// below.
friend class UCesiumSubLevelComponent;
friend class CesiumEditorSubLevelMutex;
/**
* Registers a sub-level with this switcher. The switcher will ensure that
* no more than one of the registered sub-levels is active at any time.
*/
void RegisterSubLevel(ALevelInstance* pSubLevel) noexcept;
/**
* Unregisters a sub-level from this switcher. This is primarily used if the
* sub-level is being destroyed or reparented.
*/
void UnregisterSubLevel(ALevelInstance* pSubLevel) noexcept;
virtual void TickComponent(
float DeltaTime,
enum ELevelTick TickType,
FActorComponentTickFunction* ThisTickFunction) override;
void _updateSubLevelStateGame();
#if WITH_EDITOR
void _updateSubLevelStateEditor();
#endif
/**
* Finds the ULevelStreaming instance, if any, associated with a given
* sub-level.
*/
ULevelStreaming*
_getLevelStreamingForSubLevel(ALevelInstance* SubLevel) const;
// Don't save/load or copy this.
UPROPERTY(Transient, DuplicateTransient, TextExportTransient)
TArray<TWeakObjectPtr<ALevelInstance>> _sublevels;
// Don't save/load or copy this.
UPROPERTY(Transient, DuplicateTransient, TextExportTransient)
TWeakObjectPtr<ALevelInstance> _pCurrent = nullptr;
// Save/load this, but don't copy it.
UPROPERTY(DuplicateTransient, TextExportTransient)
TWeakObjectPtr<ALevelInstance> _pTarget = nullptr;
bool _doExtraChecksOnNextTick = false;
bool _isTransitioningSubLevels = false;
};

View File

@ -0,0 +1,530 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CoreMinimal.h"
#include "CesiumGeoreference.h"
#include "Components/DirectionalLightComponent.h"
#include "Components/SkyAtmosphereComponent.h"
#include "Components/SkyLightComponent.h"
#include "Components/StaticMeshComponent.h"
#include "Engine/DirectionalLight.h"
#include "GameFramework/Actor.h"
#include "CesiumSunSky.generated.h"
class UCesiumGlobeAnchorComponent;
/**
* A globe-aware sun sky actor. If the georeference is set to CartographicOrigin
* (aka Longitude/Latitude/Height) mode, then this actor will automatically
* sync its longitude and latitude properties with the georeference's, and
* recalculate the sun position whenever those properties change.
*
* Note: because we use `Planet Center at Component Transform`
* for the SkyAtmosphere transform mode, this actor's location will be forced
* to the Earth's center if the georeference is set to CartographicOrigin.
*/
UCLASS()
class CESIUMRUNTIME_API ACesiumSunSky : public AActor {
GENERATED_BODY()
public:
// Sets default values for this actor's properties
ACesiumSunSky();
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = Components)
USceneComponent* Scene;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = Components)
USkyLightComponent* SkyLight;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = Components)
UDirectionalLightComponent* DirectionalLight;
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = Components)
USkyAtmosphereComponent* SkyAtmosphere;
/**
* The Globe Anchor Component that precisely ties this Actor to the Globe.
*/
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = Components)
UCesiumGlobeAnchorComponent* GlobeAnchor;
/**
* Gets the time zone, represented as hours offset from GMT.
*
* After changing this value from Blueprints or C++, you must call UpdateSun
* for it to take effect.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium|Date and Time",
meta = (ClampMin = -12, ClampMax = 14))
double TimeZone = -5.0;
/**
* The current solar time represented as hours from midnight.
*
* After changing this value from Blueprints or C++, you must call UpdateSun
* for it to take effect.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium|Date and Time",
meta = (UIMin = 4, UIMax = 22, ClampMin = 0, ClampMax = 23.9999))
double SolarTime = 13.0;
/**
* The day of the month.
*
* After changing this value from Blueprints or C++, you must call UpdateSun
* for it to take effect.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium|Date and Time",
meta = (ClampMin = 1, ClampMax = 31))
int32 Day = 21;
/**
* The month of the year, where 1 is January and 12 is December.
*
* After changing this value from Blueprints or C++, you must call UpdateSun
* for it to take effect.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium|Date and Time",
meta = (ClampMin = 1, ClampMax = 12))
int32 Month = 9;
/**
* The year.
*
* After changing this value from Blueprints or C++, you must call UpdateSun
* for it to take effect.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium|Date and Time",
meta = (UIMin = 1800, UIMax = 2200, ClampMin = 0, ClampMax = 4000))
int32 Year = 2019;
/**
* Offset in the sun's position. Should be set to -90 for the sun's position
* to be accurate in the Unreal reference frame.
*
* After changing this value from Blueprints or C++, you must call UpdateSun
* for it to take effect.
*/
UPROPERTY(
BlueprintReadWrite,
Category = "Cesium|Date and Time",
meta = (ClampMin = -360, ClampMax = 360))
double NorthOffset = -90.0;
/**
* Enables adjustment of the Solar Time for Daylight Saving Time (DST).
*
* After changing this value from Blueprints or C++, you must call UpdateSun
* for it to take effect.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium|Date and Time|Daylight Savings")
bool UseDaylightSavingTime = true;
protected:
/**
* THIS PROPERTY IS DEPRECATED.
*
* Get the Georeference instance from the Globe Anchor Component instead.
*/
UPROPERTY(
BlueprintReadOnly,
Category = "Cesium",
BlueprintGetter = GetGeoreference,
Meta =
(DeprecatedProperty,
DeprecationMessage =
"Get the Georeference instance from the Globe Anchor Component instead."))
ACesiumGeoreference* Georeference_DEPRECATED;
/**
* Gets the Georeference Actor associated with this instance. It is obtained
* from the Globe Anchor Component.
*/
UFUNCTION(BlueprintGetter, Category = "Cesium")
ACesiumGeoreference* GetGeoreference() const;
/**
* Set the Date at which DST starts in the current year.
*
* After changing this value from Blueprints or C++, you must call UpdateSun
* for it to take effect.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium|Date and Time|Daylight Savings",
meta = (ClampMin = 1, ClampMax = 12),
meta = (EditCondition = "UseDaylightSavingTime"))
int32 DSTStartMonth = 3;
/**
* Set the Date at which DST starts in the current year.
*
* After changing this value from Blueprints or C++, you must call UpdateSun
* for it to take effect.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium|Date and Time|Daylight Savings",
meta = (ClampMin = 1, ClampMax = 31),
meta = (EditCondition = "UseDaylightSavingTime"))
int32 DSTStartDay = 10;
/**
* Set the Date at which DST ends in the current year.
*
* After changing this value from Blueprints or C++, you must call UpdateSun
* for it to take effect.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium|Date and Time|Daylight Savings",
meta = (ClampMin = 1, ClampMax = 12),
meta = (EditCondition = "UseDaylightSavingTime"))
int32 DSTEndMonth = 11;
/**
* Set the Date at which DST ends in the current year.
*
* After changing this value from Blueprints or C++, you must call UpdateSun
* for it to take effect.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium|Date and Time|Daylight Savings",
meta = (ClampMin = 1, ClampMax = 31),
meta = (EditCondition = "UseDaylightSavingTime"))
int32 DSTEndDay = 3;
/**
* Hour of the DST Switch for both beginning and end.
*
* After changing this value from Blueprints or C++, you must call UpdateSun
* for it to take effect.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium|Date and Time|Daylight Savings",
meta = (ClampMin = 0, ClampMax = 23),
meta = (EditCondition = "UseDaylightSavingTime"))
int32 DSTSwitchHour = 2;
/**
* Updates the atmosphere automatically given current player pawn's longitude,
* latitude, and height. Fixes artifacts seen with the atmosphere rendering
* when flying high above the surface, or low to the ground in high latitudes.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium|Atmosphere")
bool UpdateAtmosphereAtRuntime = true;
/**
* When the player pawn is below this height, which is expressed in kilometers
* above the ellipsoid, this Actor will use an atmosphere ground radius that
* is calculated to be at or below the terrain surface at the player pawn's
* current location. This avoids a gap between the bottom of the atmosphere
* and the top of the terrain when zoomed in close to the terrain surface.
*
* Above CircumscribedGroundThreshold, this Actor will use an atmosphere
* ground radius that is guaranteed to be above the terrain surface anywhere
* on Earth. This avoids artifacts caused by terrain poking through the
* atmosphere when viewing the Earth from far away.
*
* At player pawn heights in between InscribedGroundThreshold and
* CircumscribedGroundThreshold, this Actor uses a linear interpolation
* between the two ground radii.
*
* This value is automatically scaled according to the CesiumGeoreference
* Scale and the Actor scale.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
meta = (EditCondition = "UpdateAtmosphereAtRuntime"),
Category = "Cesium|Atmosphere")
double InscribedGroundThreshold = 30.0;
/**
* When the player pawn is above this height, which is expressed in kilometers
* above the ellipsoid, this Actor will use an atmosphere ground radius that
* is guaranteed to be above the terrain surface anywhere on Earth. This
* avoids artifacts caused by terrain poking through the atmosphere when
* viewing the Earth from far away.
*
* Below InscribedGroundThreshold, this Actor will use an atmosphere
* ground radius that is calculated to be at or below the terrain surface at
* the player pawn's current location. This avoids a gap between the bottom of
* the atmosphere and the top of the terrain when zoomed in close to the
* terrain surface.
*
* At heights in between InscribedGroundThreshold and
* CircumscribedGroundThreshold, this Actor uses a linear interpolation
* between the two ground radii.
*
* This value is automatically scaled according to the CesiumGeoreference
* Scale and the Actor scale.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
meta = (EditCondition = "UpdateAtmosphereAtRuntime"),
Category = "Cesium|Atmosphere")
double CircumscribedGroundThreshold = 100.0;
/**
* The height at which to place the bottom of the atmosphere when the player
* pawn is above the CircumscribedGroundThreshold. This is expressed as a
* height in kilometers above the maximum radius of the ellipsoid (usually
* WGS84). To avoid dark splotchy artifacts in the atmosphere when zoomed out
* far from the globe, this value must be above the greatest height achieved
* by any part of the tileset.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
meta = (EditCondition = "UpdateAtmosphereAtRuntime"),
Category = "Cesium|Atmosphere")
double CircumscribedGroundHeight = 0.0;
/**
* The height of the atmosphere layer above the ground, in kilometers. This
* value is automatically scaled according to the CesiumGeoreference Scale and
* the Actor scale. However, Unreal Engine's SkyAtmosphere has a hard-coded
* minimum effective value of 0.1, so the atmosphere will look too thick when
* the globe is scaled down drastically.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadOnly,
interp,
Category = "Cesium|Atmosphere",
meta = (UIMin = 1.0, UIMax = 200.0, ClampMin = 0.1, SliderExponent = 2.0))
float AtmosphereHeight = 60.0f;
/**
* Makes the aerial perspective look thicker by scaling distances from view
* to surfaces (opaque and translucent). This value is automatically scaled
* according to the CesiumGeoreference Scale and the Actor scale.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadOnly,
interp,
Category = "Cesium|Atmosphere",
meta =
(DisplayName = "Aerial Perspective View Distance Scale",
UIMin = 0.0,
UIMax = 3.0,
ClampMin = 0.0,
SliderExponent = 2.0))
float AerialPerspectiveViewDistanceScale = 1.0f;
/**
* The altitude in kilometers at which Rayleigh scattering effect is reduced
* to 40%. This value is automatically scaled according to the
* CesiumGeoreference Scale and the Actor scale.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadOnly,
interp,
Category = "Cesium|Atmosphere",
meta =
(UIMin = 0.01, UIMax = 20.0, ClampMin = 0.001, SliderExponent = 5.0))
float RayleighExponentialDistribution = 8.0f;
/**
* The altitude in kilometers at which Mie effects are reduced to 40%. This
* value is automatically scaled according to the CesiumGeoreference Scale and
* the Actor scale.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadOnly,
interp,
Category = "Cesium|Atmosphere",
meta =
(UIMin = 0.01, UIMax = 10.0, ClampMin = 0.001, SliderExponent = 5.0))
float MieExponentialDistribution = 1.2f;
/**
* False: Use Directional Light component inside CesiumSunSky.
* True: Use the assigned Directional Light in the level.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium|Sun")
bool UseLevelDirectionalLight = false;
/**
* Reference to a manually assigned Directional Light in the level.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium|Sun")
ADirectionalLight* LevelDirectionalLight;
/**
* The current sun elevation in degrees above the horizontal, as viewed from
* the Georeference origin.
*/
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Sun")
double Elevation = 0.f;
/**
* The current sun elevation, corrected for atmospheric diffraction, in
* degrees above the horizontal, as viewed from the Georeference origin.
*/
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Sun")
double CorrectedElevation = 0.f;
/**
* The current sun azimuth in degrees clockwise from North toward East, as
* viewed from the Georeference origin.
*/
UPROPERTY(EditDefaultsOnly, BlueprintReadOnly, Category = "Sun")
double Azimuth = 0.f;
/**
* A switch to toggle between desktop and mobile rendering code paths.
* This will NOT be automatically set when running on mobile, so make sure
* to check this setting before building on mobile platforms.
*/
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Cesium|Mobile")
bool UseMobileRendering;
/**
* Mobile platforms currently do not support the SkyAtmosphereComponent.
* In lieu of that, use the engine BP_Sky_Sphere class, or a derived class.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium|Mobile")
TSubclassOf<AActor> SkySphereClass;
/**
* Reference to BP_Sky_Sphere or similar actor (mobile only)
*/
UPROPERTY(VisibleAnywhere, BlueprintReadWrite, Category = "Cesium|Mobile")
AActor* SkySphereActor;
/**
* Default intensity of directional light that's spawned for mobile rendering.
*/
UPROPERTY(EditAnywhere, BlueprintReadOnly, Category = "Cesium|Mobile")
double MobileDirectionalLightIntensity = 6.f;
public:
UFUNCTION(
CallInEditor,
BlueprintCallable,
BlueprintNativeEvent,
Category = "Cesium")
void UpdateSun();
void UpdateSun_Implementation();
UFUNCTION(CallInEditor, BlueprintCallable, Category = "Cesium")
void UpdateAtmosphereRadius();
/**
* Convert solar time to Hours:Minutes:Seconds. Copied the implementation
* from the engine SunSkyBP class.
*/
UFUNCTION(BlueprintCallable, BlueprintPure, Category = Sun)
static void GetHMSFromSolarTime(
double InSolarTime,
int32& Hour,
int32& Minute,
int32& Second);
/**
* Check whether the current time and date (based on this class instance's
* properties) falls within Daylight Savings Time. Copied the implementation
* from the engine SunSkyBP class.
*/
UFUNCTION(BlueprintCallable, BlueprintPure, Category = Sun)
bool IsDST(
bool DSTEnable,
int32 InDSTStartMonth,
int32 InDSTStartDay,
int32 InDSTEndMonth,
int32 InDSTEndDay,
int32 InDSTSwitchHour) const;
// Begin AActor Interface
/**
* Gets called when the actor is first created, and when properties are
* changed at edit-time. Refreshes the actor's position w/r/t the georeference
* and handles mobile-specific setup if needed.
*/
virtual void OnConstruction(const FTransform& Transform) override;
// End AActor Interface
protected:
/**
* Modifies the sky atmosphere's ground radius, which represents the Earth's
* radius in the SkyAtmosphere rendering model. Only changes if there's a >0.1
* difference, to reduce redraws.
*
* @param Sky A pointer to the SkyAtmosphereComponent
* @param Radius The radius in kilometers.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
void
SetSkyAtmosphereGroundRadius(USkyAtmosphereComponent* Sky, double Radius);
/**
* Update MobileSkySphere by calling its RefreshMaterial function
*/
UFUNCTION(BlueprintCallable, Category = "Mobile")
void UpdateSkySphere();
virtual void BeginPlay() override;
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
virtual void Serialize(FArchive& Ar) override;
virtual void Tick(float DeltaSeconds) override;
virtual void PostLoad() override;
virtual bool ShouldTickIfViewportsOnly() const override;
#if WITH_EDITOR
virtual void
PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
#endif
private:
void _spawnSkySphere();
double _computeScale() const;
// Sets Directional Light Component in Sky Sphere actor
void _setSkySphereDirectionalLight();
void _setSkyAtmosphereVisibility(bool bVisible);
// Determines whether mobile sky sphere will be spawned during OnConstruction.
bool _wantsSpawnMobileSkySphere;
void _handleTransformUpdated(
USceneComponent* InRootComponent,
EUpdateTransformFlags UpdateTransformFlags,
ETeleportType Teleport);
FDelegateHandle _transformUpdatedSubscription;
};

View File

@ -0,0 +1,47 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CoreMinimal.h"
#include <Cesium3DTilesSelection/BoundingVolume.h>
#include "CesiumTile.generated.h"
/**
* A UObject representation of a Cesium Tile.
* This class provides an interface for accessing properties of a Cesium Tile
* from within Unreal Engine. It exposes the Bounds property, which can be
* accessed from Blueprints, and provides a helper function for testing
* intersection with a primitive component.
*/
UCLASS()
class CESIUMRUNTIME_API UCesiumTile : public UPrimitiveComponent {
GENERATED_BODY()
glm::dmat4 _tileTransform;
Cesium3DTilesSelection::BoundingVolume _tileBounds =
CesiumGeometry::OrientedBoundingBox(glm::dvec3(0.0), glm::dmat3(1.0));
public:
/**
* Tests whether a primitive component overlaps with this tile using a sphere
* and box comparison. This function provides a convenient way to test for
* intersection between a primitive component and this tile.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
bool TileBoundsOverlapsPrimitive(const UPrimitiveComponent* Other) const;
/**
* Checks if this tile is fully inside the given primitive component using a
* sphere and box comparison. It uses the FBox::IsInside function to compare
* the FBox of the component and the tile's bounds.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
bool
PrimitiveBoxFullyContainsTileBounds(const UPrimitiveComponent* Other) const;
virtual FBoxSphereBounds
CalcBounds(const FTransform& LocalToWorld) const override;
friend class CesiumTileExcluderAdapter;
};

View File

@ -0,0 +1,76 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumTile.h"
#include "CoreMinimal.h"
#include "CesiumTileExcluder.generated.h"
class CesiumTileExcluderAdapter;
/**
* An actor component for excluding Cesium Tiles.
* This class provides an interface for excluding Cesium Tiles from a tileset.
* You can create a blueprint that derives from this class and override the
* `ShouldExclude` function to implement custom logic for determining whether a
* tile should be excluded. This function can be implemented in either C++ or
* Blueprints.
*/
UCLASS(
ClassGroup = (Cesium),
meta = (BlueprintSpawnableComponent),
Blueprintable,
Abstract)
class CESIUMRUNTIME_API UCesiumTileExcluder : public UActorComponent {
GENERATED_BODY()
private:
CesiumTileExcluderAdapter* pExcluderAdapter;
UPROPERTY()
UCesiumTile* CesiumTile;
public:
UCesiumTileExcluder(const FObjectInitializer& ObjectInitializer);
virtual void Activate(bool bReset) override;
virtual void Deactivate() override;
virtual void OnComponentDestroyed(bool bDestroyingHierarchy) override;
#if WITH_EDITOR
// Called when properties are changed in the editor
virtual void
PostEditChangeProperty(FPropertyChangedEvent& PropertyChangedEvent) override;
#endif
/**
* Adds this tile excluder to its owning Cesium 3D Tileset Actor. If the
* excluder is already added or if this component's Owner is not a Cesium 3D
* Tileset, this method does nothing.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
void AddToTileset();
/**
* Removes this tile excluder from its owning Cesium 3D Tileset Actor. If the
* excluder is not yet added or if this component's Owner is not a Cesium 3D
* Tileset, this method does nothing.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
void RemoveFromTileset();
/**
* Refreshes this tile excluderby removing from its owning Cesium 3D Tileset
* Actor and re-adding it. If this component's Owner is not a Cesium 3D
* Tileset Actor, this method does nothing.
*/
UFUNCTION(BlueprintCallable, Category = "Cesium")
void Refresh();
/**
* Determines whether a tile should be excluded.
* This function is called to determine whether a tile should be excluded from
* the tileset. You can override this function in a derived class or blueprint
* to implement custom exclusion logic.
*/
UFUNCTION(BlueprintNativeEvent)
bool ShouldExclude(const UCesiumTile* TileObject);
};

View File

@ -0,0 +1,58 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumRasterOverlay.h"
#include "Components/ActorComponent.h"
#include "CoreMinimal.h"
#include "CesiumTileMapServiceRasterOverlay.generated.h"
/**
* A raster overlay that directly accesses a Tile Map Service (TMS) server. If
* you're using a Tile Map Service via Cesium ion, use the "Cesium ion Raster
* Overlay" component instead.
*/
UCLASS(ClassGroup = (Cesium), meta = (BlueprintSpawnableComponent))
class CESIUMRUNTIME_API UCesiumTileMapServiceRasterOverlay
: public UCesiumRasterOverlay {
GENERATED_BODY()
public:
/**
* The base URL of the Tile Map Service (TMS).
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
FString Url;
/**
* True to directly specify minum and maximum zoom levels available from the
* server, or false to automatically determine the minimum and maximum zoom
* levels from the server's tilemapresource.xml file.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
bool bSpecifyZoomLevels = false;
/**
* Minimum zoom level.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium",
meta = (EditCondition = "bSpecifyZoomLevels", ClampMin = 0))
int32 MinimumLevel = 0;
/**
* Maximum zoom level.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium",
meta = (EditCondition = "bSpecifyZoomLevels", ClampMin = 0))
int32 MaximumLevel = 10;
protected:
virtual std::unique_ptr<CesiumRasterOverlays::RasterOverlay> CreateOverlay(
const CesiumRasterOverlays::RasterOverlayOptions& options = {}) override;
};

View File

@ -0,0 +1,81 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumRasterOverlay.h"
#include "Components/ActorComponent.h"
#include "CoreMinimal.h"
#include "CesiumWebMapServiceRasterOverlay.generated.h"
/**
* A raster overlay that directly accesses a Web Map Service (WMS) server.
* https://www.ogc.org/standards/wms
*/
UCLASS(ClassGroup = (Cesium), meta = (BlueprintSpawnableComponent))
class CESIUMRUNTIME_API UCesiumWebMapServiceRasterOverlay
: public UCesiumRasterOverlay {
GENERATED_BODY()
public:
/**
* The base url of the Web Map Service (WMS).
* e.g.
* https://services.ga.gov.au/gis/services/NM_Culture_and_Infrastructure/MapServer/WMSServer
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
FString BaseUrl;
/**
* Comma-separated layer names to request from the server.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
FString Layers;
/**
* Image width
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium",
meta = (ClampMin = 64, ClampMax = 2048))
int32 TileWidth = 256;
/**
* Image height
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium",
meta = (ClampMin = 64, ClampMax = 2048))
int32 TileHeight = 256;
/**
* Minimum zoom level.
*
* Take care when specifying this that the number of tiles at the minimum
* level is small, such as four or less. A larger number is likely to
* result in rendering problems.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium",
meta = (ClampMin = 0))
int32 MinimumLevel = 0;
/**
* Maximum zoom level.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium",
meta = (ClampMin = 0))
int32 MaximumLevel = 14;
protected:
virtual std::unique_ptr<CesiumRasterOverlays::RasterOverlay> CreateOverlay(
const CesiumRasterOverlays::RasterOverlayOptions& options = {}) override;
};

View File

@ -0,0 +1,275 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumRasterOverlay.h"
#include "Components/ActorComponent.h"
#include "CoreMinimal.h"
#include "CesiumWebMapTileServiceRasterOverlay.generated.h"
/**
* Specifies the type of projection used for projecting a Web Map Tile Service
* raster overlay.
*/
UENUM(BlueprintType)
enum class ECesiumWebMapTileServiceRasterOverlayProjection : uint8 {
/**
* The raster overlay is projected using Web Mercator.
*/
WebMercator,
/**
* The raster overlay is projected using a geographic projection.
*/
Geographic
};
/**
* A raster overlay that directly accesses a Web Map Tile Service (WMTS) server.
* If you're using a Web Map Tile Service via Cesium ion, use the "Cesium ion
* Raster Overlay" component instead.
*/
UCLASS(ClassGroup = (Cesium), meta = (BlueprintSpawnableComponent))
class CESIUMRUNTIME_API UCesiumWebMapTileServiceRasterOverlay
: public UCesiumRasterOverlay {
GENERATED_BODY()
public:
/**
* The base URL of the Web Map Tile Service (WMTS).
* This URL should not include query parameters. For example:
* https://tile.openstreetmap.org/{TileMatrix}/{TileCol}/{TileRow}.png
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
FString BaseUrl;
/**
* The layer name for WMTS requests.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
FString Layer;
/**
* The style name for WMTS requests.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
FString Style;
/**
* The MIME type for images to retrieve from the server.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
FString Format = "image/jpeg";
/**
* The tile matrix set identifier for WMTS requests.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
FString TileMatrixSetID;
/**
* The prefix to use for the tile matrix set labels. For instance, setting
* "EPSG:4326:" as prefix generates label list ["EPSG:4326:0", "EPSG:4326:1",
* "EPSG:4326:2", ...]
* Only applicable when "Specify Tile Matrix Set Labels" is false.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium",
meta = (EditCondition = "!bSpecifyTileMatrixSetLabels"))
FString TileMatrixSetLabelPrefix;
/**
* Set this to true to specify tile matrix set labels manually. If false, the
* labels will be constructed from the specified levels and prefix (if one is
* specified).
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
bool bSpecifyTileMatrixSetLabels = false;
/**
* The manually specified tile matrix set labels.
*
* Only applicable when "Specify Tile Matrix Set Labels" is true.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium",
meta = (EditCondition = "bSpecifyTileMatrixSetLabels"))
TArray<FString> TileMatrixSetLabels;
UPROPERTY(
meta =
(DeprecatedProperty, DeprecationMessage = "Use Projection instead."))
bool UseWebMercatorProjection_DEPRECATED;
/**
* The type of projection used to project the WMTS imagery onto the globe.
* For instance, EPSG:4326 uses geographic projection and EPSG:3857 uses Web
* Mercator.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
ECesiumWebMapTileServiceRasterOverlayProjection Projection =
ECesiumWebMapTileServiceRasterOverlayProjection::WebMercator;
/**
* Set this to true to specify the quadtree tiling scheme according to the
* specified root tile numbers and projected bounding rectangle. If false, the
* tiling scheme will be deduced from the projection.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
bool bSpecifyTilingScheme = false;
/**
* The number of tiles corresponding to TileCol, also known as
* TileMatrixWidth. If specified, this determines the number of tiles at the
* root of the quadtree tiling scheme in the X direction.
*
* Only applicable if "Specify Tiling Scheme" is set to true.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium",
meta = (EditCondition = "bSpecifyTilingScheme", ClampMin = 1))
int32 RootTilesX = 1;
/**
* The number of tiles corresponding to TileRow, also known as
* TileMatrixHeight. If specified, this determines the number of tiles at the
* root of the quadtree tiling scheme in the Y direction.
*
* Only applicable if "Specify Tiling Scheme" is set to true.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium",
meta = (EditCondition = "bSpecifyTilingScheme", ClampMin = 1))
int32 RootTilesY = 1;
/**
* The west boundary of the bounding rectangle used for the quadtree tiling
* scheme. Specified in longitude degrees in the range [-180, 180].
*
* Only applicable if "Specify Tiling Scheme" is set to true.
*/
UPROPERTY(
Category = "Cesium",
EditAnywhere,
BlueprintReadWrite,
meta =
(EditCondition = "bSpecifyTilingScheme",
ClampMin = -180.0,
ClampMax = 180.0))
double RectangleWest = -180;
/**
* The south boundary of the bounding rectangle used for the quadtree tiling
* scheme. Specified in latitude degrees in the range [-90, 90].
*
* Only applicable if "Specify Tiling Scheme" is set to true.
*/
UPROPERTY(
Category = "Cesium",
Category = "Cesium",
EditAnywhere,
BlueprintReadWrite,
meta =
(EditCondition = "bSpecifyTilingScheme",
ClampMin = -90.0,
ClampMax = 90.0))
double RectangleSouth = -90;
/**
* The east boundary of the bounding rectangle used for the quadtree tiling
* scheme. Specified in longitude degrees in the range [-180, 180].
*
* Only applicable if "Specify Tiling Scheme" is set to true.
*/
UPROPERTY(
Category = "Cesium",
EditAnywhere,
BlueprintReadWrite,
meta =
(EditCondition = "bSpecifyTilingScheme",
ClampMin = -180.0,
ClampMax = 180.0))
double RectangleEast = 180;
/**
* The north boundary of the bounding rectangle used for the quadtree tiling
* scheme. Specified in latitude degrees in the range [-90, 90].
*
* Only applicable if "Specify Tiling Scheme" is set to true.
*/
UPROPERTY(
Category = "Cesium",
EditAnywhere,
BlueprintReadWrite,
meta =
(EditCondition = "bSpecifyTilingScheme",
ClampMin = -90.0,
ClampMax = 90.0))
double RectangleNorth = 90;
/**
* Set this to true to directly specify the minimum and maximum zoom levels
* available from the server. If false, the minimum and maximum zoom levels
* will be retrieved from the server's tilemapresource.xml file.
*/
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Cesium")
bool bSpecifyZoomLevels = false;
/**
* Minimum zoom level.
*
* Take care when specifying this that the number of tiles at the minimum
* level is small, such as four or less. A larger number is likely to result
* in rendering problems.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium",
meta = (EditCondition = "bSpecifyZoomLevels", ClampMin = 0))
int32 MinimumLevel = 0;
/**
* Maximum zoom level.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium",
meta = (EditCondition = "bSpecifyZoomLevels", ClampMin = 0))
int32 MaximumLevel = 25;
/**
* The pixel width of the image tiles.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium",
meta = (ClampMin = 64, ClampMax = 2048))
int32 TileWidth = 256;
/**
* The pixel height of the image tiles.
*/
UPROPERTY(
EditAnywhere,
BlueprintReadWrite,
Category = "Cesium",
meta = (ClampMin = 64, ClampMax = 2048))
int32 TileHeight = 256;
virtual void Serialize(FArchive& Ar) override;
protected:
virtual std::unique_ptr<CesiumRasterOverlays::RasterOverlay> CreateOverlay(
const CesiumRasterOverlays::RasterOverlayOptions& options = {}) override;
};

View File

@ -0,0 +1,92 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumRuntime.h"
#include "Kismet/BlueprintFunctionLibrary.h"
#include "Misc/Optional.h"
#include "CesiumWgs84Ellipsoid.generated.h"
UCLASS()
class CESIUMRUNTIME_API UCesiumWgs84Ellipsoid
: public UBlueprintFunctionLibrary {
GENERATED_BODY()
public:
/**
* Gets the radii of the WGS84 ellipsoid in its x-, y-, and z-directions in
* meters.
*/
UFUNCTION(BlueprintPure, Category = "Cesium|Ellipsoid|WGS84")
static FVector GetRadii();
/**
* Gets the maximum radius of the WGS84 ellipsoid in any dimension, in meters.
*/
UFUNCTION(BlueprintPure, Category = "Cesium|Ellipsoid|WGS84")
static double GetMaximumRadius();
/**
* Gets the minimum radius of the WGS854 ellipsoid in any dimension, in
* meters.
*/
UFUNCTION(BlueprintPure, Category = "Cesium|Ellipsoid|WGS84")
static double GetMinimumRadius();
/**
* Scale the given Earth-Centered, Earth-Fixed position along the geodetic
* surface normal so that it is on the surface of the ellipsoid. If the
* position is near the center of the ellipsoid, the result will have the
* value (0,0,0) because the surface position is undefined.
*/
UFUNCTION(
BlueprintPure,
Category = "Cesium|Ellipsoid|WGS84",
meta = (ReturnDisplayName = "SurfacePosition"))
static FVector
ScaleToGeodeticSurface(const FVector& EarthCenteredEarthFixedPosition);
/**
* Computes the normal of the plane tangent to the surface of the ellipsoid
* at the provided Earth-Centered, Earth-Fixed position.
*/
UFUNCTION(
BlueprintPure,
Category = "Cesium|Ellipsoid|WGS84",
meta = (ReturnDisplayName = "SurfaceNormalVector"))
static FVector
GeodeticSurfaceNormal(const FVector& EarthCenteredEarthFixedPosition);
/**
* Convert longitude in degrees (X), latitude in degrees (Y), and height above
* the WGS84 ellipsoid in meters (Z) to Earth-Centered, Earth-Fixed (ECEF)
* coordinates.
*/
UFUNCTION(
BlueprintPure,
Category = "Cesium|Ellipsoid|WGS84",
meta = (ReturnDisplayName = "EarthCenteredEarthFixedPosition"))
static FVector LongitudeLatitudeHeightToEarthCenteredEarthFixed(
const FVector& LongitudeLatitudeHeight);
/**
* Convert Earth-Centered, Earth-Fixed (ECEF) coordinates to longitude in
* degrees (X), latitude in degrees (Y), and height above the WGS84 ellipsoid
* in meters (Z). If the position is near the center of the Earth, the result
* will have the value (0,0,0) because the longitude, latitude, and height are
* undefined.
*/
UFUNCTION(
BlueprintPure,
Category = "Cesium|Ellipsoid|WGS84",
meta = (ReturnDisplayName = "LongitudeLatitudeHeight"))
static FVector EarthCenteredEarthFixedToLongitudeLatitudeHeight(
const FVector& EarthCenteredEarthFixedPosition);
/**
* Computes the transformation matrix from the local East-North-Up (ENU) frame
* to Earth-Centered, Earth-Fixed (ECEF) at the specified ECEF location.
*/
static FMatrix EastNorthUpToEarthCenteredEarthFixed(
const FVector& EarthCenteredEarthFixedPosition);
};

View File

@ -0,0 +1,54 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include <Components/PrimitiveComponent.h>
#include <CoreMinimal.h>
#include "CustomDepthParameters.generated.h"
USTRUCT(BlueprintType)
struct CESIUMRUNTIME_API FCustomDepthParameters {
GENERATED_USTRUCT_BODY()
public:
/** If true, this component will be rendered in the CustomDepth pass (usually
* used for outlines) */
UPROPERTY(
EditAnywhere,
AdvancedDisplay,
BlueprintReadOnly,
Category = Rendering,
meta = (DisplayName = "Render CustomDepth Pass"))
bool RenderCustomDepth = false;
/** Mask used for stencil buffer writes. */
UPROPERTY(
EditAnywhere,
AdvancedDisplay,
BlueprintReadOnly,
Category = "Rendering",
meta = (EditCondition = "RenderCustomDepth"))
ERendererStencilMask CustomDepthStencilWriteMask =
ERendererStencilMask::ERSM_Default;
/** Optionally write this 0-255 value to the stencil buffer in CustomDepth
* pass (Requires project setting or r.CustomDepth == 3) */
UPROPERTY(
EditAnywhere,
AdvancedDisplay,
BlueprintReadOnly,
Category = Rendering,
meta = (UIMin = "0", UIMax = "255", EditCondition = "RenderCustomDepth"))
int32 CustomDepthStencilValue = 0;
bool operator==(const FCustomDepthParameters& other) const {
return RenderCustomDepth == other.RenderCustomDepth &&
CustomDepthStencilWriteMask == other.CustomDepthStencilWriteMask &&
CustomDepthStencilValue == other.CustomDepthStencilValue;
}
bool operator!=(const FCustomDepthParameters& other) const {
return !(*this == other);
}
};

View File

@ -0,0 +1,241 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumGeospatial/Ellipsoid.h"
#include "CesiumGeospatial/LocalHorizontalCoordinateSystem.h"
#include "HAL/Platform.h"
#include "Math/Matrix.h"
#include <glm/fwd.hpp>
#include <glm/vec3.hpp>
/**
* @brief A lightweight structure to encapsulate coordinate transforms.
*
* It encapsulates the conversions between...
* - Earth-Centered, Earth-Fixed (ECEF) coordinates
* - Georeferenced coordinates (Latitude/Longitude/Height)
* - Unreal coordinates (relative to the unreal world origin)
*
*/
class CESIUMRUNTIME_API GeoTransforms {
public:
/**
* @brief Creates a new instance.
*/
GeoTransforms();
/**
* @brief Creates a new instance.
*
* The center position is the position of the origin of the
* local coordinate system that is established by this instance.
*
* @param ellipsoid The ellipsoid to use for the georeferenced coordinates
* @param center The center position.
* @param scale The scale factor of the globe in the Unreal world.
*/
GeoTransforms(
const CesiumGeospatial::Ellipsoid& ellipsoid,
const glm::dvec3& center,
double scale);
/**
* @brief Set the center position of this instance
*
* The center position is the position of the origin of the
* local coordinate system that is established by this instance.
*
* @param center The center position.
*/
void setCenter(const glm::dvec3& center) noexcept;
/**
* @brief Set the ellipsoid of this instance
*
* @param ellipsoid The ellipsoid
*/
void setEllipsoid(const CesiumGeospatial::Ellipsoid& ellipsoid) noexcept;
/**
* Transforms the given longitude in degrees (x), latitude in
* degrees (y), and height in meters (z) into Earth-Centered, Earth-Fixed
* (ECEF) coordinates.
*/
glm::dvec3 TransformLongitudeLatitudeHeightToEcef(
const glm::dvec3& LongitudeLatitudeHeight) const noexcept;
/**
* Transforms the given Earth-Centered, Earth-Fixed (ECEF) coordinates into
* longitude in degrees (x), latitude in degrees (y), and height in
* meters (z).
*/
glm::dvec3
TransformEcefToLongitudeLatitudeHeight(const glm::dvec3& Ecef) const noexcept;
/**
* Transforms the given longitude in degrees (x), latitude in
* degrees (y), and height in meters (z) into Unreal world coordinates
* (relative to the floating origin).
*/
glm::dvec3 TransformLongitudeLatitudeHeightToUnreal(
const glm::dvec3& origin,
const glm::dvec3& LongitudeLatitudeHeight) const noexcept;
/**
* Transforms Unreal world coordinates (relative to the floating origin) into
* longitude in degrees (x), latitude in degrees (y), and height in
* meters (z).
*/
glm::dvec3 TransformUnrealToLongitudeLatitudeHeight(
const glm::dvec3& origin,
const glm::dvec3& Ue) const noexcept;
/**
* Transforms the given point from Earth-Centered, Earth-Fixed (ECEF) into
* Unreal world coordinates (relative to the floating origin).
*/
glm::dvec3 TransformEcefToUnreal(
const glm::dvec3& origin,
const glm::dvec3& Ecef) const noexcept;
/**
* Transforms the given point from Unreal world coordinates (relative to the
* floating origin) to Earth-Centered, Earth-Fixed (ECEF).
*/
glm::dvec3 TransformUnrealToEcef(
const glm::dvec3& origin,
const glm::dvec3& Ue) const noexcept;
/**
* Transforms a rotator from Unreal world to East-South-Up at the given
* Unreal relative world location (relative to the floating origin).
*/
glm::dquat TransformRotatorUnrealToEastSouthUp(
const glm::dvec3& origin,
const glm::dquat& UeRotator,
const glm::dvec3& UeLocation) const noexcept;
/**
* Transforms a rotator from East-South-Up to Unreal world at the given
* Unreal world location (relative to the floating origin).
*/
glm::dquat TransformRotatorEastSouthUpToUnreal(
const glm::dvec3& origin,
const glm::dquat& EnuRotator,
const glm::dvec3& UeLocation) const noexcept;
/**
* Computes the rotation matrix from the local East-South-Up to Unreal at the
* specified Unreal world location (relative to the floating
* origin). The returned transformation works in Unreal's left-handed
* coordinate system.
*/
glm::dmat4 ComputeEastSouthUpToUnreal(
const glm::dvec3& origin,
const glm::dvec3& Ue) const noexcept;
/**
* Computes the rotation matrix from the local East-North-Up to
* Earth-Centered, Earth-Fixed (ECEF) at the specified ECEF location.
*/
glm::dmat3 ComputeEastNorthUpToEcef(const glm::dvec3& Ecef) const noexcept;
/*
* GEOREFERENCE TRANSFORMS
*/
/**
* @brief Gets the transformation from the _absolute_ "Unreal World" reference
* frame to the "Ellipsoid-centered" reference frame (i.e. ECEF).
*
* Gets a matrix that transforms coordinates from the absolute "Unreal World"
* reference frame (with respect to the absolute world origin, not the
* floating origin) to the "Ellipsoid-centered" reference frame (which is
* usually Earth-centered, Earth-fixed). See {@link reference-frames.md}.
*/
const glm::dmat4&
GetAbsoluteUnrealWorldToEllipsoidCenteredTransform() const noexcept {
return this->_coordinateSystem.getLocalToEcefTransformation();
}
/**
* @brief Gets the transformation from the "Ellipsoid-centered" reference
* frame (i.e. ECEF) to the absolute "Unreal World" reference frame.
*
* Gets a matrix that transforms coordinates from the "Ellipsoid-centered"
* reference frame (which is usually Earth-centered, Earth-fixed) to the
* absolute "Unreal world" reference frame (with respect to the absolute world
* origin, not the floating origin). See {@link reference-frames.md}.
*/
const glm::dmat4&
GetEllipsoidCenteredToAbsoluteUnrealWorldTransform() const noexcept {
return this->_coordinateSystem.getEcefToLocalTransformation();
}
/**
* @brief Computes the normal of the plane tangent to the surface of the
* ellipsoid that is used by this instance, at the provided position.
*
* @param position The cartesian position for which to to determine the
* surface normal.
* @return The normal.
*/
glm::dvec3 ComputeGeodeticSurfaceNormal(const glm::dvec3& position) const {
return _ellipsoid.geodeticSurfaceNormal(position);
}
/**
* Computes the rotation in ellipsoid surface normal between an old position
* and a new position. This rotation is expressed in terms of Unreal world
* coordinates, and can be used to maintain an object's orientation relative
* to the local horizontal as it moves over the globe.
*
* @param oldPosition The old ECEF position that the object moved from.
* @param newPosition The new ECEF position that the object moved to.
* @return The rotation from the ellipsoid surface normal at the old position
* to the ellipsoid surface normal at the new position.
*/
glm::dquat ComputeSurfaceNormalRotation(
const glm::dvec3& oldPosition,
const glm::dvec3& newPosition) const;
/**
* Computes the rotation in ellipsoid surface normal between an old position
* and a new position. This rotation is expressed in terms of Unreal world
* coordinates, and can be used to maintain an object's orientation relative
* to the local horizontal as it moves over the globe.
*
* @param oldPosition The old ECEF position that the object moved from.
* @param newPosition The new ECEF position that the object moved to.
* @return The rotation from the ellipsoid surface normal at the old position
* to the ellipsoid surface normal at the new position.
*/
glm::dquat ComputeSurfaceNormalRotationUnreal(
const glm::dvec3& oldPosition,
const glm::dvec3& newPosition) const;
const FMatrix& GetEllipsoidCenteredToAbsoluteUnrealWorldMatrix() const {
return this->_ecefToUnreal;
}
const FMatrix& GetAbsoluteUnrealWorldToEllipsoidCenteredMatrix() const {
return this->_unrealToEcef;
}
private:
/**
* Update the derived state (i.e. the local horizontal coordinate system) when
* either the center or the ellipsoid has changed.
*/
void updateTransforms() noexcept;
CesiumGeospatial::LocalHorizontalCoordinateSystem _coordinateSystem;
// Modifiable state
CesiumGeospatial::Ellipsoid _ellipsoid;
glm::dvec3 _center;
double _scale;
FMatrix _ecefToUnreal;
FMatrix _unrealToEcef;
};

View File

@ -0,0 +1,249 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumGeospatial/Ellipsoid.h"
#include "CoreMinimal.h"
#include "GameFramework/DefaultPawn.h"
#include <glm/mat3x3.hpp>
#include <glm/vec3.hpp>
#include <vector>
#include "GlobeAwareDefaultPawn.generated.h"
class ACesiumGeoreference;
class UCesiumGlobeAnchorComponent;
class UCurveFloat;
class UCesiumFlyToComponent;
/**
* The delegate for when the pawn finishes flying
* which is triggered from _handleFlightStep
*/
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FCompletedFlight);
/**
* The delegate for when the pawn's flying is interrupted
* which is triggered from _interruptFlight
*/
DECLARE_DYNAMIC_MULTICAST_DELEGATE(FInterruptedFlight);
/**
* This pawn can be used to easily move around the globe while maintaining a
* sensible orientation. As the pawn moves across the horizon, it automatically
* changes its own up direction such that the world always looks right-side up.
*/
UCLASS()
class CESIUMRUNTIME_API AGlobeAwareDefaultPawn : public ADefaultPawn {
GENERATED_BODY()
public:
AGlobeAwareDefaultPawn();
/**
* Input callback to move forward in local space (or backward if Val is
* negative).
* @param Val Amount of movement in the forward direction (or backward if
* negative).
* @see APawn::AddMovementInput()
*/
virtual void MoveForward(float Val) override;
/**
* Input callback to strafe right in local space (or left if Val is negative).
* @param Val Amount of movement in the right direction (or left if negative).
* @see APawn::AddMovementInput()
*/
virtual void MoveRight(float Val) override;
/**
* Input callback to move up in world space (or down if Val is negative).
* @param Val Amount of movement in the world up direction (or down if
* negative).
* @see APawn::AddMovementInput()
*/
virtual void MoveUp_World(float Val) override;
/**
* Gets the absolute rotation of the camera view from the Unreal world.
*/
virtual FRotator GetViewRotation() const override;
/**
* Gets the rotation of the aim direction, which is the same as the View
* Rotation.
*/
virtual FRotator GetBaseAimRotation() const override;
UPROPERTY(
meta =
(DeprecatedProperty,
DeprecationMessage =
"FlyToGranularityDegrees has been deprecated. This property no longer needs to be set."))
float FlyToGranularityDegrees_DEPRECATED = 0.01f;
UPROPERTY(
BlueprintAssignable,
meta =
(DeprecatedProperty,
DeprecationMessage =
"Use OnFlightComplete on CesiumFlyToComponent instead."))
FCompletedFlight OnFlightComplete_DEPRECATED;
UPROPERTY(
BlueprintAssignable,
meta =
(DeprecatedProperty,
DeprecationMessage =
"Use OnFlightInterrupted on CesiumFlyToComponent instead."))
FInterruptedFlight OnFlightInterrupt_DEPRECATED;
/**
* Gets the transformation from globe's reference frame to the Unreal world
* (relative to the floating origin). This is equivalent to calling
* GetActorTransform on this pawn's attach parent, if it has one. If this pawn
* does not have an attach parent, an identity transformation is returned.
*/
UFUNCTION(BlueprintPure, Category = "Cesium")
const FTransform& GetGlobeToUnrealWorldTransform() const;
/**
* Begin a smooth camera flight to the given Earth-Centered, Earth-Fixed
* (ECEF) destination such that the camera ends at the specified yaw and
* pitch. The characteristics of the flight can be configured with
* {@see FlyToAltitudeProfileCurve}, {@see FlyToProgressCurve},
* {@see FlyToMaximumAltitudeCurve}, and {@see FlyToDuration}
*/
UFUNCTION(
BlueprintCallable,
meta =
(DeprecatedFunction,
DeprecationMessage =
"Use FlyToEarthCenteredEarthFixed on CesiumFlyToComponent instead."))
void FlyToLocationECEF(
const FVector& ECEFDestination,
double YawAtDestination,
double PitchAtDestination,
bool CanInterruptByMoving);
/**
* Begin a smooth camera flight to the given WGS84 longitude in degrees (x),
* latitude in degrees (y), and height in meters (z) such that the camera
* ends at the given yaw and pitch. The characteristics of the flight can be
* configured with {@see FlyToAltitudeProfileCurve},
* {@see FlyToProgressCurve}, {@see FlyToMaximumAltitudeCurve},
* {@see FlyToDuration}, and {@see FlyToGranularityDegrees}.
*/
UFUNCTION(
BlueprintCallable,
meta =
(DeprecatedFunction,
DeprecationMessage =
"Use FlyToLocationLongitudeLatitudeHeight on CesiumFlyToComponent instead."))
void FlyToLocationLongitudeLatitudeHeight(
const FVector& LongitudeLatitudeHeightDestination,
double YawAtDestination,
double PitchAtDestination,
bool CanInterruptByMoving);
protected:
virtual void Serialize(FArchive& Ar) override;
virtual void PostLoad() override;
/**
* THIS PROPERTY IS DEPRECATED.
*
* Get the Georeference instance from the Globe Anchor Component instead.
*/
UPROPERTY(
Category = "Cesium",
BlueprintReadOnly,
BlueprintGetter = GetGeoreference,
Meta =
(DeprecatedProperty,
DeprecationMessage =
"Get the Georeference instance from the Globe Anchor Component instead."))
ACesiumGeoreference* Georeference_DEPRECATED;
/**
* Gets the Georeference Actor associated with this instance. It is obtained
* from the Globe Anchor Component.
*/
UFUNCTION(BlueprintGetter, Category = "Cesium")
ACesiumGeoreference* GetGeoreference() const;
/**
* The Globe Anchor Component that precisely ties this Pawn to the Globe.
*/
UPROPERTY(VisibleAnywhere, BlueprintReadOnly, Category = "Cesium")
UCesiumGlobeAnchorComponent* GlobeAnchor;
private:
UPROPERTY(
Category = "Cesium",
BlueprintGetter = GetFlyToProgressCurve_DEPRECATED,
BlueprintSetter = SetFlyToProgressCurve_DEPRECATED,
meta =
(AllowPrivateAccess,
DeprecatedProperty,
DeprecationMessage =
"Use ProgressCurve on CesiumFlyToComponent instead."))
UCurveFloat* FlyToProgressCurve_DEPRECATED;
UFUNCTION(BlueprintGetter)
UCurveFloat* GetFlyToProgressCurve_DEPRECATED() const;
UFUNCTION(BlueprintSetter)
void SetFlyToProgressCurve_DEPRECATED(UCurveFloat* NewValue);
UPROPERTY(
Category = "Cesium",
BlueprintGetter = GetFlyToAltitudeProfileCurve_DEPRECATED,
BlueprintSetter = SetFlyToAltitudeProfileCurve_DEPRECATED,
meta =
(AllowPrivateAccess,
DeprecatedProperty,
DeprecationMessage =
"Use HeightPercentageCurve on CesiumFlyToComponent instead."))
UCurveFloat* FlyToAltitudeProfileCurve_DEPRECATED;
UFUNCTION(BlueprintGetter)
UCurveFloat* GetFlyToAltitudeProfileCurve_DEPRECATED() const;
UFUNCTION(BlueprintSetter)
void SetFlyToAltitudeProfileCurve_DEPRECATED(UCurveFloat* NewValue);
UPROPERTY(
Category = "Cesium",
BlueprintGetter = GetFlyToMaximumAltitudeCurve_DEPRECATED,
BlueprintSetter = SetFlyToMaximumAltitudeCurve_DEPRECATED,
meta =
(AllowPrivateAccess,
DeprecatedProperty,
DeprecationMessage =
"Use MaximumHeightByDistanceCurve on CesiumFlyToComponent instead."))
UCurveFloat* FlyToMaximumAltitudeCurve_DEPRECATED;
UFUNCTION(BlueprintGetter)
UCurveFloat* GetFlyToMaximumAltitudeCurve_DEPRECATED() const;
UFUNCTION(BlueprintSetter)
void SetFlyToMaximumAltitudeCurve_DEPRECATED(UCurveFloat* NewValue);
UPROPERTY(
Category = "Cesium",
BlueprintGetter = GetFlyToDuration_DEPRECATED,
BlueprintSetter = SetFlyToDuration_DEPRECATED,
meta =
(AllowPrivateAccess,
DeprecatedProperty,
DeprecationMessage =
"Use Duration on CesiumFlyToComponent instead."))
float FlyToDuration_DEPRECATED = 5.0f;
UFUNCTION(BlueprintGetter)
float GetFlyToDuration_DEPRECATED() const;
UFUNCTION(BlueprintSetter)
void SetFlyToDuration_DEPRECATED(float NewValue);
void _moveAlongViewAxis(EAxis::Type axis, double Val);
void _moveAlongVector(const FVector& axis, double Val);
UFUNCTION()
void _onFlightComplete();
UFUNCTION()
void _onFlightInterrupted();
};

View File

@ -0,0 +1,31 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CoreMinimal.h"
#include "GameFramework/Actor.h"
#include "OriginPlacement.generated.h"
/**
* An enumeration of the possible strategies for placing the origin of
* a Georeference.
*/
UENUM(BlueprintType)
enum class EOriginPlacement : uint8 {
/**
* Use the tileset's true origin as the Actor's origin. For georeferenced
* tilesets, this usually means the Actor's origin will be at the center
* of the Earth, which is not recommended. For a non-georeferenced tileset,
* however, such as a detailed building with a local origin, putting the
* Actor's origin at the same location as the tileset's origin can be useful.
*/
TrueOrigin UMETA(DisplayName = "True origin"),
/**
* Use a custom position within the tileset as the Actor's origin. The
* position is expressed as a longitude, latitude, and height, and that
* position within the tileset will be at coordinate (0,0,0) in the Actor's
* coordinate system.
*/
CartographicOrigin UMETA(DisplayName = "Longitude / latitude / height")
};

View File

@ -0,0 +1,41 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumAsync/AsyncSystem.h"
#include "CesiumAsync/IAssetAccessor.h"
#include "Containers/Map.h"
#include "Containers/UnrealString.h"
#include "HAL/Platform.h"
#include <cstddef>
class CESIUMRUNTIME_API UnrealAssetAccessor
: public CesiumAsync::IAssetAccessor {
public:
UnrealAssetAccessor();
virtual CesiumAsync::Future<std::shared_ptr<CesiumAsync::IAssetRequest>>
get(const CesiumAsync::AsyncSystem& asyncSystem,
const std::string& url,
const std::vector<CesiumAsync::IAssetAccessor::THeader>& headers)
override;
virtual CesiumAsync::Future<std::shared_ptr<CesiumAsync::IAssetRequest>>
request(
const CesiumAsync::AsyncSystem& asyncSystem,
const std::string& verb,
const std::string& url,
const std::vector<CesiumAsync::IAssetAccessor::THeader>& headers,
const std::span<const std::byte>& contentPayload) override;
virtual void tick() noexcept override;
private:
CesiumAsync::Future<std::shared_ptr<CesiumAsync::IAssetRequest>> getFromFile(
const CesiumAsync::AsyncSystem& asyncSystem,
const std::string& url,
const std::vector<CesiumAsync::IAssetAccessor::THeader>& headers);
FString _userAgent;
TMap<FString, FString> _cesiumRequestHeaders;
};

View File

@ -0,0 +1,132 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumGltf/PropertyTypeTraits.h"
#include "CesiumMetadataValueType.h"
#include "CesiumUtility/JsonValue.h"
#include <cstdlib>
#include <glm/common.hpp>
#include <type_traits>
enum class ECesiumEncodedMetadataComponentType : uint8;
/**
* @brief Converts a FCesiumMetadataValueType to the best-fitting Blueprints
* type.
*
* @param ValueType The input metadata value type.
*/
ECesiumMetadataBlueprintType
CesiumMetadataValueTypeToBlueprintType(FCesiumMetadataValueType ValueType);
// Deprecated.
ECesiumMetadataBlueprintType CesiumMetadataTrueTypeToBlueprintType(
ECesiumMetadataTrueType_DEPRECATED trueType);
// For backwards compatibility.
ECesiumMetadataTrueType_DEPRECATED
CesiumMetadataValueTypeToTrueType(FCesiumMetadataValueType ValueType);
static const std::string VectorComponents = "XYZW";
struct UnrealMetadataConversions {
public:
static FIntPoint toIntPoint(const glm::ivec2& vec2);
/**
* Converts a std::string_view to a FIntPoint. This expects the values to be
* written in the "X=... Y=..." format. If this function fails to parse
* a FIntPoint, the default value is returned.
*/
static FIntPoint
toIntPoint(const std::string_view& string, const FIntPoint& defaultValue);
static FVector2D toVector2D(const glm::dvec2& vec2);
/**
* Converts a std::string_view to a FVector2D. This uses
* FVector2D::InitFromString, which expects the values to be written in the
* "X=... Y=..." format. If this function fails to parse a FVector2D, the
* default value is returned.
*/
static FVector2D
toVector2D(const std::string_view& string, const FVector2D& defaultValue);
static FIntVector toIntVector(const glm::ivec3& vec3);
/**
* Converts a std::string_view to a FIntVector. This expects the values to be
* written in the "X=... Y=... Z=..." format. If this function fails to parse
* a FIntVector, the default value is returned.
*
* @param string The std::string_view to be parsed.
* @param defaultValue The default value to be returned if conversion fails.
*/
static FIntVector
toIntVector(const std::string_view& string, const FIntVector& defaultValue);
static FVector3f toVector3f(const glm::vec3& vec3);
static FVector3f
toVector3f(const std::string_view& string, const FVector3f& defaultValue);
static FVector toVector(const glm::dvec3& vec3);
static FVector
toVector(const std::string_view& string, const FVector& defaultValue);
static FVector4 toVector4(const glm::dvec4& vec4);
static FVector4
toVector4(const std::string_view& string, const FVector4& defaultValue);
static FMatrix toMatrix(const glm::dmat4& mat4);
/**
* Converts a glm::vecN to a FString. This follows the format that ToString()
* functions call on the Unreal vector equivalents. For example, a glm::vec3
* will return a string in the format "X=... Y=... Z=...".
*
* @param from The glm::vecN to be converted.
*/
template <glm::length_t N, typename T>
static FString toString(const glm::vec<N, T>& from) {
std::string result;
for (glm::length_t i = 0; i < N; i++) {
if (i > 0) {
result += " ";
}
result += VectorComponents[i];
result += "=";
result += std::to_string(from[i]);
}
return FString(result.c_str());
}
/**
* Converts a glm::matN to a FString. This follows the format that ToString()
* functions call on the Unreal matrix equivalents. Each row is
* returned in square brackets, e.g. "[1 2 3 4]", with spaces in-between.
*
* @param from The glm::matN to be converted.
*/
template <glm::length_t N, typename T>
static FString toString(const glm::mat<N, N, T>& from) {
std::string result;
// glm::matNs are column-major, but Unreal matrices are row-major and print
// their values by row.
for (glm::length_t r = 0; r < N; r++) {
if (r > 0) {
result += " ";
}
result += "[";
for (glm::length_t c = 0; c < N; c++) {
if (c > 0) {
result += " ";
}
result += std::to_string(from[c][r]);
}
result += "]";
}
return FString(result.c_str());
}
static FString toString(const std::string_view& from);
static FString toString(const std::string& from);
};

View File

@ -0,0 +1,12 @@
// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#pragma once
#include "CesiumAsync/ITaskProcessor.h"
#include "HAL/Platform.h"
class CESIUMRUNTIME_API UnrealTaskProcessor
: public CesiumAsync::ITaskProcessor {
public:
virtual void startTask(std::function<void()> f) override;
};