Agrarsense
Public Member Functions | Protected 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
 

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 15 of file InstancedRendererManager.cpp.

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

Member Function Documentation

◆ AddActorToInstancedRendering()

bool AInstancedRendererManager::AddActorToInstancedRendering ( AInstancedActor InstancedActor)

Adds an AInstancedActor to the appropriate instanced renderer.

Definition at line 47 of file InstancedRendererManager.cpp.

48{
49 if (!InstancedActor)
50 {
51#if WITH_EDITOR
52 UE_LOG(LogTemp, Warning, TEXT("InstancedRenderer.cpp: Actor is null!"));
53#endif
54 return false;
55 }
56
57 if (InstancedActor->UpdateTransformAutomatically())
58 {
59#if WITH_EDITOR
60 UE_LOG(LogTemp, Warning, TEXT("InstancedRenderer.cpp: AInstancedActor %s is set to update transform automatically."), *InstancedActor->GetName());
61#endif
62 return false;
63 }
64
65 UStaticMeshComponent* StaticMeshComponent = InstancedActor->GetStaticMeshComponent();
66 if (!StaticMeshComponent)
67 {
68#if WITH_EDITOR
69 UE_LOG(LogTemp, Warning, TEXT("InstancedRenderer.cpp: AInstancedActor %s UStaticMeshComponent is null!"), *InstancedActor->GetName());
70#endif
71 return false;
72 }
73
74 UStaticMesh* Mesh = StaticMeshComponent->GetStaticMesh();
75 if (!Mesh)
76 {
77#if WITH_EDITOR
78 UE_LOG(LogTemp, Warning, TEXT("InstancedRenderer.cpp: AInstancedActor %s UStaticMeshComponent mesh is null!"), *InstancedActor->GetName());
79#endif
80 return false;
81 }
82
83 // Loop throigh InstancedRenderers and check if we already have this type of instance in the world.
85 {
86 if (Renderer && Renderer->Matches(StaticMeshComponent, InstancedActor->AlternativeMaterial))
87 {
88 UInstancedStaticMeshComponent* Comp = Renderer->GetInstancedStaticMeshComponent();
89 if (Comp)
90 {
91 Comp->AddInstance(InstancedActor->GetActorTransform());
92 InstancedActor->InstanceAdded();
93 InstancedActor->Destroy();
94 return true;
95 }
96 }
97 }
98
99 // Else this is new instance, create new AInstancedActorRenderer Actor.
100 FTransform SpawnTransform = FTransform::Identity;
101 FActorSpawnParameters SpawnParams;
102
103 AInstancedActorRenderer* NewRenderer = GetWorld()->SpawnActor<AInstancedActorRenderer>(
104 AInstancedActorRenderer::StaticClass(),
105 SpawnTransform,
106 SpawnParams
107 );
108
109 InstancedRenderers.AddUnique(NewRenderer);
110 NewRenderer->SetupFromInstancedActor(InstancedActor);
111
112 return true;
113}
void SetupFromInstancedActor(AInstancedActor *InstancedActor)
bool UpdateTransformAutomatically() const
UStaticMeshComponent * GetStaticMeshComponent() const
TArray< AInstancedActorRenderer * > InstancedRenderers

References 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 115 of file InstancedRendererManager.cpp.

116{
117 if (!ISM)
118 {
119 return false;
120 }
121
123 {
124 if (!Renderer || !Renderer->Matches(ISM))
125 {
126 continue;
127 }
128
129 UInstancedStaticMeshComponent* Comp = Renderer->GetInstancedStaticMeshComponent();
130 if (!Comp)
131 {
132 continue;
133 }
134
135 const int32 InstanceCount = ISM->GetInstanceCount();
136 for (int32 i = 0; i < InstanceCount; ++i)
137 {
138 FTransform InstanceTransform;
139 if (ISM->GetInstanceTransform(i, InstanceTransform, true))
140 {
141 Comp->AddInstance(InstanceTransform);
142 }
143 }
144
145 return true;
146 }
147
148 return false;
149}

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 151 of file InstancedRendererManager.cpp.

152{
153 if (!ISM)
154 {
155 return false;
156 }
157
158 if (!AppendISM(ISM))
159 {
160 FTransform SpawnTransform = FTransform::Identity;
161 FActorSpawnParameters SpawnParams;
162
163 AInstancedActorRenderer* NewRenderer = GetWorld()->SpawnActor<AInstancedActorRenderer>(
164 AInstancedActorRenderer::StaticClass(),
165 SpawnTransform,
166 SpawnParams
167 );
168
169 if (!NewRenderer)
170 {
171 return false;
172 }
173
174 InstancedRenderers.AddUnique(NewRenderer);
175
176 UInstancedStaticMeshComponent* Comp = NewRenderer->GetInstancedStaticMeshComponent();
177
178 if (Comp)
179 {
180 Comp->SetStaticMesh(ISM->GetStaticMesh());
181 const int32 NumberOfMaterials = ISM->GetNumMaterials();
182 for (int32 i = 0; i < NumberOfMaterials; i++)
183 {
184 Comp->SetMaterial(i, ISM->GetMaterial(i));
185 }
186
187 TArray<FTransform> InstanceTransforms;
188 for (int32 i = 0; i < ISM->GetInstanceCount(); i++)
189 {
190 FTransform InstanceTransform;
191 if (ISM->GetInstanceTransform(i, InstanceTransform, true))
192 {
193 InstanceTransforms.Add(InstanceTransform);
194 }
195 }
196
197 for (const FTransform& Transform : InstanceTransforms)
198 {
199 Comp->AddInstance(Transform);
200 }
201 }
202
203 return true;
204 }
205
206 return true;
207}
UInstancedStaticMeshComponent * GetInstancedStaticMeshComponent() const
bool AppendISM(UInstancedStaticMeshComponent *ISM)

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

◆ BeginPlay()

void AInstancedRendererManager::BeginPlay ( )
overridevirtual

Definition at line 20 of file InstancedRendererManager.cpp.

21{
22 Super::BeginPlay();
23
24 if (!Instance)
25 {
26 Instance = this;
27 }
28 else
29 {
30#if WITH_EDITOR
31 UE_LOG(LogTemp, Warning, TEXT("InstancedRenderer.cpp: Instance already exists. Destroying this actor.."));
32#endif
33 Destroy();
34 }
35}
static AInstancedRendererManager * Instance

References 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 279 of file InstancedRendererManager.cpp.

280{
281 if (!ISM)
282 {
283 return;
284 }
285
287 {
288 if (!Renderer)
289 {
290 continue;
291 }
292
293 FInstancedActorParameters params = Renderer->GetInstancedActorParameters();
294 if (!params.IsTree && OnlyTrees)
295 {
296 continue;
297 }
298
299 UInstancedStaticMeshComponent* Comp = Renderer->GetInstancedStaticMeshComponent();
300 if (Comp && Comp == ISM)
301 {
302 TArray<int32> OverlappingInstances = Comp->GetInstancesOverlappingBox(AreaBox);
303
304 // Sort indices in descending order to avoid shifting issues
305 OverlappingInstances.Sort([](int32 A, int32 B)
306 {
307 return B < A;
308 });
309
310 for (int32 InstanceIndex : OverlappingInstances)
311 {
312 Comp->RemoveInstance(InstanceIndex);
313 }
314 }
315 }
316}

References InstancedRenderers, and FInstancedActorParameters::IsTree.

Referenced by ADeletionVolume::DestroyOverlappingActors().

◆ EndPlay()

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

Definition at line 37 of file InstancedRendererManager.cpp.

38{
39 Super::EndPlay(EndPlayReason);
40
41 if (Instance == this)
42 {
43 Instance = nullptr;
44 }
45}

References Instance.

◆ ExportTreesAsCSV()

void AInstancedRendererManager::ExportTreesAsCSV ( )

Definition at line 333 of file InstancedRendererManager.cpp.

334{
335 AGeoReferencingSystem* GeoReferencingSystem = AGeoReferencingSystem::GetGeoReferencingSystem(GetWorld());
336 TArray<TArray<FString>> Rows;
337
339 {
340 if (Renderer && Renderer->GetInstancedActorParameters().IsTree)
341 {
342 UInstancedStaticMeshComponent* ISM = Renderer->GetInstancedStaticMeshComponent();
343 if (!ISM) continue;
344
345 const int32 InstanceCount = ISM->GetInstanceCount();
346 const FString MeshName = Renderer->GetStaticMesh() ? Renderer->GetStaticMesh()->GetName() : TEXT("Unknown");
347
348 for (int32 i = 0; i < InstanceCount; ++i)
349 {
350 FTransform Transform;
351 if (!ISM->GetInstanceTransform(i, Transform, true)) continue;
352
353 const FVector Location = Transform.GetLocation();
354 const FRotator Rotation = Transform.Rotator();
355
356 FString LatitudeStr = TEXT(""), LongitudeStr = TEXT(""), AltitudeStr = TEXT("");
357
358 if (GeoReferencingSystem)
359 {
360 const FGeographicCoordinates GeographicCoordinates = UCoordinateConversionUtilities::UnrealToGeographicCoordinates(GeoReferencingSystem, Location);
361 LatitudeStr = FString::Printf(TEXT("%.8f"), GeographicCoordinates.Latitude);
362 LongitudeStr = FString::Printf(TEXT("%.8f"), GeographicCoordinates.Longitude);
363 AltitudeStr = FString::Printf(TEXT("%.8f"), GeographicCoordinates.Altitude);
364 }
365
366 TArray<FString> Row;
367 Row.Add(MeshName);
368 Row.Add(FString::Printf(TEXT("%.2f"), Location.X));
369 Row.Add(FString::Printf(TEXT("%.2f"), Location.Y));
370 Row.Add(FString::Printf(TEXT("%.2f"), Location.Z));
371
372 if (GeoReferencingSystem)
373 {
374 Row.Add(LatitudeStr);
375 Row.Add(LongitudeStr);
376 Row.Add(AltitudeStr);
377 }
378
379 Rows.Add(Row);
380 }
381 }
382 }
383
384 if (Rows.IsEmpty())
385 {
386 return;
387 }
388
389 // CSV file settings
390 FCSVFileSettings Settings;
392 Settings.Append = false;
393 Settings.CreateUnique = true;
395
396 // Filename
397 FString MapName = GetWorld()->GetMapName();
398 FString FileName = MapName + TEXT("_TreeLocations");
399
400 // Create CSV file
401 UCSVFile* CSV = UCSVFile::CreateCSVFile(FileName, Settings);
402
403 // Create CSV Header row
404 TArray<FString> Header = { TEXT("name"), TEXT("x"), TEXT("y"), TEXT("z") };
405 if (GeoReferencingSystem)
406 {
407 Header.Append({ TEXT("latitude"), TEXT("longitude"), TEXT("altitude") });
408 }
409 CSV->WriteRow(Header);
410
411 // Write data rows
412 for (const TArray<FString>& Row : Rows)
413 {
414 CSV->WriteRow(Row);
415 }
416
417 // Finish writing and close the file
418 CSV->Destroy();
419}
static UCSVFile * CreateCSVFile(const FString &FileNameWithoutExtension, const FCSVFileSettings &Settings)
Definition: CSVFile.cpp:14
void WriteRow(const TArray< FString > &Cells)
Definition: CSVFile.cpp:69
void Destroy()
Definition: CSVFile.cpp:125
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 222 of file InstancedRendererManager.cpp.

223{
224 UWorld* World = GetWorld();
225 if (World && !World->IsGameWorld())
226 {
227 TArray<AActor*> FoundActors;
228 UGameplayStatics::GetAllActorsOfClass(World, AInstancedActorRenderer::StaticClass(), FoundActors);
229
230 TArray<AInstancedActorRenderer*> RendererActors;
231 for (AActor* Actor : FoundActors)
232 {
233 if (AInstancedActorRenderer* Renderer = Cast<AInstancedActorRenderer>(Actor))
234 {
235 RendererActors.AddUnique(Renderer);
236 }
237 }
238 return RendererActors;
239 }
240
241 // If running at runtime (including PIE), return InstancedRenderers
242 return InstancedRenderers;
243}

References InstancedRenderers.

◆ GetTotalInstanceCount()

int32 AInstancedRendererManager::GetTotalInstanceCount ( )

Definition at line 245 of file InstancedRendererManager.cpp.

246{
247 int32 total = 0;
249 {
250 if (Renderer)
251 {
252 UInstancedStaticMeshComponent* Comp = Renderer->GetInstancedStaticMeshComponent();
253 if (Comp)
254 {
255 total += Comp->GetInstanceCount();
256 }
257 }
258 }
259
260 TotalInstanceCount = total;
261
262 return TotalInstanceCount;
263}

References InstancedRenderers, and TotalInstanceCount.

◆ SetInstancedRendering()

void AInstancedRendererManager::SetInstancedRendering ( bool  Visible)

Set all ISM components visibility.

Definition at line 318 of file InstancedRendererManager.cpp.

319{
321 {
322 if (Renderer)
323 {
324 UInstancedStaticMeshComponent* Comp = Renderer->GetInstancedStaticMeshComponent();
325 if (Comp)
326 {
327 Comp->SetVisibility(Visible);
328 }
329 }
330 }
331}

References InstancedRenderers.

Referenced by UAgrarsenseSettings::SetInstancedRenderingVisibility().

◆ SpawnAllInstancesBackToActors()

void AInstancedRendererManager::SpawnAllInstancesBackToActors ( )

Spawn all instanced back to actors.

Definition at line 209 of file InstancedRendererManager.cpp.

210{
211 for (int32 i = InstancedRenderers.Num() - 1; i >= 0; --i)
212 {
214 if (Renderer && Renderer->SpawnInstancesBackActors())
215 {
216 Renderer->Destroy();
217 InstancedRenderers.RemoveAt(i);
218 }
219 }
220}

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 265 of file InstancedRendererManager.cpp.

266{
268 {
269 if (Renderer && Renderer->SpawnInstanceBackToActor(ISM, Index, OnlyTree))
270 {
271 return true;
272 }
273 }
274
275 // Didn't find instance or spawning instance back to actor failed.
276 return false;
277}

References InstancedRenderers.

Member Data Documentation

◆ 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: