Skip to content

Commit

Permalink
Update landscape size based on GeoTiff texture's real size (#25)
Browse files Browse the repository at this point in the history
* Add the basic implementation of update landscape size.

* Use proper sizes to scale the Landscape.

* Fix live preview to support new geotiff landscape update settings.

* Make sure GeoTiffInfo persists into the actor.

* Fix a typo in the Build.cs file.
  • Loading branch information
arunoda committed Dec 17, 2022
1 parent 0d1a0bf commit f5daaa7
Show file tree
Hide file tree
Showing 12 changed files with 156 additions and 24 deletions.

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file modified TerrainMagicDevApp/Content/Maps/Main.umap
Binary file not shown.
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ TArray<FLandscapeClipPaintLayerSettings> AGeoTiffLandscapeClip::GetPaintLayerSet
return PaintLayerSettings;
}

void AGeoTiffLandscapeClip::ApplyRawHeightData(uint32 TextureWidth, TArray<float> HeightData)
void AGeoTiffLandscapeClip::ApplyRawHeightData(FGeoTiffInfo SourceGeoTiffInfo, uint32 TextureWidth, TArray<float> HeightData)
{
if (!IsValid(G16Texture) || G16Texture->GetTextureWidth() != TextureWidth)
{
Expand All @@ -129,6 +129,8 @@ void AGeoTiffLandscapeClip::ApplyRawHeightData(uint32 TextureWidth, TArray<float
const int32 Max16BitValue = FMath::Pow(2.0, 16.0) - 1;
const float HeightRangeRatio = Max16BitValue / Range;

SourceGeoTiffInfo.Range = Range;

TArray<uint16> G16HeightData;
G16HeightData.SetNumUninitialized(TextureWidth * TextureWidth);

Expand All @@ -137,10 +139,11 @@ void AGeoTiffLandscapeClip::ApplyRawHeightData(uint32 TextureWidth, TArray<float
G16HeightData[Index] = (HeightData[Index] - MinValue) * HeightRangeRatio;
}

G16Texture->UpdateAndCache(G16HeightData.GetData(), [this](UTexture2D* Texture)
G16Texture->UpdateAndCache(G16HeightData.GetData(), [this, SourceGeoTiffInfo](UTexture2D* Texture)
{
FTerrainMagicThreading::RunOnGameThread([this, Texture]()
FTerrainMagicThreading::RunOnGameThread([this, SourceGeoTiffInfo, Texture]()
{
GeoTiffInfo = SourceGeoTiffInfo;
HeightMap = Texture;
_Invalidate();
});
Expand Down Expand Up @@ -182,3 +185,11 @@ int32 AGeoTiffLandscapeClip::GetTargetResolution() const
return -1;
}
}

FVector AGeoTiffLandscapeClip::GetUpdatedLandscapeSize() const
{
const float GeoTiffWidth = GeoTiffInfo.TextureResolution.X * GeoTiffInfo.PixelToMetersRatio.X;
float WidthScale = GeoTiffWidth / LandscapeSize.X * 100;
float HeightScale = GeoTiffInfo.Range / 512 * 100;
return {WidthScale, WidthScale, HeightScale};
}
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,12 @@ void ALandscapeClip::Tick(float DeltaTime)
return;
}

if (RunMatchLandscapeSizeActive && RunMatchLandscapeSizeAt < FDateTime::Now())
{
_MatchLandscapeSize();
RunMatchLandscapeSizeActive = false;
}

// Initialize the Z-Index
if (GetZIndex() < 0)
{
Expand Down Expand Up @@ -176,6 +182,12 @@ void ALandscapeClip::_MatchLandscapeSize()
_Invalidate();
}

void ALandscapeClip::_MatchLandscapeSizeDefferred(float Secs)
{
RunMatchLandscapeSizeActive = true;
RunMatchLandscapeSizeAt = FDateTime::Now() + FTimespan::FromSeconds(Secs);
}

void ALandscapeClip::ApplyMaterialParamsForHeight(TArray<FTerrainMagicMaterialParam> Params)
{
if (MaterialForHeight == nullptr)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -213,8 +213,8 @@ void ATerrainMagicManager::Tick(float DeltaTime)
const FVector2D LandscapeMid = Landscape2DLocation + LandscapeSizeInCm/2.0;

PreviewMeshComponent->SetRelativeScale3D(FVector(
LandscapeSize.X,
LandscapeSize.Y,
LandscapeSizeInCm.X / 100.0f,
LandscapeSizeInCm.Y / 100.0f,
0.1
));
PreviewMeshComponent->SetRelativeLocation({
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,34 @@ enum EGeoTiffTargetTextureResolution
GTRES_8192 = 4 UMETA(DisplayName="8192"),
};

USTRUCT(BlueprintType)
struct FGeoTiffInfo
{
GENERATED_BODY()

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="TerrainMagic")
FIntPoint TextureResolution;

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="TerrainMagic")
FVector2D Origin;

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="TerrainMagic")
FVector2D PixelToMetersRatio;

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="TerrainMagic")
float Range;
};

UCLASS()
class TERRAINMAGIC_API AGeoTiffLandscapeClip : public ALandscapeClip
{
GENERATED_BODY()

UPROPERTY()
UG16Texture* G16Texture = nullptr;

UPROPERTY()
FGeoTiffInfo GeoTiffInfo;

bool HasTextureReloaded = false;
void ReloadTextureIfNeeded();
Expand All @@ -47,9 +68,10 @@ class TERRAINMAGIC_API AGeoTiffLandscapeClip : public ALandscapeClip
virtual int GetZIndex() const override;
virtual UTexture* GetHeightMap() const override;
virtual TArray<FLandscapeClipPaintLayerSettings> GetPaintLayerSettings() const override;
void ApplyRawHeightData(uint32 TextureWidth, TArray<float> HeightData);
void ApplyRawHeightData(FGeoTiffInfo GeoTiffInfo, uint32 TextureWidth, TArray<float> HeightData);
virtual void Tick(float DeltaSeconds) override;
int32 GetTargetResolution() const;
FVector GetUpdatedLandscapeSize() const;

UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="01-General")
bool bEnabled = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,9 @@ class TERRAINMAGIC_API ALandscapeClip : public AActor
UPROPERTY()
float InitialZPosition = -12424.0;

bool RunMatchLandscapeSizeActive = false;
FDateTime RunMatchLandscapeSizeAt = 0;

public:
// Sets default values for this actor's properties
ALandscapeClip();
Expand Down Expand Up @@ -104,6 +107,7 @@ class TERRAINMAGIC_API ALandscapeClip : public AActor
void _ToggleSolo();
void _TogglePreview();
void _MatchLandscapeSize();
void _MatchLandscapeSizeDefferred(float Secs);

UPROPERTY()
bool bShowOutline = true;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
#include "gdal/gdal_priv.h"
#include "gdal/cpl_conv.h"
#include "IDesktopPlatform.h"
#include "Landscape.h"
#include "Utils/TerrainMagicThreading.h"

#define LOCTEXT_NAMESPACE "LandscapeClipDetails"

Expand Down Expand Up @@ -153,6 +155,20 @@ void FLandscapeClipDetails::CustomizeDetails(IDetailLayoutBuilder& DetailBuilder
SNew(SButton)
.Text(LOCTEXT("Import", "Import GeoTiff"))
.OnClicked_Raw(this, &FLandscapeClipDetails::OnImportGeoTiff)
]
+SGridPanel::Slot(1, 3).Padding(5, 2)
[
SNew(SButton)
.Text(LOCTEXT("UpdateLandscapeSize", "Update Landscape Size"))
.ToolTipText(LOCTEXT("UpdateLandscapeSizeToolTip", "Update the landscape scale to match the real size of the terrain"))
.OnClicked_Raw(this, &FLandscapeClipDetails::OnUpdateLandscapeSize)
]
+SGridPanel::Slot(2, 3).Padding(5, 2)
[
SNew(SButton)
.Text(LOCTEXT("ResetLandscapeSize", "Reset"))
.ToolTipText(LOCTEXT("ResetLandscapeSizeTooltip", "Reset the landscape scale back to default settings"))
.OnClicked_Raw(this, &FLandscapeClipDetails::OnResetLandscapeSize)
];
}

Expand Down Expand Up @@ -310,17 +326,17 @@ FReply FLandscapeClipDetails::OnImportGeoTiff()
// Get image metadata
const uint32 Width = dataset->GetRasterXSize();
const uint32 Height = dataset->GetRasterYSize();

FGeoTiffInfo GeoTiffInfo = {};
GeoTiffInfo.TextureResolution.X = Width;
GeoTiffInfo.TextureResolution.Y = Height;

// Get image resolution data
FVector2D Origin;
FVector2D PixelSize;

double geoTransform[6];
if (dataset->GetGeoTransform(geoTransform) == CE_None ) {
Origin.X = geoTransform[0];
Origin.Y = geoTransform[3];
PixelSize.X = geoTransform[1];
PixelSize.Y = geoTransform[5];
GeoTiffInfo.Origin.X = geoTransform[0];
GeoTiffInfo.Origin.Y = geoTransform[3];
GeoTiffInfo.PixelToMetersRatio.X = geoTransform[1];
GeoTiffInfo.PixelToMetersRatio.Y = geoTransform[5];
} else {
FNotificationInfo Info(LOCTEXT("Unsupported GeoTiff File", "Unsupported GeoTiff file found!"));
Info.ExpireDuration = 10.0f;
Expand All @@ -338,7 +354,52 @@ FReply FLandscapeClipDetails::OnImportGeoTiff()
elevationBand->RasterIO(GF_Read, 0, 0, Width, Height, RawHeightData.GetData(), ReadResolution, ReadResolution, GDT_Float32, 0, 0);

// Pass the Data to the Clip
GeoTiffLandscapeClip->ApplyRawHeightData(ReadResolution, RawHeightData);

GeoTiffLandscapeClip->ApplyRawHeightData(GeoTiffInfo, ReadResolution, RawHeightData);

return FReply::Handled();
}

FReply FLandscapeClipDetails::OnUpdateLandscapeSize()
{
// Load the GeoTiffClip
AGeoTiffLandscapeClip* GeoTiffLandscapeClip = nullptr;
for (ALandscapeClip* Clip: GetSelectedLandscapeClips())
{
GeoTiffLandscapeClip = Cast<AGeoTiffLandscapeClip>(Clip);
if (GeoTiffLandscapeClip != nullptr)
{
break;
}
}

const FVector RealSize = GeoTiffLandscapeClip->GetUpdatedLandscapeSize();
ALandscape* Landscape = Cast<ALandscape>(UGameplayStatics::GetActorOfClass(GeoTiffLandscapeClip->GetWorld(), ALandscape::StaticClass()));
Landscape->SetActorScale3D(RealSize);

GeoTiffLandscapeClip->_Invalidate();
GeoTiffLandscapeClip->_MatchLandscapeSizeDefferred(2);

return FReply::Handled();
}

FReply FLandscapeClipDetails::OnResetLandscapeSize()
{
AGeoTiffLandscapeClip* GeoTiffLandscapeClip = nullptr;
for (ALandscapeClip* Clip: GetSelectedLandscapeClips())
{
GeoTiffLandscapeClip = Cast<AGeoTiffLandscapeClip>(Clip);
if (GeoTiffLandscapeClip != nullptr)
{
break;
}
}

ALandscape* Landscape = Cast<ALandscape>(UGameplayStatics::GetActorOfClass(GeoTiffLandscapeClip->GetWorld(), ALandscape::StaticClass()));
Landscape->SetActorScale3D({100.0f, 100.0f, 100.f});

GeoTiffLandscapeClip->_Invalidate();
GeoTiffLandscapeClip->_MatchLandscapeSizeDefferred(2);

return FReply::Handled();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ class FLandscapeClipDetails : public IDetailCustomization
FReply OnClickDownloadTile();
FReply OnOpenMap();
FReply OnImportGeoTiff();
FReply OnUpdateLandscapeSize();
FReply OnResetLandscapeSize();

// Helpers
TArray<ALandscapeClip*> GetSelectedLandscapeClips();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,8 @@ public TerrainMagicEditor(ReadOnlyTargetRules Target) : base(Target)
PrivateDependencyModuleNames.AddRange(new []
{
"Slate", "SlateCore", "TerrainMagic",
"InputCore",
"ToolMenus", "Projects", "EditorStyle",
"InputCore", "RenderCore",
"ToolMenus", "Projects", "EditorStyle", "Landscape",
#if UE_5_0_OR_LATER
"EditorFramework",
#endif
Expand Down

0 comments on commit f5daaa7

Please sign in to comment.