bmh/FlightSimulation/Plugins/CesiumForUnreal_5.4/Source/CesiumRuntime/Public/CesiumFlyToComponent.h
2025-02-07 22:52:32 +08:00

222 lines
7.9 KiB
C++

// 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;
};