bmh/FlightSimulation/Plugins/CesiumForUnreal_5.4/Source/CesiumRuntime/Private/CesiumCartographicPolygon.cpp
2025-02-07 22:52:32 +08:00

90 lines
2.9 KiB
C++

// Copyright 2020-2024 CesiumGS, Inc. and Contributors
#include "CesiumCartographicPolygon.h"
#include "CesiumActors.h"
#include "CesiumUtility/Math.h"
#include "Components/SceneComponent.h"
#include "StaticMeshResources.h"
#include <glm/glm.hpp>
using namespace CesiumGeospatial;
ACesiumCartographicPolygon::ACesiumCartographicPolygon() : AActor() {
PrimaryActorTick.bCanEverTick = false;
this->Polygon = CreateDefaultSubobject<USplineComponent>(TEXT("Selection"));
this->SetRootComponent(this->Polygon);
this->Polygon->SetClosedLoop(true);
this->Polygon->SetMobility(EComponentMobility::Movable);
this->Polygon->SetSplinePoints(
TArray<FVector>{
FVector(-10000.0f, -10000.0f, 0.0f),
FVector(10000.0f, -10000.0f, 0.0f),
FVector(10000.0f, 10000.0f, 0.0f),
FVector(-10000.0f, 10000.0f, 0.0f)},
ESplineCoordinateSpace::Local);
this->MakeLinear();
#if WITH_EDITOR
this->SetIsSpatiallyLoaded(false);
#endif
this->GlobeAnchor =
CreateDefaultSubobject<UCesiumGlobeAnchorComponent>(TEXT("GlobeAnchor"));
}
void ACesiumCartographicPolygon::OnConstruction(const FTransform& Transform) {
this->MakeLinear();
}
void ACesiumCartographicPolygon::BeginPlay() {
Super::BeginPlay();
this->MakeLinear();
}
CesiumGeospatial::CartographicPolygon
ACesiumCartographicPolygon::CreateCartographicPolygon(
const FTransform& worldToTileset) const {
int32 splinePointsCount = this->Polygon->GetNumberOfSplinePoints();
if (splinePointsCount < 3) {
return CartographicPolygon({});
}
std::vector<glm::dvec2> polygon(splinePointsCount);
// The spline points should be located in the tileset _exactly where they
// appear to be_. The way we do that is by getting their world position, and
// then transforming that world position to a Cesium3DTileset local position.
// That way if the tileset is transformed relative to the globe, the polygon
// will still affect the tileset where the user thinks it should.
for (size_t i = 0; i < splinePointsCount; ++i) {
const FVector& unrealPosition = worldToTileset.TransformPosition(
this->Polygon->GetLocationAtSplinePoint(
i,
ESplineCoordinateSpace::World));
FVector cartographic =
this->GlobeAnchor->ResolveGeoreference()
->TransformUnrealPositionToLongitudeLatitudeHeight(unrealPosition);
polygon[i] =
glm::dvec2(glm::radians(cartographic.X), glm::radians(cartographic.Y));
}
return CartographicPolygon(polygon);
}
void ACesiumCartographicPolygon::MakeLinear() {
// set spline point types to linear for all points.
for (size_t i = 0; i < this->Polygon->GetNumberOfSplinePoints(); ++i) {
this->Polygon->SetSplinePointType(i, ESplinePointType::Linear);
}
}
void ACesiumCartographicPolygon::PostLoad() {
Super::PostLoad();
if (CesiumActors::shouldValidateFlags(this))
CesiumActors::validateActorFlags(this);
}