UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
InstancedFoliage.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3/*=============================================================================
4InstancedFoliage.h: Instanced foliage type definitions.
5=============================================================================*/
6#pragma once
7
8#include "CoreMinimal.h"
9#include "Misc/Guid.h"
11#include "FoliageInstanceBase.h"
13
15class UActorComponent;
16class UFoliageType;
20class UPrimitiveComponent;
21class UStaticMesh;
22struct FSMInstanceId;
23
24#if WITH_EDITORONLY_DATA
26#endif
27
29
30namespace FoliageElementUtil
31{
33}
34
39{
41 FOLIAGE_NoRandomYaw = 0x00000002,
42 FOLIAGE_Readjusted = 0x00000004,
43 FOLIAGE_InstanceDeleted = 0x00000008, // Used only for migration from pre-HierarchicalISM foliage.
44};
45
67
77
82{
83 // ID of base this instance was painted on
85
87
89
91 : BaseId(0)
92 , BaseComponent(nullptr)
93 {}
94
96
101
103 {
104 Location = Transform.GetTranslation();
105 Rotation = Transform.Rotator();
106 DrawScale3D = FVector3f(Transform.GetScale3D());
107 }
108
109 void AlignToNormal(const FVector& InNormal, float AlignMaxAngle = 0.f)
110 {
112
113 FRotator AlignRotation = InNormal.Rotation();
114 // Static meshes are authored along the vertical axis rather than the X axis, so we add 90 degrees to the static mesh's Pitch.
115 AlignRotation.Pitch -= 90.f;
116 // Clamp its value inside +/- one rotation
118
119 // limit the maximum pitch angle if it's > 0.
120 if (AlignMaxAngle > 0.f)
121 {
122 int32 MaxPitch = static_cast<int32>(AlignMaxAngle);
123 if (AlignRotation.Pitch > MaxPitch)
124 {
125 AlignRotation.Pitch = MaxPitch;
126 }
127 else if (AlignRotation.Pitch < -MaxPitch)
128 {
129 AlignRotation.Pitch = -MaxPitch;
130 }
131 }
132
135 }
136};
137
139{
141
142#if WITH_EDITORONLY_DATA
143 // Allows us to detect if FoliageType was updated while this level wasn't loaded
145
146 // Editor-only placed instances
148#endif
149
151 : Component(nullptr)
152 {
153 }
154
156};
157
162{
164
165#if WITH_EDITORONLY_DATA
166 // Allows us to detect if FoliageType was updated while this level wasn't loaded
168
169 // Editor-only placed instances
170 TArray<FFoliageInstance> Instances;
171#endif
172
173
175
177};
178
183{
184 Unknown = 0,
185 StaticMesh = 1,
186 Actor = 2,
187 ISMActor = 3
188};
189
190struct FFoliageInfo;
191
196{
198#if WITH_EDITORONLY_DATA
199 : Info(InInfo)
200#endif
201 {}
202 virtual ~FFoliageImpl() {}
203
205 virtual void Serialize(FArchive& Ar) = 0;
206 virtual void PostSerialize(FArchive& Ar) {}
207 virtual void PostLoad() {}
208
209#if WITH_EDITORONLY_DATA
210 // Not serialized but FFoliageInfo will make sure it stays valid (mostly Undo/Redo)
212#endif
213
214#if WITH_EDITOR
215 virtual bool IsInitialized() const = 0;
216 virtual void Initialize(const UFoliageType* FoliageType) = 0;
217 virtual void Uninitialize() = 0;
218 virtual void Reapply(const UFoliageType* FoliageType) = 0;
219 virtual int32 GetInstanceCount() const = 0;
220 virtual void PreAddInstances(const UFoliageType* FoliageType, int32 Count) = 0;
221 virtual void AddInstance(const FFoliageInstance& NewInstance) = 0;
222 virtual void RemoveInstance(int32 InstanceIndex) = 0;
223 virtual void MoveInstance(int32 InstanceIndex, UObject*& OutInstanceImplementation) { RemoveInstance(InstanceIndex); }
225 virtual void SetInstanceWorldTransform(int32 InstanceIndex, const FTransform& Transform, bool bTeleport) = 0;
226 virtual FTransform GetInstanceWorldTransform(int32 InstanceIndex) const = 0;
227 virtual void PostUpdateInstances() {}
229 virtual void PostMoveInstances(TArrayView<const int32> InInstancesMoved, bool bFinished) {}
230 virtual bool IsOwnedComponent(const UPrimitiveComponent* PrimitiveComponent) const = 0;
231
232 virtual void SelectAllInstances(bool bSelect) = 0;
233 virtual void SelectInstance(bool bSelect, int32 Index) = 0;
234 virtual void SelectInstances(bool bSelect, const TSet<int32>& SelectedIndices) = 0;
235 virtual int32 GetInstanceIndexFrom(const UPrimitiveComponent* PrimitiveComponent, int32 ComponentIndex) const = 0;
237 virtual void ApplySelection(bool bApply, const TSet<int32>& SelectedIndices) = 0;
238 virtual void ClearSelection(const TSet<int32>& SelectedIndices) = 0;
239
240 virtual void ForEachSMInstance(TFunctionRef<bool(FSMInstanceId)> Callback) const {}
241 virtual void ForEachSMInstance(int32 InstanceIndex, TFunctionRef<bool(FSMInstanceId)> Callback) const {}
242
243 virtual void BeginUpdate() {}
244 virtual void EndUpdate() {}
245 virtual void Refresh(bool Async, bool Force) {}
247 virtual void PreEditUndo(UFoliageType* FoliageType) {}
248 virtual void PostEditUndo(FFoliageInfo* InInfo, UFoliageType* FoliageType) { Info = InInfo; }
249 virtual void NotifyFoliageTypeWillChange(UFoliageType* FoliageType) {}
250
251 // Return true if implementation needs to change
252 virtual bool NotifyFoliageTypeChanged(UFoliageType* FoliageType, bool bSourceChanged) = 0;
253 virtual void EnterEditMode() {}
254 virtual void ExitEditMode() {}
255 virtual bool ShouldAttachToBaseComponent() const { return true; }
256
258 FFoliageInfo* GetInfo() const { check(Info); return Info; }
259#endif
260
261 virtual int32 GetOverlappingSphereCount(const FSphere& Sphere) const { return 0; }
262 virtual int32 GetOverlappingBoxCount(const FBox& Box) const { return 0; }
263 virtual void GetOverlappingBoxTransforms(const FBox& Box, TArray<FTransform>& OutTransforms) const { }
265};
266
271{
274
275#if WITH_EDITORONLY_DATA
276 // Owning IFA
278
279 // Allows us to detect if FoliageType was updated while this level wasn't loaded
281
282 // Editor-only placed instances
283 TArray<FFoliageInstance> Instances;
284
285 // Transient, editor-only locality hash of instances
287
288 // Transient, editor-only set of instances per component
290
291 // Transient, editor-only list of selected instances.
293
294 // Moving instances
296#endif
297
300
303
304 // Will only return a valid component in the case of non-actor foliage
306
308 void PostSerialize(FArchive& Ar);
309 void PostLoad();
310
312 FOLIAGE_API void Initialize(const UFoliageType* FoliageType);
315
317 int32 GetOverlappingBoxCount(const FBox& Box) const;
318 void GetOverlappingBoxTransforms(const FBox& Box, TArray<FTransform>& OutTransforms) const;
320
321#if WITH_EDITOR
322
324 FOLIAGE_API void CreateImplementation(const UFoliageType* FoliageType);
327
328 FOLIAGE_API void ClearSelection();
329
330 FOLIAGE_API void SetInstanceWorldTransform(int32 InstanceIndex, const FTransform& Transform, bool bTeleport);
331
333 FOLIAGE_API void AddInstance(const UFoliageType* InSettings, const FFoliageInstance& InNewInstance);
337
339
341
342 // Apply changes in the FoliageType to the component
349 FOLIAGE_API void GetInstanceAtLocation(const FVector& Location, int32& OutInstance, bool& bOutSucess) const;
352 FOLIAGE_API TArray<int32> GetInstancesOverlappingBox(const FBox& Box) const;
353
354 // Destroy existing clusters and reassign all instances to new clusters
356
358
360
362
363 // Get the number of placed instances
365
369 bool ShouldAttachToBaseComponent() const { return Implementation->ShouldAttachToBaseComponent(); }
370
371 // For debugging. Validate state after editing.
372 void CheckValid();
373
374 void ForEachSMInstance(TFunctionRef<bool(FSMInstanceId)> Callback) const;
375 void ForEachSMInstance(int32 InstanceIndex, TFunctionRef<bool(FSMInstanceId)> Callback) const;
376
377 FOLIAGE_API void Refresh(bool Async, bool Force);
379 FOLIAGE_API void PostEditUndo(UFoliageType* FoliageType);
380 FOLIAGE_API void PreEditUndo(UFoliageType* FoliageType);
383
385 FOLIAGE_API void IncludeActor(const UFoliageType* FoliageType, AActor* InActor);
387
389#endif
390
391 FOLIAGE_API friend FArchive& operator<<(FArchive& Ar, FFoliageInfo& MeshInfo);
392
393 // Non-copyable
394 FFoliageInfo(const FFoliageInfo&) = delete;
396
397private:
401
404};
405
407{
408 explicit operator bool() const
409 {
410 return Info != nullptr
411 && Index != INDEX_NONE;
412 }
413
415 {
416 return Info == InRHS.Info
417 && Index == InRHS.Index;
418 }
419
421 {
422 return !(*this == InRHS);
423 }
424
425#if WITH_EDITOR
426 FFoliageInstance* GetInstance() const
427 {
428 return (Info && Info->Instances.IsValidIndex(Index))
429 ? &Info->Instances[Index]
430 : nullptr;
431 }
432
434 {
435 FFoliageInstance* Instance = GetInstance();
437 return *Instance;
438 }
439#endif
440
442 {
443 return HashCombine(GetTypeHash(InId.Index), GetTypeHash(InId.Info));
444 }
445
446 FFoliageInfo* Info = nullptr;
448};
449
452{
453 enum Type
454 {
457 };
458
459}
460
497
498#if WITH_EDITOR
499// Struct to hold potential instances we've sampled
501{
502 FVector HitLocation;
503 FVector HitNormal;
504 UPrimitiveComponent* HitComponent;
505 float HitWeight;
507
509 FOLIAGE_API bool PlaceInstance(const UWorld* InWorld, const UFoliageType* Settings, FFoliageInstance& Inst, bool bSkipCollision = false);
510};
511#endif
OODEFFUNC typedef void(OODLE_CALLBACK t_fp_OodleCore_Plugin_Free)(void *ptr)
#define check(expr)
Definition AssertionMacros.h:314
@ INDEX_NONE
Definition CoreMiscDefines.h:150
@ ForceInit
Definition CoreMiscDefines.h:155
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
FPlatformTypes::uint64 uint64
A 64-bit unsigned integer.
Definition Platform.h:1117
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
int32 FFoliageInstanceBaseId
Definition FoliageInstanceBase.h:11
#define FVector
Definition IOSSystemIncludes.h:8
EFoliageInstanceFlags
Definition InstancedFoliage.h:39
@ FOLIAGE_InstanceDeleted
Definition InstancedFoliage.h:43
@ FOLIAGE_Readjusted
Definition InstancedFoliage.h:42
@ FOLIAGE_NoRandomYaw
Definition InstancedFoliage.h:41
@ FOLIAGE_AlignToNormal
Definition InstancedFoliage.h:40
EFoliageImplType
Definition InstancedFoliage.h:183
#define DECLARE_LOG_CATEGORY_EXTERN(CategoryName, DefaultVerbosity, CompileTimeVerbosity)
Definition LogMacros.h:361
UE::Math::TQuat< double > FQuat
Definition MathFwd.h:50
UE::Math::TVector< float > FVector3f
Definition MathFwd.h:73
UE::Math::TTransform< double > FTransform
Definition MathFwd.h:53
UE::Math::TRotator< double > FRotator
Definition MathFwd.h:57
const bool
Definition NetworkReplayStreaming.h:178
constexpr uint32 HashCombine(uint32 A, uint32 C)
Definition TypeHash.h:36
uint8_t uint8
Definition binka_ue_file_header.h:8
uint32_t uint32
Definition binka_ue_file_header.h:6
Definition Actor.h:257
Definition InstancedFoliageActor.h:29
Definition Archive.h:1208
Definition UObjectGlobals.h:2492
Definition ArrayView.h:139
Definition Array.h:670
Definition AssetRegistryState.h:50
Definition UnrealString.h.inl:34
Definition UniquePtr.h:107
Definition ActorComponent.h:152
Definition FoliageType_InstancedStaticMesh.h:14
Definition FoliageType.h:106
Definition HierarchicalInstancedStaticMeshComponent.h:136
Definition InstancedStaticMeshComponent.h:158
Definition Object.h:95
Definition StaticMesh.h:593
Definition World.h:918
Definition InstancedFoliage.h:452
Type
Definition InstancedFoliage.h:454
@ Manual
Definition InstancedFoliage.h:455
@ Procedural
Definition InstancedFoliage.h:456
Definition InstancedFoliage.cpp:94
bool FoliageInstanceElementsEnabled()
Definition InstancedFoliage.cpp:103
U16 Index
Definition radfft.cpp:71
Definition BodyInstance.h:320
Definition InstancedFoliage.h:463
FVector EndTrace
Definition InstancedFoliage.h:490
FDesiredFoliageInstance(const FVector &InStartTrace, const FVector &InEndTrace, const UFoliageType *InFoliageType, const float InTraceRadius=0.f)
Definition InstancedFoliage.h:476
FQuat Rotation
Definition InstancedFoliage.h:491
FVector StartTrace
Definition InstancedFoliage.h:489
const struct FBodyInstance * ProceduralVolumeBodyInstance
Definition InstancedFoliage.h:494
FGuid ProceduralGuid
Definition InstancedFoliage.h:488
EFoliagePlacementMode::Type PlacementMode
Definition InstancedFoliage.h:495
float TraceRadius
Definition InstancedFoliage.h:492
FDesiredFoliageInstance()
Definition InstancedFoliage.h:464
float Age
Definition InstancedFoliage.h:493
const UFoliageType * FoliageType
Definition InstancedFoliage.h:487
Definition InstancedFoliage.h:196
virtual void GetOverlappingMeshCount(const FSphere &Sphere, TMap< UStaticMesh *, int32 > &OutCounts) const
Definition InstancedFoliage.h:264
virtual void PostLoad()
Definition InstancedFoliage.h:207
FFoliageImpl(FFoliageInfo *InInfo)
Definition InstancedFoliage.h:197
virtual void AddReferencedObjects(UObject *InThis, FReferenceCollector &Collector)
Definition InstancedFoliage.h:204
virtual void Serialize(FArchive &Ar)=0
virtual int32 GetOverlappingBoxCount(const FBox &Box) const
Definition InstancedFoliage.h:262
virtual ~FFoliageImpl()
Definition InstancedFoliage.h:202
virtual void PostSerialize(FArchive &Ar)
Definition InstancedFoliage.h:206
virtual int32 GetOverlappingSphereCount(const FSphere &Sphere) const
Definition InstancedFoliage.h:261
virtual void GetOverlappingBoxTransforms(const FBox &Box, TArray< FTransform > &OutTransforms) const
Definition InstancedFoliage.h:263
Definition InstancedFoliage.h:271
FFoliageInfo(const FFoliageInfo &)=delete
FOLIAGE_API UHierarchicalInstancedStaticMeshComponent * GetComponent() const
Definition InstancedFoliage.cpp:2026
int32 GetOverlappingBoxCount(const FBox &Box) const
Definition InstancedFoliage.cpp:2092
TUniquePtr< FFoliageImpl > Implementation
Definition InstancedFoliage.h:273
void AddReferencedObjects(UObject *InThis, FReferenceCollector &Collector)
Definition InstancedFoliage.cpp:2037
FFoliageInfo & operator=(FFoliageInfo &&Other)=default
FOLIAGE_API bool IsInitialized() const
void PostSerialize(FArchive &Ar)
Definition InstancedFoliage.cpp:2045
void GetOverlappingBoxTransforms(const FBox &Box, TArray< FTransform > &OutTransforms) const
Definition InstancedFoliage.cpp:2102
void GetOverlappingMeshCount(const FSphere &Sphere, TMap< UStaticMesh *, int32 > &OutCounts) const
Definition InstancedFoliage.cpp:2110
FOLIAGE_API FFoliageInfo()
Definition InstancedFoliage.cpp:2014
FOLIAGE_API void Initialize(const UFoliageType *FoliageType)
void PostLoad()
Definition InstancedFoliage.cpp:2053
FFoliageInfo & operator=(const FFoliageInfo &)=delete
FOLIAGE_API ~FFoliageInfo()
Definition InstancedFoliage.cpp:2023
EFoliageImplType Type
Definition InstancedFoliage.h:272
FFoliageInfo(FFoliageInfo &&Other)=default
FOLIAGE_API void CreateImplementation(EFoliageImplType InType)
Definition InstancedFoliage.cpp:2061
FOLIAGE_API void Uninitialize()
FOLIAGE_API friend FArchive & operator<<(FArchive &Ar, FFoliageInfo &MeshInfo)
Definition InstancedFoliage.cpp:494
int32 GetOverlappingSphereCount(const FSphere &Sphere) const
Definition InstancedFoliage.cpp:2082
Definition InstancedFoliage.h:407
bool operator!=(const FFoliageInstanceId &InRHS) const
Definition InstancedFoliage.h:420
bool operator==(const FFoliageInstanceId &InRHS) const
Definition InstancedFoliage.h:414
int32 Index
Definition InstancedFoliage.h:447
FFoliageInfo * Info
Definition InstancedFoliage.h:446
friend uint32 GetTypeHash(const FFoliageInstanceId &InId)
Definition InstancedFoliage.h:441
Definition InstancedFoliage.h:50
FRotator PreAlignRotation
Definition InstancedFoliage.h:53
FVector Location
Definition InstancedFoliage.h:51
FFoliageInstancePlacementInfo()
Definition InstancedFoliage.h:58
FRotator Rotation
Definition InstancedFoliage.h:52
FVector3f DrawScale3D
Definition InstancedFoliage.h:54
uint32 Flags
Definition InstancedFoliage.h:56
float ZOffset
Definition InstancedFoliage.h:55
Definition InstancedFoliage.h:72
UActorComponent * Base
Definition InstancedFoliage.h:73
FGuid ProceduralGuid
Definition InstancedFoliage.h:74
friend FArchive & operator<<(FArchive &Ar, FFoliageInstance_Deprecated &Instance)
Definition InstancedFoliage.cpp:277
Definition InstancedFoliage.h:82
FFoliageInstanceBaseId BaseId
Definition InstancedFoliage.h:84
FTransform GetInstanceWorldTransform() const
Definition InstancedFoliage.h:97
FGuid ProceduralGuid
Definition InstancedFoliage.h:86
void AlignToNormal(const FVector &InNormal, float AlignMaxAngle=0.f)
Definition InstancedFoliage.h:109
friend FArchive & operator<<(FArchive &Ar, FFoliageInstance &Instance)
Definition InstancedFoliage.cpp:318
UActorComponent * BaseComponent
Definition InstancedFoliage.h:88
FFoliageInstance()
Definition InstancedFoliage.h:90
void SetInstanceWorldTransform(const FTransform &Transform)
Definition InstancedFoliage.h:102
Definition InstancedFoliage.h:162
friend FArchive & operator<<(FArchive &Ar, FFoliageMeshInfo_Deprecated2 &MeshInfo)
Definition InstancedFoliage.cpp:482
UHierarchicalInstancedStaticMeshComponent * Component
Definition InstancedFoliage.h:163
FFoliageMeshInfo_Deprecated2()
Definition InstancedFoliage.cpp:478
Definition InstancedFoliage.h:139
friend FArchive & operator<<(FArchive &Ar, FFoliageMeshInfo_Deprecated &MeshInfo)
Definition InstancedFoliage.cpp:450
UHierarchicalInstancedStaticMeshComponent * Component
Definition InstancedFoliage.h:140
FFoliageMeshInfo_Deprecated()
Definition InstancedFoliage.h:150
Definition Guid.h:109
Definition SMInstanceElementId.h:20
T Pitch
Definition Rotator.h:46
static double NormalizeAxis(double Angle)
Definition Rotator.h:706