UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
LandscapeDataAccess.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3/*=============================================================================
4LandscapeDataAccess.h: Classes for the editor to access to Landscape data
5=============================================================================*/
6
7#pragma once
8
9#include "CoreMinimal.h"
10#include "Engine/Texture2D.h"
11
12#define LANDSCAPE_VALIDATE_DATA_ACCESS 1
13#define LANDSCAPE_ZSCALE (1.0f/128.0f)
14#define LANDSCAPE_INV_ZSCALE 128.0f
15
16#define LANDSCAPE_XYOFFSET_SCALE UE_DEPRECATED_MACRO(5.7, "RetopologizeTool/XYOffset deprecated with the removal of non-edit layer landscapes") (1.0f/256.f)
17#define LANDSCAPE_INV_XYOFFSET_SCALE UE_DEPRECATED_MACRO(5.7, "RetopologizeTool/XYOffset deprecated with the removal of non-edit layer landscapes") 256.f
18
19#define LANDSCAPE_VISIBILITY_THRESHOLD (2.0f/3.0f)
20
21class ULandscapeComponent;
23
25{
26 inline constexpr int32 MaxValue = 65535;
27 inline constexpr float MidValue = 32768.f;
29 {
30 return (static_cast<float>(Height) - MidValue) * LANDSCAPE_ZSCALE;
31 }
32
34 {
35 return static_cast<uint16>(FMath::RoundToInt(FMath::Clamp<float>(Height * LANDSCAPE_INV_ZSCALE + MidValue, 0.f, MaxValue)));
36 }
37
39 {
41 Color.R = Height >> 8;
42 Color.G = Height & 255;
43 return MoveTemp(Color);
44 }
45
47 {
49 return GetLocalHeight(Height);
50 }
51
53 {
55 Normal.X = 2.f * static_cast<float>(InHeightmapSample.B) / 255.f - 1.f;
56 Normal.Y = 2.f * static_cast<float>(InHeightmapSample.A) / 255.f - 1.f;
57 Normal.Z = FMath::Sqrt(FMath::Max(1.0f - (FMath::Square(Normal.X) + FMath::Square(Normal.Y)), 0.0f));
58 return Normal;
59 }
60};
61
62#if WITH_EDITOR
63
64class ULandscapeComponent;
66
67//
68// FLandscapeDataInterface
69//
71{
72private:
73
75 {
77 : LockCount(0)
78 {}
79
80 TArray64<uint8> MipData;
81 int32 LockCount;
82 };
83
84public:
85 // Constructor
86 // @param bInAutoDestroy - shall we automatically clean up when the last
88 {}
89
90 void* LockMip(UTexture2D* Texture, int32 MipLevel)
91 {
92 check(Texture->Source.IsValid());
94
96 if( MipInfo == nullptr )
97 {
99 for (int32 i = 0; i < Texture->Source.GetNumMips(); ++i)
100 {
101 MipInfo->Add(FLockedMipDataInfo());
102 }
103 }
104
105 if( (*MipInfo)[MipLevel].MipData.Num() == 0 )
106 {
107 verify( Texture->Source.GetMipData((*MipInfo)[MipLevel].MipData, MipLevel) );
108 }
109 (*MipInfo)[MipLevel].LockCount++;
110
111 return (*MipInfo)[MipLevel].MipData.GetData();
112 }
113
114 void UnlockMip(UTexture2D* Texture, int32 MipLevel)
115 {
117 check(MipInfo);
118
119 if ((*MipInfo)[MipLevel].LockCount <= 0)
120 return;
121 (*MipInfo)[MipLevel].LockCount--;
122 if( (*MipInfo)[MipLevel].LockCount == 0 )
123 {
124 check( (*MipInfo)[MipLevel].MipData.Num() != 0 );
125 (*MipInfo)[MipLevel].MipData.Empty();
126 }
127 }
128
129private:
131};
132
133
135{
138
139 // Accessors
140 void VertexIndexToXY(int32 VertexIndex, int32& OutX, int32& OutY) const
141 {
142 OutX = VertexIndex % ComponentSizeVerts;
143 OutY = VertexIndex / ComponentSizeVerts;
144 }
145
146 // Accessors
148 {
149 OutX = QuadIndex % (ComponentSizeVerts-1);
150 OutY = QuadIndex / (ComponentSizeVerts-1);
151 }
152
154 {
155 return VertY * ComponentSizeVerts + VertX;
156 }
157
159 {
160 // We do the calculation as if we're looking for the previous vertex.
161 // This allows us to pick up the last shared vertex of every subsection correctly.
162 SubNumX = (CompX-1) / (SubsectionSizeVerts - 1);
163 SubNumY = (CompY-1) / (SubsectionSizeVerts - 1);
164 SubX = (CompX-1) % (SubsectionSizeVerts - 1) + 1;
165 SubY = (CompY-1) % (SubsectionSizeVerts - 1) + 1;
166
167 // If we're asking for the first vertex, the calculation above will lead
168 // to a negative SubNumX/Y, so we need to fix that case up.
169 if( SubNumX < 0 )
170 {
171 SubNumX = 0;
172 SubX = 0;
173 }
174
175 if( SubNumY < 0 )
176 {
177 SubNumY = 0;
178 SubY = 0;
179 }
180 }
181
183 {
184 int32 SubNumX, SubNumY, SubX, SubY;
186
187 OutX = SubNumX * SubsectionSizeVerts + SubX;
188 OutY = SubNumY * SubsectionSizeVerts + SubY;
189 }
190
191 int32 VertexIndexToTexel(int32 VertexIndex) const
192 {
194 VertexIndexToXY(VertexIndex, VertX, VertY);
198 }
199
201 {
202 return TexelY * ComponentNumSubsections * SubsectionSizeVerts + TexelX;
203 }
204
205 uint16 GetHeight(int32 LocalX, int32 LocalY, const TArray<FColor>& HeightAndNormals) const
206 {
207 const FColor* Texel = GetHeightData(LocalX, LocalY, HeightAndNormals);
208 return (uint16)(Texel->R << 8) | (uint16)Texel->G;
209 }
210
211 float GetScaleFactor() const
212 {
213 return (float)ComponentSizeQuads / (float)(ComponentSizeVerts - 1);
214 }
215
217 {
218 const float ScaleFactor = GetScaleFactor();
219
220 return FVector(ScaleFactor * (float)LocalX, ScaleFactor * (float)LocalY, LandscapeDataAccess::GetLocalHeight(GetHeight(LocalX, LocalY, HeightAndNormals)));
221 }
222
223 float GetLocalHeight(int32 LocalX, int32 LocalY, const TArray<FColor>& HeightAndNormals) const
224 {
225 return LandscapeDataAccess::GetLocalHeight(GetHeight(LocalX, LocalY, HeightAndNormals));
226 }
227
228 const FColor* GetHeightData(int32 LocalX, int32 LocalY, const TArray<FColor>& HeightAndNormals) const
229 {
230#if LANDSCAPE_VALIDATE_DATA_ACCESS
231 check(LocalX >= 0 && LocalY >= 0 && LocalX < ComponentSizeVerts&& LocalY < HeightmapStride);
232#endif
233
235 VertexXYToTexelXY(LocalX, LocalY, TexelX, TexelY);
236
238 }
239
241 {
242 // Note: these are still pre-scaled, just not rotated
243 const FColor* Data = GetHeightData(LocalX, LocalY, HeightAndNormals);
247 }
248
249 int32 GetComponentSizeVerts() const { return ComponentSizeVerts; }
250
251public:
252 // offset of this component's data into heightmap texture
257 const int32 MipLevel = 0;
258
259protected:
260 int32 ComponentSizeQuads = 0;
261 int32 ComponentSizeVerts = 0;
262 int32 SubsectionSizeVerts = 0;
263 int32 ComponentNumSubsections = 0;
264};
265
266//
267// FLandscapeComponentDataInterface
268//
270{
271 friend struct FLandscapeDataInterface;
272
273 // tors
276
277 FColor* GetRawHeightData() const
278 {
279 return HeightMipData;
280 }
281
283 {
285 }
286
289
290 /* Return the raw heightmap data exactly same size for Heightmap texture which belong to only this component */
292
294
295 FColor* GetHeightData(int32 LocalX, int32 LocalY) const
296 {
297#if LANDSCAPE_VALIDATE_DATA_ACCESS
301 check(LocalX >=0 && LocalY >=0 && LocalX < ComponentSizeVerts && LocalY < ComponentSizeVerts);
302#endif
303
305 VertexXYToTexelXY(LocalX, LocalY, TexelX, TexelY);
306
308 }
309
310 UE_DEPRECATED(5.7, "RetopologizeTool/XYOffset deprecated with the removal of non-edit layer landscapes")
311 LANDSCAPE_API FColor* GetXYOffsetData(int32 LocalX, int32 LocalY) const;
312
313 uint16 GetHeight( int32 LocalX, int32 LocalY ) const
314 {
315 FColor* Texel = GetHeightData(LocalX, LocalY);
316 return (uint16)(Texel->R << 8) | (uint16)Texel->G;
317 }
318
319 uint16 GetHeight( int32 VertexIndex ) const
320 {
321 int32 X, Y;
322 VertexIndexToXY( VertexIndex, X, Y );
323 return GetHeight( X, Y );
324 }
325
326 float GetLocalHeight(int32 LocalX, int32 LocalY) const
327 {
328 return LandscapeDataAccess::GetLocalHeight(GetHeight(LocalX, LocalY));
329 }
330
331 float GetLocalHeight(int32 VertexIndex) const
332 {
333 return LandscapeDataAccess::GetLocalHeight(GetHeight(VertexIndex));
334 }
335
336 LANDSCAPE_API FVector GetLocalVertex(int32 LocalX, int32 LocalY) const;
337
339 {
340 // Note: these are still pre-scaled, just not rotated
341
342 FColor* Data = GetHeightData( LocalX, LocalY );
346 }
347
348 FVector GetLocalVertex( int32 VertexIndex ) const
349 {
350 int32 X, Y;
351 VertexIndexToXY( VertexIndex, X, Y );
352 return GetLocalVertex( X, Y );
353 }
354
356 {
357 int32 X, Y;
358 VertexIndexToXY( VertexIndex, X, Y );
360 }
361
362 LANDSCAPE_API FVector GetWorldVertex(int32 LocalX, int32 LocalY) const;
363
364 LANDSCAPE_API void GetWorldTangentVectors(int32 LocalX, int32 LocalY, FVector& WorldTangentX, FVector& WorldTangentY, FVector& WorldTangentZ) const;
365
366 LANDSCAPE_API void GetWorldPositionTangents(int32 LocalX, int32 LocalY, FVector& WorldPos, FVector& WorldTangentX, FVector& WorldTangentY, FVector& WorldTangentZ) const;
367
368 FVector GetWorldVertex( int32 VertexIndex ) const
369 {
370 int32 X, Y;
371 VertexIndexToXY( VertexIndex, X, Y );
372 return GetWorldVertex( X, Y );
373 }
374
375 void GetWorldTangentVectors( int32 VertexIndex, FVector& WorldTangentX, FVector& WorldTangentY, FVector& WorldTangentZ ) const
376 {
377 int32 X, Y;
378 VertexIndexToXY( VertexIndex, X, Y );
379 GetWorldTangentVectors( X, Y, WorldTangentX, WorldTangentY, WorldTangentZ );
380 }
381
382 void GetWorldPositionTangents( int32 VertexIndex, FVector& WorldPos, FVector& WorldTangentX, FVector& WorldTangentY, FVector& WorldTangentZ ) const
383 {
384 int32 X, Y;
385 VertexIndexToXY( VertexIndex, X, Y );
386 GetWorldPositionTangents( X, Y, WorldPos, WorldTangentX, WorldTangentY, WorldTangentZ );
387 }
388
389private:
390 FLandscapeDataInterface DataInterface;
391 ULandscapeComponent* Component = nullptr;
392 bool bWorkOnEditingLayer = false;
393 FColor* HeightMipData = nullptr;
394};
395
396// Helper functions
397template<typename T>
399{
401
402 if (CornerSet)
403 {
404 // Fill unset values
405 while (CornerSet != 15)
406 {
407 if (CornerSet != 15 && (OriginalSet & 1))
408 {
409 if (!(CornerSet & 1 << 1))
410 {
412 CornerSet |= 1 << 1;
413 }
414 if (!(CornerSet & 1 << 2))
415 {
417 CornerSet |= 1 << 2;
418 }
419 }
420 if (CornerSet != 15 && (OriginalSet & 1 << 1))
421 {
422 if (!(CornerSet & 1))
423 {
425 CornerSet |= 1;
426 }
427 if (!(CornerSet & 1 << 3))
428 {
430 CornerSet |= 1 << 3;
431 }
432 }
433 if (CornerSet != 15 && (OriginalSet & 1 << 2))
434 {
435 if (!(CornerSet & 1))
436 {
438 CornerSet |= 1;
439 }
440 if (!(CornerSet & 1 << 3))
441 {
443 CornerSet |= 1 << 3;
444 }
445 }
446 if (CornerSet != 15 && (OriginalSet & 1 << 3))
447 {
448 if (!(CornerSet & 1 << 1))
449 {
451 CornerSet |= 1 << 1;
452 }
453 if (!(CornerSet & 1 << 2))
454 {
456 CornerSet |= 1 << 2;
457 }
458 }
459
461 }
462 }
463}
464
465#endif // WITH_EDITOR
@ Normal
Definition AndroidInputInterface.h:116
#define FORCEINLINE
Definition AndroidPlatform.h:140
#define checkSlow(expr)
Definition AssertionMacros.h:332
#define check(expr)
Definition AssertionMacros.h:314
#define verify(expr)
Definition AssertionMacros.h:319
@ ForceInit
Definition CoreMiscDefines.h:155
#define UE_DEPRECATED(Version, Message)
Definition CoreMiscDefines.h:302
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 X(Name, Desc)
Definition FormatStringSan.h:47
#define FVector
Definition IOSSystemIncludes.h:8
#define LANDSCAPE_ZSCALE
Definition LandscapeDataAccess.h:13
#define LANDSCAPE_INV_ZSCALE
Definition LandscapeDataAccess.h:14
USkinnedMeshComponent float
Definition SkinnedMeshComponent.h:60
CORE_API bool IsInParallelGameThread()
Definition ThreadingBase.cpp:207
CORE_API bool IsInGameThread()
Definition ThreadingBase.cpp:185
UE_INTRINSIC_CAST UE_REWRITE constexpr std::remove_reference_t< T > && MoveTemp(T &&Obj) noexcept
Definition UnrealTemplate.h:520
uint8_t uint8
Definition binka_ue_file_header.h:8
uint16_t uint16
Definition binka_ue_file_header.h:7
Definition Array.h:670
UE_NODEBUG UE_FORCEINLINE_HINT SizeType Add(ElementType &&Item)
Definition Array.h:2696
UE_NODEBUG UE_FORCEINLINE_HINT bool Find(const ElementType &Item, SizeType &Index) const
Definition Array.h:1302
Definition UnrealString.h.inl:34
Definition LandscapeLayerInfoObject.h:60
Definition Texture2D.h:26
GeometryCollection::Facades::FMuscleActivationData Data
Definition MuscleActivationConstraints.h:15
Definition LandscapeDataAccess.h:25
FORCEINLINE FColor PackHeight(uint16 Height)
Definition LandscapeDataAccess.h:38
constexpr float MidValue
Definition LandscapeDataAccess.h:27
FORCEINLINE FVector UnpackNormal(const FColor &InHeightmapSample)
Definition LandscapeDataAccess.h:52
constexpr int32 MaxValue
Definition LandscapeDataAccess.h:26
FORCEINLINE float UnpackHeight(const FColor &InHeightmapSample)
Definition LandscapeDataAccess.h:46
FORCEINLINE float GetLocalHeight(uint16 Height)
Definition LandscapeDataAccess.h:28
FORCEINLINE uint16 GetTexHeight(float Height)
Definition LandscapeDataAccess.h:33
const FName VertexIndex("VertexIndex")
Definition MeshAttributes.h:28
Definition Color.h:486
static constexpr UE_FORCEINLINE_HINT T Square(const T A)
Definition UnrealMathUtility.h:578
T X
Definition Vector.h:62