UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
LandscapeEdgeFixup.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
7#include "Misc/EnumRange.h"
10#include "LandscapeEdgeFixup.generated.h"
11
12struct FLandscapeGroup;
13class ULandscapeComponent;
14class ULandscapeInfo;
15class UTexture2D;
16
17namespace UE::Landscape
18{
19 // Enumerates directions, for the edges or neighbors of a tile in the the landscape group grid.
20 // When specifically referencing an edge or a neighbor, use EEdgeIndex or ENeighborIndex
22 {
23 Bottom = 0,
24 BottomRight = 1,
25 Right = 2,
26 TopRight = 3,
27 Top = 4,
28 TopLeft = 5,
29 Left = 6,
30 BottomLeft = 7,
31
32 First = 0,
33 Last = 7,
34 Count = 8,
35
36 FirstEdge = 0,
37 LastEdge = 6,
38 EdgeCount = 4,
39
40 FirstCorner = 1,
41 LastCorner = 7,
42 CornerCount = 4,
43 };
44
45 // Specifies a set of edges or neighbors.
47 {
48 Bottom = 0x00000001,
49 BottomRight = 0x00000002,
50 Right = 0x00000004,
51 TopRight = 0x00000008,
52 Top = 0x00000010,
53 TopLeft = 0x00000020,
54 Left = 0x00000040,
55 BottomLeft = 0x00000080,
56
57 None = 0,
61 };
62
63 typedef EDirectionIndex EEdgeIndex; // EEdgeIndex specifies an edge or corner on the local landscape component.
64 typedef EDirectionFlags EEdgeFlags; // EEdgeFlags specifies a set of edges and corners on the local landscape component.
65 typedef EDirectionIndex ENeighborIndex; // ENeighborIndex specifies a neighbor landscape component, relative to a local landscape component.
66 typedef EDirectionFlags ENeighborFlags; // ENeighborFlags specifies a set of neighboring landscape components.
67
69 {
70 static_assert(PLATFORM_LITTLE_ENDIAN, "This code needs to be adapted to big endian");
71
72 union
73 {
76 struct
77 {
79 uint8 HeightL; // low 8 bits
80 uint8 HeightH; // high 8 bits
82 };
83 };
84
86 {
87 return (((uint32)HeightH) << 8) + HeightL;
88 }
89
91 {
92 HeightL = NewHeight & 0xff;
93 HeightH = (NewHeight >> 8) & 0xff;
94 }
95
97 {
99 // these seem to produce the nearest result to the GPU normal calculation
100 // (matches 'straight up' of 0x7f coming from the GPU)
101 NormalX = static_cast<uint8>(FMath::RoundToInt32(127.49999f + Normal.X * 127.5f));
102 NormalY = static_cast<uint8>(FMath::RoundToInt32(127.49999f + Normal.Y * 127.5f));
103 }
104
106 {
107 uint32 HeightBitsXOR = (Data32 ^ Other.Data32) & 0x00FFFF00;
108 return HeightBitsXOR == 0;
109 }
110 };
111
112 // states required to perform edge patching
121}
124
125namespace UE::Landscape
126{
127 // Returns the relative offset (in group tile coords) of a neighbor
129
130 // Returns the set of neighbors that blend with any local edge in EdgeFlags
132
133 // Converts a neighbor index to a neighbor flag (or an edge index to an edge flag)
135
136 // Returns a debug string describing the neighbor (or edge) direction
138}
139
140
145USTRUCT()
147{
150
151private:
152 int32 EdgeLength = 0; // edge length for recorded edge data here - when up to date, should match texture resolution (width AND height)
153 TArray<uint32> EdgeData; // height and normal data for each edge & mip (in heightmap texture format 32bpp). Use GetEdgeData() to access specific edges and mips.
154 TStaticArray<uint32, 8> SnapshotEdgeHashes; // hash of each edge / corner (at full resolution) in the EdgeData
155 TStaticArray<uint32, 8> InitialEdgeHashes; // hash of each edge / corner (at full resolution) in the GPU Texture Resource (at initial unpatched state)
156
157#if WITH_EDITOR
158 FGuid TextureSourceID; // used to detect when this is out of date with texture sourcesource
159#endif // WITH_EDITOR
160
161public:
167
168#if WITH_EDITOR
169 // Create a snapshot from the heightmap source
171#endif // WITH_EDITOR
172 // Create a snapshot from an explicit byte array (in heightmap source standard layout)
173 static TSharedRef<FHeightmapTextureEdgeSnapshot> CreateEdgeSnapshotFromTextureData(const TArrayView64<UE::Landscape::FHeightmapTexel>& InHeightmapTextureData, int32 InEdgeLength, const FVector& LandscapeGridScale);
174
175 // Return the set of edges that are different (according to edge hashes) -- i.e. changes that could cause neighbors to patch
177
179
181 {
182#if WITH_EDITOR
183 return TextureSourceID.ToString();
184#else
185 return FString("<NONE>");
186#endif // WITH_EDITOR
187 }
188
189private:
190 void ResizeForEdgeLength(const int32 InEdgeLength);
191
192 // This function is not thread safe to call on existing snapshots
193 // it should only be used on a newly allocated FHeightmapTextureEdgeSnapshot
194 void CaptureEdgeDataFromTextureData_Internal(const TArrayView64<UE::Landscape::FHeightmapTexel>& InHeightmapTextureData, int32 InEdgeLength, const FVector& LandscapeGridScale);
195
196 // must call ResizeForEdgeLength to set the texture size before calling CopyTextureEdgeDataAndRecomputeNormals
197 void CaptureSingleEdgeDataAndComputeNormalsAndHashes(const UE::Landscape::FHeightmapTexel* TextureData, const UE::Landscape::EEdgeIndex EdgeOrCorner, const FVector& LandscapeGridScale);
198};
199
200// This UAssetUserData is attached to landscape heightmap UTexture2D's and tracks the heightmap texture's edge fixup state
201// This is used by mip providers to apply edge fixup on mip streaming/creation, and
202// also used by runtime dynamic fixup when neighboring landscape components are pulled in
203UCLASS(NotBlueprintable, MinimalAPI, Within = Texture2D)
205{
210
211private:
212 // SERIALIZED snapshot of the heightmap edge data
213 // COPY-ON-WRITE so we can use it safely from other threads. do not modify an existing snapshot, create a new snapshot and replace this reference.
215
216 // transient runtime tracking data
217 TObjectPtr<UTexture2D> HeightmapTexture; // heightmap texture (set to our parent heightmap, on first registration)
218
219 TObjectPtr<ULandscapeComponent> ActiveComponent; // the active component, that is patching HeightmapTexture
220 FLandscapeGroup* ActiveGroup = nullptr; // the active group, that is patching HeightmapTexture
221
222 TStaticArray<uint32, 8> GPUEdgeHashes; // hash for the current GPU edge state, initialized on first registration
223 UE::Landscape::EEdgeFlags GPUEdgeModifiedFlags = // edges that have been patched / modified from the initial state
224 UE::Landscape::EEdgeFlags::None;
225
226#if WITH_EDITOR
228 bool bUpdateGPUEdgeHashes = false;
229#endif // WITH_EDITOR
230
231 // per-group settings (apply to the active group/component)
232 bool bMapped = false;
233 bool bForceUpdateSnapshot = true; // set to true initially so that we do a force update on the very first request
234 FIntPoint GroupCoord = FIntPoint::ZeroValue; // coordinate of this heightmap in the active group (when bMapped)
235
236 // components that also want to use this heightmap & edge fixup, but were disabled as we can only support one active component at a time.
237 // these must be weak object pointers, as they can be unregistered while still in this list, and can be garbage collected out from under us.
238 // Note that this array is generally empty except in scenarios where there are multiple active worlds sharing the same landscape textures (PIE)
239 // so the expense of accessing the TWeakObjectPtr is a PIE-only cost.
241
242public:
243 inline bool IsActive() { return ActiveGroup != nullptr; }
244 inline UTexture2D* GetHeightmapTexture() { return HeightmapTexture; }
245 inline bool IsComponentActive(ULandscapeComponent* Component) { return ActiveComponent == Component; }
246 inline const FIntPoint& GetGroupCoord() { return GroupCoord; }
247
248#if WITH_EDITOR
251#endif // WITH_EDITOR
252
253 virtual void Serialize(FArchive& Ar) override;
254 static void AddReferencedObjects(UObject* InThis, FReferenceCollector& Collector);
255
256 // [main thread] -- Find or Create an edge fixup class for the given heightmap texture. Will only create in editor (the data used to create is only available in editor)
258
259 // set the heightmap texture (can only be called once)
260 void SetHeightmapTexture(UTexture2D* InHeightmapTexture);
261
262 // set the active landscape component, handling unmapping the old, and mapping the new.
263 // if bDisableCurrentActive, it will move the current active component, if any, to the disabled list.
264 void SetActiveComponent(ULandscapeComponent* InComponent, FLandscapeGroup* InGroup, const bool bDisableCurrentActive = true);
265
266 // Request edge texture patching on a set of neighbors.
267 void RequestEdgeTexturePatchingForNeighbors(UE::Landscape::ENeighborFlags NeighborsNeedingPatching);
268
269#if WITH_EDITOR
270 // Request an update to the edge snapshot (capturing from the heightmap source).
271 // When bUpdateGPUEdgeHashes is true, it will also update the GPU Edge Hashes to match.
272 // This is set when we know the heightmap source exactly reflects the GPU texture state
273 // i.e. after reading back from GPU to CPU after a layer merge, or after UpdateResource().
275
276 // Update the edge snapshot from heightmap source. Returns the set of edges that changed since the previous snapshot.
277 UE::Landscape::EEdgeFlags UpdateEdgeSnapshotFromHeightmapSource(const FVector& LandscapeGridScale, bool bForceUpdate = false, bool* bOutSuccess = nullptr);
278#endif // WITH_EDITOR
279
280 // Patch the GPU texture edges if needed, using the current snapshot and corresponding neighbor snapshots as source data.
281 // Returns the number of edges patched.
282 int32 CheckAndPatchTextureEdgesFromEdgeSnapshots();
283
284 // Get the set of neighbor snapshots (nullptr if they don't exist), and gather existence and modified flags
285 // this is the data necessary to perform patching on a component
286 void GetNeighborSnapshots(UE::Landscape::FNeighborSnapshots& OutSnapshots);
287
288 // Patch all of the edges for a single texture mip.
289 // Called during streaming operations to patch a newly streamed mip in flight.
290 // Returns the number of edges and corners patched
291 static int32 PatchTextureEdgesForSingleMip(int32 MipIndex, FTextureMipInfo& DestMipInfo, const UE::Landscape::FNeighborSnapshots& NeighborSnapshots);
292 static int32 PatchTextureEdgesForStreamingMips(int32 FirstMipIndexInclusive, int32 LastMipIndexExclusive, FTextureMipInfoArray& DestMipInfos, const UE::Landscape::FNeighborSnapshots& NeighborSnapshots);
293
294private:
295 void PatchTextureEdge_Internal(UE::Landscape::EEdgeIndex EdgeIndex);
297
298 // Helper functions that generate blended edge or corner data from snapshots, to use in texture patching
301};
302
@ Normal
Definition AndroidInputInterface.h:116
#define PLATFORM_LITTLE_ENDIAN
Definition AndroidPlatform.h:38
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
#define ENUM_CLASS_FLAGS(Enum)
Definition EnumClassFlags.h:6
#define ENUM_RANGE_BY_FIRST_AND_LAST(EnumType, First, Last)
Definition EnumRange.h:47
FArchive & operator<<(FArchive &Ar, FEnvQueryDebugProfileData::FStep &Data)
Definition EnvQueryTypes.cpp:489
#define GENERATED_UCLASS_BODY(...)
Definition ObjectMacros.h:768
#define UCLASS(...)
Definition ObjectMacros.h:776
#define USTRUCT(...)
Definition ObjectMacros.h:746
#define GENERATED_USTRUCT_BODY(...)
Definition ObjectMacros.h:767
ESPMode
Definition SharedPointerFwd.h:12
uint8_t uint8
Definition binka_ue_file_header.h:8
uint16_t uint16
Definition binka_ue_file_header.h:7
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition Archive.h:1208
Definition LandscapeTextureStorageProvider.h:98
Definition LandscapeTextureStorageProvider.h:40
Definition UObjectGlobals.h:2492
Definition Landscape.Build.cs:7
Definition ArrayView.h:139
Definition Array.h:670
Definition SharedPointer.h:692
Definition SharedPointer.h:153
Definition StaticArray.h:26
Definition StridedView.h:44
Definition AssetUserData.h:18
Definition LandscapeEdgeFixup.h:205
bool IsComponentActive(ULandscapeComponent *Component)
Definition LandscapeEdgeFixup.h:245
const FIntPoint & GetGroupCoord()
Definition LandscapeEdgeFixup.h:246
bool IsActive()
Definition LandscapeEdgeFixup.h:243
UTexture2D * GetHeightmapTexture()
Definition LandscapeEdgeFixup.h:244
Definition LandscapeInfo.h:109
Definition Object.h:95
Definition Texture2D.h:26
Definition Landscape.h:55
EDirectionFlags EEdgeFlags
Definition LandscapeEdgeFixup.h:64
EDirectionFlags ENeighborFlags
Definition LandscapeEdgeFixup.h:66
EDirectionFlags
Definition LandscapeEdgeFixup.h:47
ENeighborFlags EdgesToAffectedNeighbors(EEdgeFlags LocalEdgeFlags)
Definition LandscapeEdgeFixup.cpp:106
EDirectionIndex
Definition LandscapeEdgeFixup.h:22
const FString & GetDirectionString(EDirectionIndex Index)
Definition LandscapeEdgeFixup.cpp:65
EDirectionIndex ENeighborIndex
Definition LandscapeEdgeFixup.h:65
EDirectionIndex EEdgeIndex
Definition LandscapeEdgeFixup.h:63
EDirectionFlags ToFlag(EDirectionIndex Index)
Definition LandscapeEdgeFixup.cpp:34
FIntPoint GetNeighborRelativePosition(ENeighborIndex NeighborIndex)
Definition LandscapeEdgeFixup.cpp:45
Definition AdvancedWidgetsModule.cpp:13
U16 Index
Definition radfft.cpp:71
Definition Guid.h:109
Definition LandscapeEdgeFixup.h:147
FString GetTextureSourceIDAsString()
Definition LandscapeEdgeFixup.h:180
Definition LandscapeGroup.h:22
Definition TextureMipDataProvider.h:23
Definition ObjectPtr.h:488
Definition LandscapeEdgeFixup.h:69
void SetHeight16(uint16 NewHeight)
Definition LandscapeEdgeFixup.h:90
uint8 HeightH
Definition LandscapeEdgeFixup.h:80
uint8 Data[4]
Definition LandscapeEdgeFixup.h:75
void SetNormal(const FVector &NewNormal)
Definition LandscapeEdgeFixup.h:96
uint8 HeightL
Definition LandscapeEdgeFixup.h:79
bool IsSameHeight(const FHeightmapTexel &Other) const
Definition LandscapeEdgeFixup.h:105
uint8 NormalY
Definition LandscapeEdgeFixup.h:81
uint32 GetHeight16() const
Definition LandscapeEdgeFixup.h:85
uint32 Data32
Definition LandscapeEdgeFixup.h:74
uint8 NormalX
Definition LandscapeEdgeFixup.h:78
Definition LandscapeEdgeFixup.h:114
EEdgeFlags EdgesWithAnyModifiedNeighbor
Definition LandscapeEdgeFixup.h:116
FHeightmapTextureEdgeSnapshot * LocalSnapshot
Definition LandscapeEdgeFixup.h:118
TStaticArray< uint32, 8 > GPUEdgeHashes
Definition LandscapeEdgeFixup.h:119
ENeighborFlags ExistingNeighbors
Definition LandscapeEdgeFixup.h:115
FHeightmapTextureEdgeSnapshot * NeighborSnapshots[8]
Definition LandscapeEdgeFixup.h:117
Definition IntPoint.h:25
static const TIntPoint ZeroValue
Definition IntPoint.h:45
TVector< T > GetSafeNormal(T Tolerance=UE_SMALL_NUMBER, const TVector< T > &ResultIfZero=ZeroVector) const
Definition Vector.h:2060