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 12 of file InstancedActorRenderer.cpp.

12 : Super(ObjectInitializer)
13{
14 PrimaryActorTick.bCanEverTick = false;
15}

Member Function Documentation

◆ BeginPlay()

void AInstancedActorRenderer::BeginPlay ( )
overridevirtual

Definition at line 17 of file InstancedActorRenderer.cpp.

18{
19 Super::BeginPlay();
20
21 UWorld* World = GetWorld();
22
24 if (Settings)
25 {
28 }
29
31 if (Weather)
32 {
35 }
36}
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 236 of file InstancedActorRenderer.cpp.

237{
239 {
240 return InstancedStaticMeshComponent->GetStaticMesh();
241 }
242
243 return nullptr;
244}

References InstancedStaticMeshComponent.

◆ Matches() [1/2]

bool AInstancedActorRenderer::Matches ( UInstancedStaticMeshComponent *  ISM) const

Definition at line 354 of file InstancedActorRenderer.cpp.

355{
357 {
358 return false;
359 }
360
361 if (ISM->GetStaticMesh() == InstancedActorParameters.Mesh)
362 {
363 const int32 NumberOfMaterials = ISM->GetNumMaterials();
364 if (NumberOfMaterials != InstancedActorParameters.Materials.Num())
365 {
366 return false;
367 }
368
369 for (int32 i = 0; i < NumberOfMaterials; i++)
370 {
371 if (ISM->GetMaterial(i) != InstancedActorParameters.Materials[i])
372 {
373 return false;
374 }
375 }
376
377 return true;
378 }
379
380 return false;
381}
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 299 of file InstancedActorRenderer.cpp.

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

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

◆ OnGraphicsSettingsChanged()

void AInstancedActorRenderer::OnGraphicsSettingsChanged ( FGlobalGraphicsSettings  GraphicsSettings)
private

◆ OnWeatherParametersChanged()

void AInstancedActorRenderer::OnWeatherParametersChanged ( FWeatherParameters  WeatherParameters)
private

Definition at line 421 of file InstancedActorRenderer.cpp.

422{
423 CurrentWeatherParameters = WeatherParameters;
424
425 bool IsWinter = WeatherParameters.IsWinterSeason();
426 bool IsWindy = WeatherParameters.WindIntensity > 0.05f;
427
428 // Should render tree wind (WPO)
429 bool ShouldRenderTreeWPO = IsWinter || IsWindy;
430
431 // Should render snow (WPO), like rocks etc.
432 bool ShouldRenderSnowWPO = WeatherParameters.SnowAmount != 0.0f;
433
434 bool ShouldRenderWPO = IsWinter || IsWindy;
435
436 // Only update if the rendering state has changed
437 if (RenderingWPO != ShouldRenderWPO)
438 {
439 RenderingWPO = ShouldRenderWPO;
440 SetRenderWorldPositionOffet(ShouldRenderWPO);
441 }
442}
void SetRenderWorldPositionOffet(bool RenderWPO)

References CurrentWeatherParameters, 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 406 of file InstancedActorRenderer.cpp.

407{
409 {
410 InstancedStaticMeshComponent->SetEvaluateWorldPositionOffset(RenderWPO);
411 InstancedStaticMeshComponent->SetEvaluateWorldPositionOffsetInRayTracing(RenderWPO);
412 }
413}

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 398 of file InstancedActorRenderer.cpp.

399{
401 {
402 InstancedStaticMeshComponent->ShadowCacheInvalidationBehavior = ShadowCacheInvalidationBehaviour;
403 }
404}

References InstancedStaticMeshComponent.

Referenced by OnGraphicsSettingsChanged().

◆ SetupFromInstancedActor()

void AInstancedActorRenderer::SetupFromInstancedActor ( AInstancedActor InstancedActor)

Definition at line 57 of file InstancedActorRenderer.cpp.

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

384{
385 if (WorldPositionOffsetDistance == NewWPODistance)
386 {
387 return;
388 }
389
390 WorldPositionOffsetDistance = NewWPODistance;
391
393 {
394 InstancedStaticMeshComponent->SetWorldPositionOffsetDisableDistance(WorldPositionOffsetDistance);
395 }
396}

References InstancedStaticMeshComponent, and WorldPositionOffsetDistance.

Referenced by OnGraphicsSettingsChanged().

◆ SpawnInstanceBackToActor()

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

Definition at line 184 of file InstancedActorRenderer.cpp.

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

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

◆ SpawnInstancesBackActors()

bool AInstancedActorRenderer::SpawnInstancesBackActors ( )

Definition at line 246 of file InstancedActorRenderer.cpp.

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

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: