Agrarsense
Public Member Functions | Public Attributes | Protected Member Functions | Protected Attributes | Private Member Functions | Private Attributes | List of all members
AInstancedActorRenderer Class Reference

#include <InstancedActorRenderer.h>

Inheritance diagram for AInstancedActorRenderer:
Inheritance graph
[legend]
Collaboration diagram for AInstancedActorRenderer:
Collaboration graph
[legend]

Public Member Functions

 AInstancedActorRenderer (const FObjectInitializer &ObjectInitializer)
 
virtual void BeginPlay () override
 
virtual void EndPlay (const EEndPlayReason::Type EndPlayReason) override
 
void SetupFromInstancedActor (AInstancedActor *InstancedActor)
 
bool SpawnInstanceBackToActor (UInstancedStaticMeshComponent *ISM, int32 Index, bool OnlyTree)
 
bool Matches (UStaticMeshComponent *StaticMeshComponent, const bool CanHaveAlternativeMaterial) const
 
bool Matches (UInstancedStaticMeshComponent *ISM) const
 
bool SpawnInstancesBackActors ()
 
UInstancedStaticMeshComponent * GetInstancedStaticMeshComponent () const
 
FInstancedActorParameters GetInstancedActorParameters () const
 
UStaticMesh * GetStaticMesh () const
 

Public Attributes

UInstancedStaticMeshComponent * InstancedStaticMeshComponent = nullptr
 

Protected Member Functions

void SetWorldPositionOffsetDistance (int32 NewWPODistance)
 
void SetShadowCacheBehaviour (EShadowCacheInvalidationBehavior ShadowCacheInvalidationBehaviour)
 
void SetRenderWorldPositionOffet (bool RenderWPO)
 

Protected Attributes

FInstancedActorParameters InstancedActorParameters
 

Private Member Functions

void OnGraphicsSettingsChanged (FGlobalGraphicsSettings GraphicsSettings)
 
void OnWeatherParametersChanged (FWeatherParameters WeatherParameters)
 

Private Attributes

FWeatherParameters CurrentWeatherParameters
 
int32 WorldPositionOffsetDistance = 30000
 
bool Rendering = true
 
bool RenderingWPO = false
 

Detailed Description

Definition at line 50 of file InstancedActorRenderer.h.

Constructor & Destructor Documentation

◆ AInstancedActorRenderer()

AInstancedActorRenderer::AInstancedActorRenderer ( const FObjectInitializer &  ObjectInitializer)

Definition at line 15 of file InstancedActorRenderer.cpp.

15 : Super(ObjectInitializer)
16{
17 PrimaryActorTick.bCanEverTick = false;
18}

Member Function Documentation

◆ BeginPlay()

void AInstancedActorRenderer::BeginPlay ( )
overridevirtual

Definition at line 20 of file InstancedActorRenderer.cpp.

21{
22 Super::BeginPlay();
23
24 UWorld* World = GetWorld();
25
27 if (Settings)
28 {
31 }
32
34 if (Weather)
35 {
38 }
39}
void OnGraphicsSettingsChanged(FGlobalGraphicsSettings GraphicsSettings)
void OnWeatherParametersChanged(FWeatherParameters WeatherParameters)
FWeatherParameters CurrentWeatherParameters
const FWeatherParameters & GetCurrentWeather() const
Definition: Weather.h:76
FLevelEventDelegate_WeatherChanged OnWeatherChanged
Definition: Weather.h:91
int32 GetWorldPositionOffsetRenderDistance() const
FGraphicsSettingsDelegate OnGraphicsSettingsChanged
static UAgrarsenseSettings * GetAgrarsenseSettings()
static AWeather * GetWeatherActor(const UObject *WorldContextObject)

References CurrentWeatherParameters, UAgrarsenseStatics::GetAgrarsenseSettings(), AWeather::GetCurrentWeather(), UAgrarsenseStatics::GetWeatherActor(), UAgrarsenseSettings::GetWorldPositionOffsetRenderDistance(), OnGraphicsSettingsChanged(), UAgrarsenseSettings::OnGraphicsSettingsChanged, AWeather::OnWeatherChanged, OnWeatherParametersChanged(), and WorldPositionOffsetDistance.

◆ EndPlay()

void AInstancedActorRenderer::EndPlay ( const EEndPlayReason::Type  EndPlayReason)
overridevirtual

◆ GetInstancedActorParameters()

FInstancedActorParameters AInstancedActorRenderer::GetInstancedActorParameters ( ) const
inline

Definition at line 82 of file InstancedActorRenderer.h.

83 {
85 }
FInstancedActorParameters InstancedActorParameters

◆ GetInstancedStaticMeshComponent()

UInstancedStaticMeshComponent * AInstancedActorRenderer::GetInstancedStaticMeshComponent ( ) const
inline

Definition at line 76 of file InstancedActorRenderer.h.

77 {
79 }
UInstancedStaticMeshComponent * InstancedStaticMeshComponent

Referenced by AInstancedRendererManager::AppendOrCreateISM().

◆ GetStaticMesh()

UStaticMesh * AInstancedActorRenderer::GetStaticMesh ( ) const

Definition at line 239 of file InstancedActorRenderer.cpp.

240{
242 {
243 return InstancedStaticMeshComponent->GetStaticMesh();
244 }
245
246 return nullptr;
247}

References InstancedStaticMeshComponent.

◆ Matches() [1/2]

bool AInstancedActorRenderer::Matches ( UInstancedStaticMeshComponent *  ISM) const

Definition at line 357 of file InstancedActorRenderer.cpp.

358{
360 {
361 return false;
362 }
363
364 if (ISM->GetStaticMesh() == InstancedActorParameters.Mesh)
365 {
366 const int32 NumberOfMaterials = ISM->GetNumMaterials();
367 if (NumberOfMaterials != InstancedActorParameters.Materials.Num())
368 {
369 return false;
370 }
371
372 for (int32 i = 0; i < NumberOfMaterials; i++)
373 {
374 if (ISM->GetMaterial(i) != InstancedActorParameters.Materials[i])
375 {
376 return false;
377 }
378 }
379
380 return true;
381 }
382
383 return false;
384}
TWeakObjectPtr< UStaticMesh > Mesh
TArray< UMaterialInterface * > Materials

References InstancedActorParameters, InstancedStaticMeshComponent, FInstancedActorParameters::Materials, and FInstancedActorParameters::Mesh.

◆ Matches() [2/2]

bool AInstancedActorRenderer::Matches ( UStaticMeshComponent *  StaticMeshComponent,
const bool  CanHaveAlternativeMaterial 
) const

Definition at line 302 of file InstancedActorRenderer.cpp.

303{
304 if (!StaticMeshComponent)
305 {
306 return false;
307 }
308
309 UStaticMesh* StaticMesh = StaticMeshComponent->GetStaticMesh();
310 if (!StaticMesh)
311 {
312 return false;
313 }
314
315 if (!CanHaveAlternativeMaterial)
316 {
317 if (InstancedActorParameters.Mesh == StaticMesh)
318 {
319 return true;
320 }
321 }
322 else
323 {
324 const int32 NumberOfMaterials = StaticMeshComponent->GetNumMaterials();
325 TArray<UMaterialInterface*> MeshMaterials;
326 MeshMaterials.Reserve(NumberOfMaterials);
327 for (int32 i = 0; i < NumberOfMaterials; i++)
328 {
329 MeshMaterials.Add(StaticMeshComponent->GetMaterial(i));
330 }
331
332 if (InstancedActorParameters.Mesh == StaticMesh)
333 {
334 bool bMaterialsMatch = true;
335
336 for (int32 MaterialIndex = 0; MaterialIndex < InstancedActorParameters.Materials.Num(); ++MaterialIndex)
337 {
338 UMaterialInterface* UniqueMeshMaterial = InstancedActorParameters.Materials[MaterialIndex];
339 UMaterialInterface* MeshMaterial = MeshMaterials[MaterialIndex];
340 if (UniqueMeshMaterial != MeshMaterial)
341 {
342 bMaterialsMatch = false;
343 }
344 }
345 MeshMaterials.Empty();
346
347 if (bMaterialsMatch)
348 {
349 return true;
350 }
351 }
352 }
353
354 return false;
355}

References InstancedActorParameters, FInstancedActorParameters::Materials, and FInstancedActorParameters::Mesh.

◆ OnGraphicsSettingsChanged()

void AInstancedActorRenderer::OnGraphicsSettingsChanged ( FGlobalGraphicsSettings  GraphicsSettings)
private

◆ OnWeatherParametersChanged()

void AInstancedActorRenderer::OnWeatherParametersChanged ( FWeatherParameters  WeatherParameters)
private

Definition at line 424 of file InstancedActorRenderer.cpp.

425{
426 CurrentWeatherParameters = WeatherParameters;
427
428 bool HideLeaves = WeatherParameters.HideTreeLeaves;
429 bool IsWinter = WeatherParameters.IsWinterSeason();
430 bool IsWindy = WeatherParameters.WindIntensity > 0.05f;
431
432 // Should render tree wind (WPO)
433 bool ShouldRenderTreeWPO = IsWinter || IsWindy;
434
435 // Should render snow (WPO), like rocks etc.
436 bool ShouldRenderSnowWPO = WeatherParameters.SnowAmount != 0.0f;
437
438 bool ShouldRenderWPO = IsWinter || IsWindy;
439
440 // If HideLeaves is true, we need to ensure RenderingWPO is set to true
441 bool NewRenderingWPO = ShouldRenderWPO || HideLeaves;
442
443 // Only update if the rendering state has changed
444 if (RenderingWPO != NewRenderingWPO)
445 {
446 RenderingWPO = NewRenderingWPO;
447 SetRenderWorldPositionOffet(NewRenderingWPO);
448 }
449}
void SetRenderWorldPositionOffet(bool RenderWPO)

References CurrentWeatherParameters, FWeatherParameters::HideTreeLeaves, FWeatherParameters::IsWinterSeason(), RenderingWPO, SetRenderWorldPositionOffet(), FWeatherParameters::SnowAmount, and FWeatherParameters::WindIntensity.

Referenced by BeginPlay(), and EndPlay().

◆ SetRenderWorldPositionOffet()

void AInstancedActorRenderer::SetRenderWorldPositionOffet ( bool  RenderWPO)
protected

Sets whether the World Position Offset (WPO) rendering is enabled or disabled.

Parameters
RenderWPOTrue to enable World Position Offset rendering, false to disable.

Definition at line 409 of file InstancedActorRenderer.cpp.

410{
412 {
413 InstancedStaticMeshComponent->SetEvaluateWorldPositionOffset(RenderWPO);
414 InstancedStaticMeshComponent->SetEvaluateWorldPositionOffsetInRayTracing(RenderWPO);
415 }
416}

References InstancedStaticMeshComponent.

Referenced by OnWeatherParametersChanged().

◆ SetShadowCacheBehaviour()

void AInstancedActorRenderer::SetShadowCacheBehaviour ( EShadowCacheInvalidationBehavior  ShadowCacheInvalidationBehaviour)
protected

Sets the behavior for shadow cache invalidation. Default Rigid.

Parameters
ShadowCacheInvalidationBehaviourThe new behavior for shadow cache invalidation.

Definition at line 401 of file InstancedActorRenderer.cpp.

402{
404 {
405 InstancedStaticMeshComponent->ShadowCacheInvalidationBehavior = ShadowCacheInvalidationBehaviour;
406 }
407}

References InstancedStaticMeshComponent.

Referenced by OnGraphicsSettingsChanged().

◆ SetupFromInstancedActor()

void AInstancedActorRenderer::SetupFromInstancedActor ( AInstancedActor InstancedActor)

Definition at line 60 of file InstancedActorRenderer.cpp.

61{
62 if (!InstancedActor)
63 {
64 return;
65 }
66
67 UStaticMeshComponent* StaticMeshComponent = InstancedActor->GetStaticMeshComponent();
68 UStaticMesh* Mesh = StaticMeshComponent->GetStaticMesh();
69 UClass* ClassPtr = InstancedActor->GetClass();
70
71 FString Name = IInteractable::Execute_GetInteractableName(InstancedActor).ToString();
72
73 if (Name.IsEmpty())
74 {
75 Name = ClassPtr->GetAuthoredName();
76 if (Name.EndsWith(TEXT("_C")))
77 {
78 Name = Name.LeftChop(2);
79 }
80 if (Name.StartsWith(TEXT("BP_")))
81 {
82 Name = Name.RightChop(3);
83 }
84 Name.ReplaceInline(TEXT("_"), TEXT(" "));
85 Name.ReplaceInline(TEXT("Instanced"), TEXT(" "));
86 }
87
88#if WITH_EDITOR
89 FString ActorName = Name;
90 ActorName.ReplaceInline(TEXT(","), TEXT(""));
91 ActorName.ReplaceInline(TEXT(" "), TEXT("_"));
92 ActorName += "_Instanced";
93 SetActorLabel(ActorName);
94#endif
95
96 // Generate a 4-character GUID
97 FString Guid = FGuid::NewGuid().ToString().Left(4);
98 Name = FString::Printf(TEXT("%s(_%s_)"), *Name, *Guid);
99
100 InstancedStaticMeshComponent = NewObject<UInstancedStaticMeshComponent>(this);
101 InstancedStaticMeshComponent->AttachToComponent(GetRootComponent(), FAttachmentTransformRules::KeepRelativeTransform);
102 AddInstanceComponent(InstancedStaticMeshComponent);
103
104 // Add new instance.
105 const FTransform& Transform = InstancedActor->GetActorTransform();
107
108 InstancedStaticMeshComponent->Rename(*Name);
109 InstancedStaticMeshComponent->bEditableWhenInherited = false;
110 InstancedStaticMeshComponent->RegisterComponent();
111 InstancedStaticMeshComponent->SetCollisionEnabled(ECollisionEnabled::QueryAndPhysics);
112 InstancedStaticMeshComponent->CreatePhysicsState(false);
113 InstancedStaticMeshComponent->SetSimulatePhysics(false);
114 InstancedStaticMeshComponent->SetStaticMesh(Mesh);
115 InstancedStaticMeshComponent->SetMobility(EComponentMobility::Static);
116 InstancedStaticMeshComponent->SetHiddenInGame(false);
117 InstancedStaticMeshComponent->SetVisibility(true);
118 InstancedStaticMeshComponent->AttachToComponent(RootComponent, FAttachmentTransformRules::KeepWorldTransform);
119 InstancedStaticMeshComponent->InstanceStartCullDistance = InstancedActor->GetInstanceStartCullDistance();
120 InstancedStaticMeshComponent->InstanceEndCullDistance = InstancedActor->GetInstanceEndCullDistance();
121
122 bool AllowWorldPositionOffsetDisable = InstancedActor->GetAllowWorldPositionOffsetDisable();
123
124 // For whatever reason this only works when done a bit later..
125 FTimerHandle Handle;
126 GetWorld()->GetTimerManager().SetTimer(Handle, FTimerDelegate::CreateLambda([this, AllowWorldPositionOffsetDisable] {
127 if (InstancedStaticMeshComponent && AllowWorldPositionOffsetDisable && CurrentWeatherParameters.WindIntensity < 0.05f)
128 {
129 InstancedStaticMeshComponent->SetEvaluateWorldPositionOffset(false);
130 InstancedStaticMeshComponent->SetEvaluateWorldPositionOffsetInRayTracing(false);
131 }}), 0.350f, false);
132
133 // Thermal and Semantic camera use custom depth.
134 // RenderCustomDepth is set to false, if no Thermal or Semantic camera exists in the level,
135 // and is automatically set to true/false for all instances when they are spawned/destroyed.
136 // Doing this saves a lot rendering performance.
137 InstancedStaticMeshComponent->SetRenderCustomDepth(true);
138 InstancedStaticMeshComponent->SetCustomDepthStencilValue(StaticMeshComponent->CustomDepthStencilValue);
139
140 // Huge performance implication, recommend is Rigid (especially for Foliage with WPO).
141 // https://docs.unrealengine.com/5.3/en-US/PythonAPI/class/ShadowCacheInvalidationBehavior.html
142 InstancedStaticMeshComponent->ShadowCacheInvalidationBehavior = EShadowCacheInvalidationBehavior::Rigid;
143
144 const int32 NumberOfMaterials = StaticMeshComponent->GetNumMaterials();
145 TArray<UMaterialInterface*> MeshMaterials;
146 MeshMaterials.Reserve(NumberOfMaterials);
147 for (int32 i = 0; i < NumberOfMaterials; i++)
148 {
149 MeshMaterials.Add(StaticMeshComponent->GetMaterial(i));
150 }
151
154 InstancedActorParameters.Materials = MeshMaterials;
155 InstancedActorParameters.CustomDepthStencilValue = StaticMeshComponent->CustomDepthStencilValue;
156 InstancedActorParameters.AllowWorldPositionOffsetDisable = AllowWorldPositionOffsetDisable;
157 InstancedActorParameters.IsTree = InstancedActor->IsTreeActor();
158
159 // Set materials to newly created UInstancedStaticMeshComponent
160 const int32 MaterialCount = MeshMaterials.Num();
161 for (int32 MaterialIndex = 0; MaterialIndex < MaterialCount; ++MaterialIndex)
162 {
163 UMaterialInterface* MaterialInterface = InstancedActorParameters.Materials[MaterialIndex];
164
165 if (MaterialInterface)
166 {
167 InstancedStaticMeshComponent->SetMaterial(MaterialIndex, MaterialInterface);
168
169#if WITH_EDITOR
170 // Validate in Editor that material has bUsedWithInstancedStaticMeshes on
171 UMaterial* Material = Cast<UMaterial>(MaterialInterface);
172 if (Material)
173 {
174 if (!Material->bUsedWithInstancedStaticMeshes)
175 {
176 UE_LOG(LogTemp, Warning, TEXT("AInstancedRendererManager: Material '%s' bUsedWithInstancedStaticMeshes is not set to true!"), *Material->GetName());
177 }
178 }
179#endif
180 }
181 }
182
183 InstancedActor->InstanceAdded();
184 InstancedActor->Destroy();
185}
int32 GetInstanceEndCullDistance() const
int32 GetInstanceStartCullDistance() const
UStaticMeshComponent * GetStaticMeshComponent() const
bool GetAllowWorldPositionOffsetDisable() const
bool IsTreeActor() const
TSubclassOf< AActor > ActorClass

References FInstancedActorParameters::ActorClass, FInstancedActorParameters::AllowWorldPositionOffsetDisable, CurrentWeatherParameters, FInstancedActorParameters::CustomDepthStencilValue, AInstancedActor::GetAllowWorldPositionOffsetDisable(), AInstancedActor::GetInstanceEndCullDistance(), AInstancedActor::GetInstanceStartCullDistance(), AInstancedActor::GetStaticMeshComponent(), AInstancedActor::InstanceAdded(), InstancedActorParameters, InstancedStaticMeshComponent, FInstancedActorParameters::IsTree, AInstancedActor::IsTreeActor(), FInstancedActorParameters::Materials, FInstancedActorParameters::Mesh, Transform, and FWeatherParameters::WindIntensity.

Referenced by AInstancedRendererManager::AddActorToInstancedRendering().

◆ SetWorldPositionOffsetDistance()

void AInstancedActorRenderer::SetWorldPositionOffsetDistance ( int32  NewWPODistance)
protected

Sets the distance for the World Position Offset (WPO) effect.

Parameters
NewWPODistanceThe new distance for the World Position Offset.

Definition at line 386 of file InstancedActorRenderer.cpp.

387{
388 if (WorldPositionOffsetDistance == NewWPODistance)
389 {
390 return;
391 }
392
393 WorldPositionOffsetDistance = NewWPODistance;
394
396 {
397 InstancedStaticMeshComponent->SetWorldPositionOffsetDisableDistance(WorldPositionOffsetDistance);
398 }
399}

References InstancedStaticMeshComponent, and WorldPositionOffsetDistance.

Referenced by OnGraphicsSettingsChanged().

◆ SpawnInstanceBackToActor()

bool AInstancedActorRenderer::SpawnInstanceBackToActor ( UInstancedStaticMeshComponent *  ISM,
int32  Index,
bool  OnlyTree 
)

Definition at line 187 of file InstancedActorRenderer.cpp.

188{
189 if (!ISM || !InstancedStaticMeshComponent|| Index < 0 || Index >= ISM->GetInstanceCount())
190 {
191 return false;
192 }
193
195 {
196 return false;
197 }
198
199 UWorld* World = GetWorld();
200 if (!World)
201 {
202 return false;
203 }
204
205 if (OnlyTree && !InstancedActorParameters.IsTree)
206 {
207 return false;
208 }
209
210 UClass* ActorClass = InstancedActorParameters.ActorClass;
211 if (!ActorClass)
212 {
213 return false;
214 }
215
216 // Get the transform for the specified instance
217 FTransform InstanceTransform;
218 InstancedStaticMeshComponent->GetInstanceTransform(Index, InstanceTransform);
219
220 // Spawn the actor
221 AActor* SpawnedActor = World->SpawnActorDeferred<AActor>(ActorClass, InstanceTransform);
222 if (SpawnedActor)
223 {
224 AInstancedActor* InstancedActor = Cast<AInstancedActor>(SpawnedActor);
225 if (InstancedActor)
226 {
227 InstancedActor->AddToInstancedRenderer = false;
228 }
229
230 SpawnedActor->FinishSpawning(InstanceTransform);
231
232 // Remove this ISM instance.
233 return InstancedStaticMeshComponent->RemoveInstance(Index);
234 }
235
236 return true;
237}

References FInstancedActorParameters::ActorClass, AInstancedActor::AddToInstancedRenderer, InstancedActorParameters, InstancedStaticMeshComponent, and FInstancedActorParameters::IsTree.

◆ SpawnInstancesBackActors()

bool AInstancedActorRenderer::SpawnInstancesBackActors ( )

Definition at line 249 of file InstancedActorRenderer.cpp.

250{
251 UWorld* World = GetWorld();
252
253 if (!World)
254 {
255 return false;
256 }
257
259 {
260 return false;
261 }
262
263 UClass* Class = InstancedActorParameters.ActorClass;
264 if (!Class)
265 {
266 UE_LOG(LogTemp, Warning, TEXT("AInstancedActorRenderer: No spawn class setup."));
267 return false;
268 }
269
270 InstancedStaticMeshComponent->SetVisibility(false);
271
272 // Extract transforms from ISM component into TArray
273 TArray<FTransform> Transforms;
274
275 const int32 InstanceCount = InstancedStaticMeshComponent->GetInstanceCount();
276
277 for (int32 i = 0; i < InstanceCount; i++)
278 {
279 FTransform Transform;
280 InstancedStaticMeshComponent->GetInstanceTransform(i, Transform);
281 Transforms.Add(Transform);
282 }
283
284 // Spawn actors to level
285 for (const FTransform& Transform : Transforms)
286 {
287 if (Class)
288 {
289 AActor* SpawnedActor = World->SpawnActorDeferred<AActor>(Class, Transform);
290 if (SpawnedActor)
291 {
292 SpawnedActor->FinishSpawning(Transform);
293 }
294 }
295 }
296
297 InstancedStaticMeshComponent->DestroyComponent();
298
299 return true;
300}

References FInstancedActorParameters::ActorClass, InstancedActorParameters, InstancedStaticMeshComponent, and Transform.

Referenced by AInstancedRendererManager::SpawnAllInstancesBackToActors().

Member Data Documentation

◆ CurrentWeatherParameters

FWeatherParameters AInstancedActorRenderer::CurrentWeatherParameters
private

◆ InstancedActorParameters

FInstancedActorParameters AInstancedActorRenderer::InstancedActorParameters
protected

◆ InstancedStaticMeshComponent

UInstancedStaticMeshComponent* AInstancedActorRenderer::InstancedStaticMeshComponent = nullptr

◆ Rendering

bool AInstancedActorRenderer::Rendering = true
private

Definition at line 134 of file InstancedActorRenderer.h.

◆ RenderingWPO

bool AInstancedActorRenderer::RenderingWPO = false
private

Definition at line 136 of file InstancedActorRenderer.h.

Referenced by OnWeatherParametersChanged().

◆ WorldPositionOffsetDistance

int32 AInstancedActorRenderer::WorldPositionOffsetDistance = 30000
private

World Position Offset (WPO) render distance in cm

Definition at line 132 of file InstancedActorRenderer.h.

Referenced by BeginPlay(), and SetWorldPositionOffsetDistance().


The documentation for this class was generated from the following files: