Off the ladder at the user's request. Scripts/Authoring/generate_heightmap.py (numpy, installed locally by bootstrap-pylib.sh) writes a 16-bit height PNG and three 8-bit weight PNGs to Content/World/Heightmaps; create_world.py rebuilds /Game/Maps/L_World from them through ULandscapeAuthoringLibrary in the new SaltyEditor module, which wraps ALandscape::Import because the engine exposes no landscape creation to Python. Uses Elite_RockyMeadows' landscape material and layer infos (the pack itself is still uncommitted). 4033 vertices a side at 350 cm a quad; swap the PNGs and rerun to change the terrain. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
44 lines
1.9 KiB
C++
44 lines
1.9 KiB
C++
#pragma once
|
|
|
|
#include "CoreMinimal.h"
|
|
#include "Kismet/BlueprintFunctionLibrary.h"
|
|
#include "LandscapeAuthoringLibrary.generated.h"
|
|
|
|
class ALandscape;
|
|
class ULandscapeLayerInfoObject;
|
|
class UMaterialInterface;
|
|
|
|
// One paint layer to import with the heightmap: the layer info asset the material expects and an 8-bit
|
|
// greyscale file (PNG or raw) with the same resolution as the heightmap.
|
|
USTRUCT(BlueprintType)
|
|
struct FLandscapeAuthoringWeightmap
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Landscape")
|
|
TObjectPtr<ULandscapeLayerInfoObject> LayerInfo = nullptr;
|
|
|
|
UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = "Landscape")
|
|
FString File;
|
|
};
|
|
|
|
// What the editor's "New Landscape > Import" button does, callable from an authoring script. The engine exposes
|
|
// no landscape creation to Python, so this is the project's first editor tool. Mirrors
|
|
// FLandscapeEditorDetailCustomization_NewLandscape::OnCreateButtonClicked without the regions path.
|
|
UCLASS()
|
|
class SALTYEDITOR_API ULandscapeAuthoringLibrary : public UBlueprintFunctionLibrary
|
|
{
|
|
GENERATED_BODY()
|
|
|
|
public:
|
|
// Creates a landscape in World from a 16-bit heightmap file, centred on Location, with the given per-quad
|
|
// scale (cm; Z is the engine's height scale where 100 spans -256 m to +256 m). The component layout is chosen
|
|
// from the file's resolution; a file that does not fit a layout exactly is expanded, not resampled. In a
|
|
// world-partitioned level the landscape is split into streaming proxies of GridSize x GridSize components.
|
|
// Returns null and logs why on failure.
|
|
UFUNCTION(BlueprintCallable, Category = "Salty|Authoring")
|
|
static ALandscape* CreateLandscapeFromHeightmap(UWorld* World, const FString& HeightmapFile,
|
|
const TArray<FLandscapeAuthoringWeightmap>& Weightmaps, UMaterialInterface* Material,
|
|
FVector Location, FVector Scale, int32 WorldPartitionGridSize = 4);
|
|
};
|