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

#include <InstancedRendererManager.h>

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

Public Member Functions

 AInstancedRendererManager (const FObjectInitializer &ObjectInitializer)
 
virtual void BeginPlay () override
 
virtual void EndPlay (const EEndPlayReason::Type EndPlayReason) override
 
bool AddActorToInstancedRendering (AInstancedActor *InstancedActor)
 
bool AppendISM (UInstancedStaticMeshComponent *ISM)
 
bool AppendOrCreateISM (UInstancedStaticMeshComponent *ISM)
 
void SpawnAllInstancesBackToActors ()
 
bool SpawnInstanceBackToActor (UInstancedStaticMeshComponent *ISM, int32 Index, bool OnlyTree)
 
void ExportTreesAsCSV ()
 
void DestroyOverlappingInstancesBox (UInstancedStaticMeshComponent *ISM, FBox AreaBox, bool OnlyTrees)
 
void SetInstancedRendering (bool Visible)
 
TArray< AInstancedActorRenderer * > GetAllInstancedActorRendererActors () const
 
int32 GetTotalInstanceCount ()
 

Protected Attributes

TArray< AInstancedActorRenderer * > InstancedRenderers
 
int32 TotalInstanceCount = 0
 

Private Attributes

bool AllowISMCreation = false
 

Static Private Attributes

static AInstancedRendererManagerInstance = nullptr
 

Detailed Description

Manages all AInstancedActorRenderer actors. Handles adding/removing instances, spawning them back into actors, and toggling visibility.

Definition at line 20 of file InstancedRendererManager.h.

Constructor & Destructor Documentation

◆ AInstancedRendererManager()

AInstancedRendererManager::AInstancedRendererManager ( const FObjectInitializer &  ObjectInitializer)

Definition at line 16 of file InstancedRendererManager.cpp.

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

Member Function Documentation

◆ AddActorToInstancedRendering()

bool AInstancedRendererManager::AddActorToInstancedRendering ( AInstancedActor InstancedActor)

Adds an AInstancedActor to the appropriate instanced renderer.

Definition at line 65 of file InstancedRendererManager.cpp.

66{
68 {
69 return false;
70 }
71
72 if (!InstancedActor)
73 {
74#if WITH_EDITOR
75 UE_LOG(LogTemp, Warning, TEXT("InstancedRenderer.cpp: Actor is null!"));
76#endif
77 return false;
78 }
79
80 if (InstancedActor->UpdateTransformAutomatically())
81 {
82#if WITH_EDITOR
83 UE_LOG(LogTemp, Warning, TEXT("InstancedRenderer.cpp: AInstancedActor %s is set to update transform automatically."), *InstancedActor->GetName());
84#endif
85 return false;
86 }
87
88 UStaticMeshComponent* StaticMeshComponent = InstancedActor->GetStaticMeshComponent();
89 if (!StaticMeshComponent)
90 {
91#if WITH_EDITOR
92 UE_LOG(LogTemp, Warning, TEXT("InstancedRenderer.cpp: AInstancedActor %s UStaticMeshComponent is null!"), *InstancedActor->GetName());
93#endif
94 return false;
95 }
96
97 UStaticMesh* Mesh = StaticMeshComponent->GetStaticMesh();
98 if (!Mesh)
99 {
100#if WITH_EDITOR
101 UE_LOG(LogTemp, Warning, TEXT("InstancedRenderer.cpp: AInstancedActor %s UStaticMeshComponent mesh is null!"), *InstancedActor->GetName());
102#endif
103 return false;
104 }
105
106 // Loop throigh InstancedRenderers and check if we already have this type of instance in the world.
108 {
109 if (Renderer && Renderer->Matches(StaticMeshComponent, InstancedActor->AlternativeMaterial))
110 {
111 UInstancedStaticMeshComponent* Comp = Renderer->GetInstancedStaticMeshComponent();
112 if (Comp)
113 {
114 Comp->AddInstance(InstancedActor->GetActorTransform());
115 InstancedActor->InstanceAdded();
116 InstancedActor->Destroy();
117 return true;
118 }
119 }
120 }
121
122 // Else this is new instance, create new AInstancedActorRenderer Actor.
123 FTransform SpawnTransform = FTransform::Identity;
124 FActorSpawnParameters SpawnParams;
125
126 AInstancedActorRenderer* NewRenderer = GetWorld()->SpawnActor<AInstancedActorRenderer>(
127 AInstancedActorRenderer::StaticClass(),
128 SpawnTransform,
129 SpawnParams
130 );
131
132 InstancedRenderers.AddUnique(NewRenderer);
133 NewRenderer->SetupFromInstancedActor(InstancedActor);
134
135 return true;
136}
void SetupFromInstancedActor(AInstancedActor *InstancedActor)
bool UpdateTransformAutomatically() const
UStaticMeshComponent * GetStaticMeshComponent() const
TArray< AInstancedActorRenderer * > InstancedRenderers

References AllowISMCreation, AInstancedActor::AlternativeMaterial, AInstancedActor::GetStaticMeshComponent(), AInstancedActor::InstanceAdded(), InstancedRenderers, AInstancedActorRenderer::SetupFromInstancedActor(), and AInstancedActor::UpdateTransformAutomatically().

Referenced by AInstancedActor::AddToInstancedRendering().

◆ AppendISM()

bool AInstancedRendererManager::AppendISM ( UInstancedStaticMeshComponent *  ISM)

Appends an existing Instanced Static Mesh (ISM) to a matching AInstancedActorRenderer instance.

Definition at line 138 of file InstancedRendererManager.cpp.

139{
140 if (!ISM)
141 {
142 return false;
143 }
144
146 {
147 if (!Renderer || !Renderer->Matches(ISM))
148 {
149 continue;
150 }
151
152 UInstancedStaticMeshComponent* Comp = Renderer->GetInstancedStaticMeshComponent();
153 if (!Comp)
154 {
155 continue;
156 }
157
158 const int32 InstanceCount = ISM->GetInstanceCount();
159 for (int32 i = 0; i < InstanceCount; ++i)
160 {
161 FTransform InstanceTransform;
162 if (ISM->GetInstanceTransform(i, InstanceTransform, true))
163 {
164 Comp->AddInstance(InstanceTransform);
165 }
166 }
167
168 return true;
169 }
170
171 return false;
172}

References InstancedRenderers.

Referenced by AppendOrCreateISM().

◆ AppendOrCreateISM()

bool AInstancedRendererManager::AppendOrCreateISM ( UInstancedStaticMeshComponent *  ISM)

Appends an existing Instanced Static Mesh (ISM) to a matching AInstancedActorRenderer instance. If no matching renderer exists, creates a new one.

Definition at line 174 of file InstancedRendererManager.cpp.

175{
176 if (!ISM)
177 {
178 return false;
179 }
180
181 if (!AppendISM(ISM))
182 {
183 FTransform SpawnTransform = FTransform::Identity;
184 FActorSpawnParameters SpawnParams;
185
186 AInstancedActorRenderer* NewRenderer = GetWorld()->SpawnActor<AInstancedActorRenderer>(
187 AInstancedActorRenderer::StaticClass(),
188 SpawnTransform,
189 SpawnParams
190 );
191
192 if (!NewRenderer)
193 {
194 return false;
195 }
196
197 InstancedRenderers.AddUnique(NewRenderer);
198
199 UInstancedStaticMeshComponent* Comp = NewRenderer->GetInstancedStaticMeshComponent();
200
201 if (Comp)
202 {
203 Comp->SetStaticMesh(ISM->GetStaticMesh());
204 const int32 NumberOfMaterials = ISM->GetNumMaterials();
205 for (int32 i = 0; i < NumberOfMaterials; i++)
206 {
207 Comp->SetMaterial(i, ISM->GetMaterial(i));
208 }
209
210 TArray<FTransform> InstanceTransforms;
211 for (int32 i = 0; i < ISM->GetInstanceCount(); i++)
212 {
213 FTransform InstanceTransform;
214 if (ISM->GetInstanceTransform(i, InstanceTransform, true))
215 {
216 InstanceTransforms.Add(InstanceTransform);
217 }
218 }
219
220 for (const FTransform& Transform : InstanceTransforms)
221 {
222 Comp->AddInstance(Transform);
223 }
224 }
225
226 return true;
227 }
228
229 return true;
230}
UInstancedStaticMeshComponent * GetInstancedStaticMeshComponent() const
bool AppendISM(UInstancedStaticMeshComponent *ISM)

References AppendISM(), AInstancedActorRenderer::GetInstancedStaticMeshComponent(), InstancedRenderers, and Transform.

◆ BeginPlay()

void AInstancedRendererManager::BeginPlay ( )
overridevirtual

Definition at line 21 of file InstancedRendererManager.cpp.

22{
23 Super::BeginPlay();
24
25 if (!Instance)
26 {
27 Instance = this;
28 }
29 else
30 {
31#if WITH_EDITOR
32 UE_LOG(LogTemp, Warning, TEXT("InstancedRenderer.cpp: Instance already exists. Destroying this actor.."));
33#endif
34 Destroy();
35 }
36
37#ifdef InstanceSegmentationPass_EXISTS
38 // if using our fork of Unreal Engine, user can use instance segmentation sensor,
39 // but only in Vindeln_Dev or RovaniemiForest_Dev maps where
40 // there are no ISM instances (expect for landscape vegetation)
41 FString MapName = GetWorld()->GetMapName().ToLower();
42
43 if (MapName.Contains(TEXT("vindeln")) && !MapName.Contains(TEXT("dev")))
44 {
45 AllowISMCreation = true;
46 }
47
48 if (MapName.Contains(TEXT("rovaniemiforest")) && !MapName.Contains(TEXT("dev")))
49 {
50 AllowISMCreation = true;
51 }
52#endif
53}
static AInstancedRendererManager * Instance

References AllowISMCreation, Destroy, and Instance.

◆ DestroyOverlappingInstancesBox()

void AInstancedRendererManager::DestroyOverlappingInstancesBox ( UInstancedStaticMeshComponent *  ISM,
FBox  AreaBox,
bool  OnlyTrees 
)

Destroys all instances overlapping the specified Box area.

Parameters
ISM- The instanced static mesh component.
AreaBox- The bounding box defining the area to check.
OnlyTrees- Whether to limit destruction to tree instances only.

Definition at line 302 of file InstancedRendererManager.cpp.

303{
304 if (!ISM)
305 {
306 return;
307 }
308
310 {
311 if (!Renderer)
312 {
313 continue;
314 }
315
316 FInstancedActorParameters params = Renderer->GetInstancedActorParameters();
317 if (!params.IsTree && OnlyTrees)
318 {
319 continue;
320 }
321
322 UInstancedStaticMeshComponent* Comp = Renderer->GetInstancedStaticMeshComponent();
323 if (Comp && Comp == ISM)
324 {
325 TArray<int32> OverlappingInstances = Comp->GetInstancesOverlappingBox(AreaBox);
326
327 // Sort indices in descending order to avoid shifting issues
328 OverlappingInstances.Sort([](int32 A, int32 B)
329 {
330 return B < A;
331 });
332
333 for (int32 InstanceIndex : OverlappingInstances)
334 {
335 Comp->RemoveInstance(InstanceIndex);
336 }
337 }
338 }
339}

References InstancedRenderers, and FInstancedActorParameters::IsTree.

Referenced by ADeletionVolume::DestroyOverlappingActors().

◆ EndPlay()

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

Definition at line 55 of file InstancedRendererManager.cpp.

56{
57 Super::EndPlay(EndPlayReason);
58
59 if (Instance == this)
60 {
61 Instance = nullptr;
62 }
63}

References Instance.

◆ ExportTreesAsCSV()

void AInstancedRendererManager::ExportTreesAsCSV ( )

Definition at line 356 of file InstancedRendererManager.cpp.

357{
358 AGeoReferencingSystem* GeoReferencingSystem = AGeoReferencingSystem::GetGeoReferencingSystem(GetWorld());
359 TArray<TArray<FString>> Rows;
360
362 {
363 if (Renderer && Renderer->GetInstancedActorParameters().IsTree)
364 {
365 UInstancedStaticMeshComponent* ISM = Renderer->GetInstancedStaticMeshComponent();
366 if (!ISM) continue;
367
368 const int32 InstanceCount = ISM->GetInstanceCount();
369 const FString MeshName = Renderer->GetStaticMesh() ? Renderer->GetStaticMesh()->GetName() : TEXT("Unknown");
370
371 for (int32 i = 0; i < InstanceCount; ++i)
372 {
373 FTransform Transform;
374 if (!ISM->GetInstanceTransform(i, Transform, true)) continue;
375
376 const FVector Location = Transform.GetLocation();
377 const FRotator Rotation = Transform.Rotator();
378
379 FString LatitudeStr = TEXT(""), LongitudeStr = TEXT(""), AltitudeStr = TEXT("");
380
381 if (GeoReferencingSystem)
382 {
383 const FGeographicCoordinates GeographicCoordinates = UCoordinateConversionUtilities::UnrealToGeographicCoordinates(GeoReferencingSystem, Location);
384 LatitudeStr = FString::Printf(TEXT("%.8f"), GeographicCoordinates.Latitude);
385 LongitudeStr = FString::Printf(TEXT("%.8f"), GeographicCoordinates.Longitude);
386 AltitudeStr = FString::Printf(TEXT("%.8f"), GeographicCoordinates.Altitude);
387 }
388
389 TArray<FString> Row;
390 Row.Add(MeshName);
391 Row.Add(FString::Printf(TEXT("%.2f"), Location.X));
392 Row.Add(FString::Printf(TEXT("%.2f"), Location.Y));
393 Row.Add(FString::Printf(TEXT("%.2f"), Location.Z));
394
395 if (GeoReferencingSystem)
396 {
397 Row.Add(LatitudeStr);
398 Row.Add(LongitudeStr);
399 Row.Add(AltitudeStr);
400 }
401
402 Rows.Add(Row);
403 }
404 }
405 }
406
407 if (Rows.IsEmpty())
408 {
409 return;
410 }
411
412 // CSV file settings
413 FCSVFileSettings Settings;
415 Settings.Append = false;
416 Settings.CreateUnique = true;
418
419 // Filename
420 FString MapName = GetWorld()->GetMapName();
421 FString FileName = MapName + TEXT("_TreeLocations");
422
423 // Create CSV file
424 UCSVFile* CSV = UCSVFile::CreateCSVFile(FileName, Settings);
425
426 // Create CSV Header row
427 TArray<FString> Header = { TEXT("name"), TEXT("x"), TEXT("y"), TEXT("z") };
428 if (GeoReferencingSystem)
429 {
430 Header.Append({ TEXT("latitude"), TEXT("longitude"), TEXT("altitude") });
431 }
432 CSV->WriteRow(Header);
433
434 // Write data rows
435 for (const TArray<FString>& Row : Rows)
436 {
437 CSV->WriteRow(Row);
438 }
439
440 // Finish writing and close the file
441 CSV->Destroy();
442}
static UCSVFile * CreateCSVFile(const FString &FileNameWithoutExtension, const FCSVFileSettings &Settings)
Definition: CSVFile.cpp:14
void WriteRow(const TArray< FString > &Cells)
Definition: CSVFile.cpp:77
void Destroy()
Definition: CSVFile.cpp:133
static FGeographicCoordinates UnrealToGeographicCoordinates(AGeoReferencingSystem *GeoReferencingSystem, const FVector &Position)
bool CreateUnique
Definition: CSVFile.h:42
ECSVDelimiter Delimiter
Definition: CSVFile.h:36
FCSVFileWriteOptions FileWriteOption
Definition: CSVFile.h:45

References FCSVFileSettings::Append, UCSVFile::CreateCSVFile(), FCSVFileSettings::CreateUnique, FCSVFileSettings::Delimiter, UCSVFile::Destroy(), FCSVFileSettings::FileWriteOption, InstancedRenderers, Queue, Semicolon, Transform, UCoordinateConversionUtilities::UnrealToGeographicCoordinates(), and UCSVFile::WriteRow().

◆ GetAllInstancedActorRendererActors()

TArray< AInstancedActorRenderer * > AInstancedRendererManager::GetAllInstancedActorRendererActors ( ) const

Definition at line 245 of file InstancedRendererManager.cpp.

246{
247 UWorld* World = GetWorld();
248 if (World && !World->IsGameWorld())
249 {
250 TArray<AActor*> FoundActors;
251 UGameplayStatics::GetAllActorsOfClass(World, AInstancedActorRenderer::StaticClass(), FoundActors);
252
253 TArray<AInstancedActorRenderer*> RendererActors;
254 for (AActor* Actor : FoundActors)
255 {
256 if (AInstancedActorRenderer* Renderer = Cast<AInstancedActorRenderer>(Actor))
257 {
258 RendererActors.AddUnique(Renderer);
259 }
260 }
261 return RendererActors;
262 }
263
264 // If running at runtime (including PIE), return InstancedRenderers
265 return InstancedRenderers;
266}

References InstancedRenderers.

◆ GetTotalInstanceCount()

int32 AInstancedRendererManager::GetTotalInstanceCount ( )

Definition at line 268 of file InstancedRendererManager.cpp.

269{
270 int32 total = 0;
272 {
273 if (Renderer)
274 {
275 UInstancedStaticMeshComponent* Comp = Renderer->GetInstancedStaticMeshComponent();
276 if (Comp)
277 {
278 total += Comp->GetInstanceCount();
279 }
280 }
281 }
282
283 TotalInstanceCount = total;
284
285 return TotalInstanceCount;
286}

References InstancedRenderers, and TotalInstanceCount.

◆ SetInstancedRendering()

void AInstancedRendererManager::SetInstancedRendering ( bool  Visible)

Set all ISM components visibility.

Definition at line 341 of file InstancedRendererManager.cpp.

342{
344 {
345 if (Renderer)
346 {
347 UInstancedStaticMeshComponent* Comp = Renderer->GetInstancedStaticMeshComponent();
348 if (Comp)
349 {
350 Comp->SetVisibility(Visible);
351 }
352 }
353 }
354}

References InstancedRenderers.

Referenced by UAgrarsenseSettings::SetInstancedRenderingVisibility().

◆ SpawnAllInstancesBackToActors()

void AInstancedRendererManager::SpawnAllInstancesBackToActors ( )

Spawn all instanced back to actors.

Definition at line 232 of file InstancedRendererManager.cpp.

233{
234 for (int32 i = InstancedRenderers.Num() - 1; i >= 0; --i)
235 {
237 if (Renderer && Renderer->SpawnInstancesBackActors())
238 {
239 Renderer->Destroy();
240 InstancedRenderers.RemoveAt(i);
241 }
242 }
243}

References InstancedRenderers, and AInstancedActorRenderer::SpawnInstancesBackActors().

◆ SpawnInstanceBackToActor()

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

Spawns a specific ISM instance back to its original Actor. Cannot be added back to ISM instance afterwards.

Parameters
ISMThe instanced static mesh component containing the instance.
IndexThe index of the instance to spawn back.
Returns
True if the instance was successfully spawned, false otherwise.

Definition at line 288 of file InstancedRendererManager.cpp.

289{
291 {
292 if (Renderer && Renderer->SpawnInstanceBackToActor(ISM, Index, OnlyTree))
293 {
294 return true;
295 }
296 }
297
298 // Didn't find instance or spawning instance back to actor failed.
299 return false;
300}

References InstancedRenderers.

Member Data Documentation

◆ AllowISMCreation

bool AInstancedRendererManager::AllowISMCreation = false
private

Definition at line 101 of file InstancedRendererManager.h.

Referenced by AddActorToInstancedRendering(), and BeginPlay().

◆ Instance

AInstancedRendererManager * AInstancedRendererManager::Instance = nullptr
staticprivate

Definition at line 99 of file InstancedRendererManager.h.

Referenced by BeginPlay(), and EndPlay().

◆ InstancedRenderers

TArray<AInstancedActorRenderer*> AInstancedRendererManager::InstancedRenderers
protected

◆ TotalInstanceCount

int32 AInstancedRendererManager::TotalInstanceCount = 0
protected

Definition at line 95 of file InstancedRendererManager.h.

Referenced by GetTotalInstanceCount().


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