bool FBeginModifyLandscapeCommand::Update() { //Find the landscape FEdModeLandscape* LandscapeEdMode = (FEdModeLandscape*)GLevelEditorModeTools().GetActiveMode(FBuiltinEditorModes::EM_Landscape); //Find a location on the edge of the landscape along the x axis so the default camera can see it in the distance. FVector LandscapeSizePerComponent = LandscapeEdMode->UISettings->NewLandscape_QuadsPerSection * LandscapeEdMode->UISettings->NewLandscape_SectionsPerComponent * LandscapeEdMode->UISettings->NewLandscape_Scale; FVector TargetLoctaion(0); TargetLoctaion.X = -LandscapeSizePerComponent.X * (LandscapeEdMode->UISettings->NewLandscape_ComponentCount.X / 2); ALandscapeProxy* Proxy = LandscapeEdMode->CurrentToolTarget.LandscapeInfo.Get()->GetCurrentLevelLandscapeProxy(true); if (Proxy) { TargetLoctaion = Proxy->LandscapeActorToWorld().InverseTransformPosition(TargetLoctaion); } //Begin using the sculpting tool FLevelEditorViewportClient* SelectedViewport = LandscapeTestUtils::FindSelectedViewport(); LandscapeEdMode->CurrentTool->BeginTool(SelectedViewport, LandscapeEdMode->CurrentToolTarget, TargetLoctaion); SelectedViewport->Invalidate(); UE_LOG(LogLandscapeAutomationTests, Display, TEXT("Modified the landscape using the sculpt tool")); return true; }
void RasterizeSegmentPoints(ULandscapeInfo* LandscapeInfo, TArray<FLandscapeSplineInterpPoint> Points, const FTransform& SplineToWorld, bool bRaiseTerrain, bool bLowerTerrain, ULandscapeLayerInfoObject* LayerInfo) { ALandscapeProxy* LandscapeProxy = LandscapeInfo->GetLandscapeProxy(); const FTransform SplineToLandscape = SplineToWorld.GetRelativeTransform(LandscapeProxy->LandscapeActorToWorld()); FLandscapeEditDataInterface LandscapeEdit(LandscapeInfo); TSet<ULandscapeComponent*> ModifiedComponents; // I'd dearly love to use FIntRect in this code, but Landscape works with "Inclusive Max" and FIntRect is "Exclusive Max" int32 LandscapeMinX, LandscapeMinY, LandscapeMaxX, LandscapeMaxY; if (!LandscapeInfo->GetLandscapeExtent(LandscapeMinX, LandscapeMinY, LandscapeMaxX, LandscapeMaxY)) { return; } FBox SegmentBounds = FBox(0); for (const FLandscapeSplineInterpPoint& Point : Points) { SegmentBounds += Point.FalloffLeft; SegmentBounds += Point.FalloffRight; } SegmentBounds = SegmentBounds.TransformBy(SplineToLandscape.ToMatrixWithScale()); int32 MinX = FMath::CeilToInt(SegmentBounds.Min.X); int32 MinY = FMath::CeilToInt(SegmentBounds.Min.Y); int32 MaxX = FMath::FloorToInt(SegmentBounds.Max.X); int32 MaxY = FMath::FloorToInt(SegmentBounds.Max.Y); MinX = FMath::Max(MinX, LandscapeMinX); MinY = FMath::Max(MinY, LandscapeMinY); MaxX = FMath::Min(MaxX, LandscapeMaxX); MaxY = FMath::Min(MaxY, LandscapeMaxY); if (MinX > MaxX || MinY > MaxY) { // The segment's bounds don't intersect the landscape, so skip it entirely return; } for (int32 j = 0; j < Points.Num(); j++) { Points[j].Center = SplineToLandscape.TransformPosition(Points[j].Center); Points[j].Left = SplineToLandscape.TransformPosition(Points[j].Left); Points[j].Right = SplineToLandscape.TransformPosition(Points[j].Right); Points[j].FalloffLeft = SplineToLandscape.TransformPosition(Points[j].FalloffLeft); Points[j].FalloffRight = SplineToLandscape.TransformPosition(Points[j].FalloffRight); // local-heights to texture value heights Points[j].Left.Z = Points[j].Left.Z * LANDSCAPE_INV_ZSCALE + LandscapeDataAccess::MidValue; Points[j].Right.Z = Points[j].Right.Z * LANDSCAPE_INV_ZSCALE + LandscapeDataAccess::MidValue; Points[j].FalloffLeft.Z = Points[j].FalloffLeft.Z * LANDSCAPE_INV_ZSCALE + LandscapeDataAccess::MidValue; Points[j].FalloffRight.Z = Points[j].FalloffRight.Z * LANDSCAPE_INV_ZSCALE + LandscapeDataAccess::MidValue; } // Heights raster if (bRaiseTerrain || bLowerTerrain) { RasterizeSegmentHeight(MinX, MinY, MaxX, MaxY, LandscapeEdit, Points, bRaiseTerrain, bLowerTerrain, ModifiedComponents); if (MinX > MaxX || MinY > MaxY) { // The segment's bounds don't intersect any data, so we skip it entirely // it wouldn't intersect any weightmap data either so we don't even bother trying } } // Blend layer raster if (LayerInfo != NULL) { RasterizeSegmentAlpha(MinX, MinY, MaxX, MaxY, LandscapeEdit, Points, LayerInfo, ModifiedComponents); } LandscapeEdit.Flush(); for (ULandscapeComponent* Component : ModifiedComponents) { // Recreate collision for modified components and update the navmesh ULandscapeHeightfieldCollisionComponent* CollisionComponent = Component->CollisionComponent.Get(); if (CollisionComponent) { CollisionComponent->RecreateCollision(); UNavigationSystem* NavSys = UNavigationSystem::GetCurrent(Component); if (NavSys) { NavSys->UpdateNavOctree(CollisionComponent); } } } }