Here is where I am creating the polygon.
One thing to keep in mind is that I am still having a problem with my vector rotation.
I need vecLoc1 and vecLoc2 to be in line with one another… But other than that, this will take two vector location, a width and create a 4 point rectangle polygon. Right now I have debug code in place to draw spheres and lines between the points.
I JUST NOTICED ONE ISSUE WITH THIS
IF, at runtime, you change your CesiumGeoReference to a completely different geo location at runtime, those cuts in the terrain follow you. So, I need to figure out how to 100% refresh the cesium terrain. And that I am not sure about… Maybe it’s as simple as removing the ACesiumCartographicPolygon from the UCesiumPolygonRasterOverlay then calling Refresh on the tileset??? Not sure yet, will have to try it when I get a chance, but I can’t right this second, off to another meeting.
bool ACesiumUtility::Generate4PtPolygon(FVector* vecLoc1, FVector* vecLoc2, USplineComponent* polygon, float widthMeters)
{
bool bRetVal = false;
// Ensure all objects are valid
if (!vecLoc1 || !vecLoc2 || !polygon)
{
return bRetVal;
}
FVector run1Vec = *vecLoc1;
FVector run2Vec = *vecLoc2;
float halfWidth = (widthMeters / 2) * 100;
FVector pt1 = FVector(run1Vec);
FVector pt2 = FVector(run1Vec);
FVector pt3 = FVector(run2Vec);
FVector pt4 = FVector(run2Vec);
// Bottom left
pt1.X = run1Vec.X - halfWidth;
// bottom right
pt2.X = run1Vec.X + halfWidth;
// top left
pt3.X = run2Vec.X + halfWidth;
// top right
pt4.X = run2Vec.X - halfWidth;
if (GetWorld())
{
// For debugging purposes only
DrawDebugSphere(GetWorld(), pt1, 200.f, 12, FColor::Magenta, true);
DrawDebugSphere(GetWorld(), pt2, 200.f, 12, FColor::Yellow, true);
DrawDebugSphere(GetWorld(), pt3, 200.f, 12, FColor::Green, true);
DrawDebugSphere(GetWorld(), pt4, 200.f, 12, FColor::Blue, true);
DrawDebugLine(GetWorld(), pt1, pt2, FColor::Magenta, true);
DrawDebugLine(GetWorld(), pt2, pt3, FColor::Yellow, true);
DrawDebugLine(GetWorld(), pt3, pt4, FColor::Green, true);
DrawDebugLine(GetWorld(), pt4, pt1, FColor::Blue, true);
}
polygon->ClearSplinePoints();
polygon->AddSplinePoint(pt1, ESplineCoordinateSpace::Local);
polygon->AddSplinePoint(pt2, ESplineCoordinateSpace::Local);
polygon->AddSplinePoint(pt3, ESplineCoordinateSpace::Local);
polygon->AddSplinePoint(pt4, ESplineCoordinateSpace::Local);
polygon->SetClosedLoop(true);
UE_LOG(LogTemp, Warning, TEXT("POLYGON SPLINE POINT COUNT = %d"), polygon->GetNumberOfSplinePoints());
return polygon->GetNumberOfSplinePoints() == 4;
}
here is where I am actually punching a hole into the cesium terrain. It uses the polygon created in the function above.
// Accepts a 4 point polygon and punches a hole in the cesium terrain at that location.
bool ACesiumUtility::PunchPolygonHole( USplineComponent* polygon )
{
bool bRetVal = false;
if (!CesiumTileSet || !GetWorld() )
{
return bRetVal;
}
FVector loc = CesiumGeoreference->GetActorLocation();
FRotator rot = CesiumGeoreference->GetActorRotation();
FActorSpawnParameters params;
ACesiumCartographicPolygon* rectPoly = GetWorld()->SpawnActor<ACesiumCartographicPolygon>(loc, rot, params);
if( rectPoly )
{
rectPoly->Polygon = polygon;
UCesiumPolygonRasterOverlay* runwayRasterOverlay = CesiumTileSet->GetComponentByClass<UCesiumPolygonRasterOverlay>();
if (runwayRasterOverlay)
{
runwayRasterOverlay->Polygons.Add(rectPoly);
CesiumTileSet->RefreshTileset();
bRetVal = true;
}
}
return bRetVal;
}