10#include "Engine/World.h"
11#include "GeoReferencingSystem.h"
12#include "Kismet/GameplayStatics.h"
18 PrimaryActorTick.bCanEverTick =
false;
32 UE_LOG(LogTemp, Warning, TEXT(
"InstancedRenderer.cpp: Instance already exists. Destroying this actor.."));
37#ifdef InstanceSegmentationPass_EXISTS
41 FString MapName = GetWorld()->GetMapName().ToLower();
43 if (MapName.Contains(TEXT(
"vindeln")) && !MapName.Contains(TEXT(
"dev")))
48 if (MapName.Contains(TEXT(
"rovaniemiforest")) && !MapName.Contains(TEXT(
"dev")))
57 Super::EndPlay(EndPlayReason);
75 UE_LOG(LogTemp, Warning, TEXT(
"InstancedRenderer.cpp: Actor is null!"));
83 UE_LOG(LogTemp, Warning, TEXT(
"InstancedRenderer.cpp: AInstancedActor %s is set to update transform automatically."), *InstancedActor->GetName());
89 if (!StaticMeshComponent)
92 UE_LOG(LogTemp, Warning, TEXT(
"InstancedRenderer.cpp: AInstancedActor %s UStaticMeshComponent is null!"), *InstancedActor->GetName());
97 UStaticMesh* Mesh = StaticMeshComponent->GetStaticMesh();
101 UE_LOG(LogTemp, Warning, TEXT(
"InstancedRenderer.cpp: AInstancedActor %s UStaticMeshComponent mesh is null!"), *InstancedActor->GetName());
109 if (Renderer && Renderer->Matches(StaticMeshComponent, InstancedActor->
AlternativeMaterial))
111 UInstancedStaticMeshComponent* Comp = Renderer->GetInstancedStaticMeshComponent();
114 Comp->AddInstance(InstancedActor->GetActorTransform());
116 InstancedActor->Destroy();
123 FTransform SpawnTransform = FTransform::Identity;
124 FActorSpawnParameters SpawnParams;
127 AInstancedActorRenderer::StaticClass(),
147 if (!Renderer || !Renderer->Matches(ISM))
152 UInstancedStaticMeshComponent* Comp = Renderer->GetInstancedStaticMeshComponent();
158 const int32 InstanceCount = ISM->GetInstanceCount();
159 for (int32 i = 0; i < InstanceCount; ++i)
161 FTransform InstanceTransform;
162 if (ISM->GetInstanceTransform(i, InstanceTransform,
true))
164 Comp->AddInstance(InstanceTransform);
183 FTransform SpawnTransform = FTransform::Identity;
184 FActorSpawnParameters SpawnParams;
187 AInstancedActorRenderer::StaticClass(),
203 Comp->SetStaticMesh(ISM->GetStaticMesh());
204 const int32 NumberOfMaterials = ISM->GetNumMaterials();
205 for (int32 i = 0; i < NumberOfMaterials; i++)
207 Comp->SetMaterial(i, ISM->GetMaterial(i));
210 TArray<FTransform> InstanceTransforms;
211 for (int32 i = 0; i < ISM->GetInstanceCount(); i++)
213 FTransform InstanceTransform;
214 if (ISM->GetInstanceTransform(i, InstanceTransform,
true))
216 InstanceTransforms.Add(InstanceTransform);
220 for (
const FTransform&
Transform : InstanceTransforms)
247 UWorld* World = GetWorld();
248 if (World && !World->IsGameWorld())
250 TArray<AActor*> FoundActors;
251 UGameplayStatics::GetAllActorsOfClass(World, AInstancedActorRenderer::StaticClass(), FoundActors);
253 TArray<AInstancedActorRenderer*> RendererActors;
254 for (AActor* Actor : FoundActors)
258 RendererActors.AddUnique(Renderer);
261 return RendererActors;
275 UInstancedStaticMeshComponent* Comp = Renderer->GetInstancedStaticMeshComponent();
278 total += Comp->GetInstanceCount();
292 if (Renderer && Renderer->SpawnInstanceBackToActor(ISM, Index, OnlyTree))
317 if (!params.
IsTree && OnlyTrees)
322 UInstancedStaticMeshComponent* Comp = Renderer->GetInstancedStaticMeshComponent();
323 if (Comp && Comp == ISM)
325 TArray<int32> OverlappingInstances = Comp->GetInstancesOverlappingBox(AreaBox);
328 OverlappingInstances.Sort([](int32 A, int32 B)
333 for (int32 InstanceIndex : OverlappingInstances)
335 Comp->RemoveInstance(InstanceIndex);
347 UInstancedStaticMeshComponent* Comp = Renderer->GetInstancedStaticMeshComponent();
350 Comp->SetVisibility(Visible);
358 AGeoReferencingSystem* GeoReferencingSystem = AGeoReferencingSystem::GetGeoReferencingSystem(GetWorld());
359 TArray<TArray<FString>> Rows;
363 if (Renderer && Renderer->GetInstancedActorParameters().IsTree)
365 UInstancedStaticMeshComponent* ISM = Renderer->GetInstancedStaticMeshComponent();
368 const int32 InstanceCount = ISM->GetInstanceCount();
369 const FString MeshName = Renderer->GetStaticMesh() ? Renderer->GetStaticMesh()->GetName() : TEXT(
"Unknown");
371 for (int32 i = 0; i < InstanceCount; ++i)
374 if (!ISM->GetInstanceTransform(i,
Transform,
true))
continue;
376 const FVector Location =
Transform.GetLocation();
377 const FRotator Rotation =
Transform.Rotator();
379 FString LatitudeStr = TEXT(
""), LongitudeStr = TEXT(
""), AltitudeStr = TEXT(
"");
381 if (GeoReferencingSystem)
384 LatitudeStr = FString::Printf(TEXT(
"%.8f"), GeographicCoordinates.Latitude);
385 LongitudeStr = FString::Printf(TEXT(
"%.8f"), GeographicCoordinates.Longitude);
386 AltitudeStr = FString::Printf(TEXT(
"%.8f"), GeographicCoordinates.Altitude);
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));
395 if (GeoReferencingSystem)
397 Row.Add(LatitudeStr);
398 Row.Add(LongitudeStr);
399 Row.Add(AltitudeStr);
420 FString MapName = GetWorld()->GetMapName();
421 FString FileName = MapName + TEXT(
"_TreeLocations");
427 TArray<FString> Header = { TEXT(
"name"), TEXT(
"x"), TEXT(
"y"), TEXT(
"z") };
428 if (GeoReferencingSystem)
430 Header.Append({ TEXT(
"latitude"), TEXT(
"longitude"), TEXT(
"altitude") });
435 for (
const TArray<FString>& Row : Rows)
void SetupFromInstancedActor(AInstancedActor *InstancedActor)
bool SpawnInstancesBackActors()
UInstancedStaticMeshComponent * GetInstancedStaticMeshComponent() const
bool UpdateTransformAutomatically() const
UStaticMeshComponent * GetStaticMeshComponent() const
TArray< AInstancedActorRenderer * > InstancedRenderers
int32 GetTotalInstanceCount()
bool SpawnInstanceBackToActor(UInstancedStaticMeshComponent *ISM, int32 Index, bool OnlyTree)
void SetInstancedRendering(bool Visible)
bool AppendOrCreateISM(UInstancedStaticMeshComponent *ISM)
bool AppendISM(UInstancedStaticMeshComponent *ISM)
TArray< AInstancedActorRenderer * > GetAllInstancedActorRendererActors() const
void DestroyOverlappingInstancesBox(UInstancedStaticMeshComponent *ISM, FBox AreaBox, bool OnlyTrees)
static AInstancedRendererManager * Instance
bool AddActorToInstancedRendering(AInstancedActor *InstancedActor)
virtual void BeginPlay() override
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override
void SpawnAllInstancesBackToActors()
AInstancedRendererManager(const FObjectInitializer &ObjectInitializer)
static UCSVFile * CreateCSVFile(const FString &FileNameWithoutExtension, const FCSVFileSettings &Settings)
void WriteRow(const TArray< FString > &Cells)
static FGeographicCoordinates UnrealToGeographicCoordinates(AGeoReferencingSystem *GeoReferencingSystem, const FVector &Position)
FCSVFileWriteOptions FileWriteOption