10#include "GeoReferencingSystem.h"
11#include "Kismet/GameplayStatics.h"
17 PrimaryActorTick.bCanEverTick =
false;
31 UE_LOG(LogTemp, Warning, TEXT(
"InstancedRenderer.cpp: Instance already exists. Destroying this actor.."));
39 Super::EndPlay(EndPlayReason);
52 UE_LOG(LogTemp, Warning, TEXT(
"InstancedRenderer.cpp: Actor is null!"));
60 UE_LOG(LogTemp, Warning, TEXT(
"InstancedRenderer.cpp: AInstancedActor %s is set to update transform automatically."), *InstancedActor->GetName());
66 if (!StaticMeshComponent)
69 UE_LOG(LogTemp, Warning, TEXT(
"InstancedRenderer.cpp: AInstancedActor %s UStaticMeshComponent is null!"), *InstancedActor->GetName());
74 UStaticMesh* Mesh = StaticMeshComponent->GetStaticMesh();
78 UE_LOG(LogTemp, Warning, TEXT(
"InstancedRenderer.cpp: AInstancedActor %s UStaticMeshComponent mesh is null!"), *InstancedActor->GetName());
86 if (Renderer && Renderer->Matches(StaticMeshComponent, InstancedActor->
AlternativeMaterial))
88 UInstancedStaticMeshComponent* Comp = Renderer->GetInstancedStaticMeshComponent();
91 Comp->AddInstance(InstancedActor->GetActorTransform());
93 InstancedActor->Destroy();
100 FTransform SpawnTransform = FTransform::Identity;
101 FActorSpawnParameters SpawnParams;
104 AInstancedActorRenderer::StaticClass(),
124 if (!Renderer || !Renderer->Matches(ISM))
129 UInstancedStaticMeshComponent* Comp = Renderer->GetInstancedStaticMeshComponent();
135 const int32 InstanceCount = ISM->GetInstanceCount();
136 for (int32 i = 0; i < InstanceCount; ++i)
138 FTransform InstanceTransform;
139 if (ISM->GetInstanceTransform(i, InstanceTransform,
true))
141 Comp->AddInstance(InstanceTransform);
160 FTransform SpawnTransform = FTransform::Identity;
161 FActorSpawnParameters SpawnParams;
164 AInstancedActorRenderer::StaticClass(),
180 Comp->SetStaticMesh(ISM->GetStaticMesh());
181 const int32 NumberOfMaterials = ISM->GetNumMaterials();
182 for (int32 i = 0; i < NumberOfMaterials; i++)
184 Comp->SetMaterial(i, ISM->GetMaterial(i));
187 TArray<FTransform> InstanceTransforms;
188 for (int32 i = 0; i < ISM->GetInstanceCount(); i++)
190 FTransform InstanceTransform;
191 if (ISM->GetInstanceTransform(i, InstanceTransform,
true))
193 InstanceTransforms.Add(InstanceTransform);
197 for (
const FTransform&
Transform : InstanceTransforms)
224 UWorld* World = GetWorld();
225 if (World && !World->IsGameWorld())
227 TArray<AActor*> FoundActors;
228 UGameplayStatics::GetAllActorsOfClass(World, AInstancedActorRenderer::StaticClass(), FoundActors);
230 TArray<AInstancedActorRenderer*> RendererActors;
231 for (AActor* Actor : FoundActors)
235 RendererActors.AddUnique(Renderer);
238 return RendererActors;
252 UInstancedStaticMeshComponent* Comp = Renderer->GetInstancedStaticMeshComponent();
255 total += Comp->GetInstanceCount();
269 if (Renderer && Renderer->SpawnInstanceBackToActor(ISM, Index, OnlyTree))
294 if (!params.
IsTree && OnlyTrees)
299 UInstancedStaticMeshComponent* Comp = Renderer->GetInstancedStaticMeshComponent();
300 if (Comp && Comp == ISM)
302 TArray<int32> OverlappingInstances = Comp->GetInstancesOverlappingBox(AreaBox);
305 OverlappingInstances.Sort([](int32 A, int32 B)
310 for (int32 InstanceIndex : OverlappingInstances)
312 Comp->RemoveInstance(InstanceIndex);
324 UInstancedStaticMeshComponent* Comp = Renderer->GetInstancedStaticMeshComponent();
327 Comp->SetVisibility(Visible);
335 AGeoReferencingSystem* GeoReferencingSystem = AGeoReferencingSystem::GetGeoReferencingSystem(GetWorld());
336 TArray<TArray<FString>> Rows;
340 if (Renderer && Renderer->GetInstancedActorParameters().IsTree)
342 UInstancedStaticMeshComponent* ISM = Renderer->GetInstancedStaticMeshComponent();
345 const int32 InstanceCount = ISM->GetInstanceCount();
346 const FString MeshName = Renderer->GetStaticMesh() ? Renderer->GetStaticMesh()->GetName() : TEXT(
"Unknown");
348 for (int32 i = 0; i < InstanceCount; ++i)
351 if (!ISM->GetInstanceTransform(i,
Transform,
true))
continue;
353 const FVector Location =
Transform.GetLocation();
354 const FRotator Rotation =
Transform.Rotator();
356 FString LatitudeStr = TEXT(
""), LongitudeStr = TEXT(
""), AltitudeStr = TEXT(
"");
358 if (GeoReferencingSystem)
361 LatitudeStr = FString::Printf(TEXT(
"%.8f"), GeographicCoordinates.Latitude);
362 LongitudeStr = FString::Printf(TEXT(
"%.8f"), GeographicCoordinates.Longitude);
363 AltitudeStr = FString::Printf(TEXT(
"%.8f"), GeographicCoordinates.Altitude);
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));
372 if (GeoReferencingSystem)
374 Row.Add(LatitudeStr);
375 Row.Add(LongitudeStr);
376 Row.Add(AltitudeStr);
397 FString MapName = GetWorld()->GetMapName();
398 FString FileName = MapName + TEXT(
"_TreeLocations");
404 TArray<FString> Header = { TEXT(
"name"), TEXT(
"x"), TEXT(
"y"), TEXT(
"z") };
405 if (GeoReferencingSystem)
407 Header.Append({ TEXT(
"latitude"), TEXT(
"longitude"), TEXT(
"altitude") });
412 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