20#include "Components/CapsuleComponent.h"
21#include "GameFramework/Character.h"
22#include "Components/BoxComponent.h"
24#include "Rendering/SkeletalMeshRenderData.h"
25#include "Engine/SkeletalMeshSocket.h"
31 const FTransform& Transform)
33 auto Scale = Transform.GetScale3D();
35 InBB.
Rotation = Transform.GetRotation().Rotator();
46 auto Vehicle = Cast<ACarlaWheeledVehicle>(Actor);
49 FVector Origin =
Vehicle->GetVehicleBoundingBoxTransform().GetTranslation();
50 FVector Extent =
Vehicle->GetVehicleBoundingBoxExtent();
51 return {Origin, Extent};
57 auto Capsule =
Character->GetCapsuleComponent();
58 if (Capsule !=
nullptr)
60 const auto Radius = Capsule->GetScaledCapsuleRadius();
61 const auto HalfHeight = Capsule->GetScaledCapsuleHalfHeight();
63 FVector Origin = {0.0f, 0.0f, 0.0f};
64 FVector Extent = {Radius, Radius, HalfHeight};
65 return {Origin, Extent};
69 auto TrafficSign = Cast<ATrafficSignBase>(Actor);
70 if (TrafficSign !=
nullptr)
73 auto TriggerVolumes = TrafficSign->GetTriggerVolumes();
74 if (TriggerVolumes.Num() > 0)
77 FTransform Transform = Actor->GetActorTransform();
78 Box.Origin = Transform.InverseTransformPosition(Box.Origin);
79 Box.Rotation = Transform.InverseTransformRotation(Box.Rotation.Quaternion()).Rotator();
89 Transform.GetTranslation(),
91 Transform.GetRotation().Rotator()
96 UE_LOG(LogCarla, Warning, TEXT(
"Traffic sign missing trigger volume: %s"), *Actor->GetName());
104 FTransform Transform = Actor->GetActorTransform();
105 BB.
Origin = Transform.InverseTransformPosition(BB.
Origin);
106 BB.
Rotation = Transform.InverseTransformRotation(BB.
Rotation.Quaternion()).Rotator();
107 BB.
Rotation = Transform.GetRotation().Rotator();
121 bool FilterByTagEnabled = (TagQueried != crp::CityObjectLabel::Any);
123 UActorComponent *ActorComp =
Vehicle->GetComponentByClass(USkeletalMeshComponent::StaticClass());
124 USkeletalMeshComponent* ParentComp = Cast<USkeletalMeshComponent>(ActorComp);
128 if(FilterByTagEnabled && Tag != TagQueried)
return {};
130 USkeletalMesh* SkeletalMesh = ParentComp->SkeletalMesh;
135 UE_LOG(LogCarla, Error, TEXT(
"%s has no SKM assigned"), *
Vehicle->GetName());
140 TArray<USkeletalMeshComponent*> SkeletalMeshComps;
141 Vehicle->GetComponents<USkeletalMeshComponent>(SkeletalMeshComps);
143 if(SkeletalMeshComps.Num() > 1)
145 FVector VehicleLocation =
Vehicle->GetActorLocation();
146 FRotator VehicleRotation =
Vehicle->GetActorRotation();
147 float MaxHeadLocation = TNumericLimits<float>::Lowest();
148 float MaxKneeLocation = TNumericLimits<float>::Lowest();
149 bool SocketFound =
false;
150 for(USkeletalMeshComponent* Comp : SkeletalMeshComps)
152 if(Comp == ParentComp)
continue;
155 FVector HeadLocation = Comp->GetSocketLocation(
"crl_Head__C") - VehicleLocation;
156 FVector KneeLocation = Comp->GetSocketLocation(
"crl_leg__L") - VehicleLocation;
158 HeadLocation = VehicleRotation.UnrotateVector(HeadLocation);
159 KneeLocation = VehicleRotation.UnrotateVector(KneeLocation);
161 MaxHeadLocation = (HeadLocation.Z > MaxHeadLocation) ? HeadLocation.Z : MaxHeadLocation;
162 MaxKneeLocation = (KneeLocation.Y > MaxKneeLocation) ? KneeLocation.Y : MaxKneeLocation;
172 Min = Min.ComponentMin(Max);
173 Max = Max.ComponentMin(Tmp);
175 MaxHeadLocation += 20.0f;
177 Max.Y = (MaxKneeLocation > Max.Y) ? MaxKneeLocation : Max.Y;
178 Min.Y = (-MaxKneeLocation < Min.Y) ? MaxKneeLocation : Min.Y;
179 Max.Z = (MaxHeadLocation > Max.Z) ? MaxHeadLocation : Max.Z;
181 BB.
Extent = (Max - Min) * 0.5f;
187 auto& CompToWorldTransform = ParentComp->GetComponentTransform();
199 bool FilterByTag = TagQueried == crp::CityObjectLabel::Any ||
200 TagQueried == crp::CityObjectLabel::Pedestrians;
202 UCapsuleComponent* Capsule =
Character->GetCapsuleComponent();
205 if (Capsule && FilterByTag)
207 const float Radius = Capsule->GetScaledCapsuleRadius();
208 const float HalfHeight = Capsule->GetScaledCapsuleHalfHeight();
214 auto CompToWorldTransform = Capsule->GetComponentTransform();
225 TArray<FBoundingBox>& OutBB,
226 TArray<uint8>& OutTag,
231 TArray<FBoundingBox> BBsOfTL;
232 TArray<uint8> TagsOfTL;
236 const float DistanceThreshold = 100.0f * 100.0f;
239 uint8 TLTag =
static_cast<uint8
>(crp::CityObjectLabel::TrafficLight);
242 check(BBsOfTL.Num() == TagsOfTL.Num());
244 bool FilterByTagEnabled = (InTagQueried !=
static_cast<uint8
>(crp::CityObjectLabel::Any));
246 for(
int i = 0; i < BBsOfTL.Num(); i++)
249 uint8 Tag = TagsOfTL[i];
251 if(FilterByTagEnabled && Tag != InTagQueried)
continue;
263 UE_LOG(LogCarla, Error, TEXT(
"GetSkeletalMeshBoundingBox no SkeletalMesh"));
268 FSkeletalMeshRenderData* SkeletalMeshRenderData = SkeletalMesh->GetResourceForRendering();
269 FSkeletalMeshLODRenderData& LODRenderData = SkeletalMeshRenderData->LODRenderData[0];
270 FStaticMeshVertexBuffers& StaticMeshVertexBuffers = LODRenderData.StaticVertexBuffers;
271 FPositionVertexBuffer& FPositionVertexBuffer = StaticMeshVertexBuffers.PositionVertexBuffer;
272 uint32 NumVertices = FPositionVertexBuffer.GetNumVertices();
275 FVector Max(TNumericLimits<float>::Lowest());
276 FVector Min(TNumericLimits<float>::Max());
278 for(uint32 i = 0; i < NumVertices; i++)
280 auto Pos = FPositionVertexBuffer.VertexPosition(i);
281 Max = Max.ComponentMax(Pos);
282 Min = Min.ComponentMin(Pos);
285 auto Extent = (Max - Min) * 0.5f;
286 auto Origin = Min + Extent;
288 return {Origin, Extent};
299 FBox Box = StaticMesh->GetBoundingBox();
300 return {Box.GetCenter(), Box.GetExtent()};
305 UInstancedStaticMeshComponent*
ISMComp,
306 TArray<FBoundingBox>& OutBoundingBox)
310 UE_LOG(LogCarla, Error, TEXT(
"GetISMBoundingBox no ISMComp"));
314 const UStaticMesh *Mesh =
ISMComp->GetStaticMesh();
319 UE_LOG(LogCarla, Error, TEXT(
"%s has no SM assigned to the ISM"), *
ISMComp->GetOwner()->GetName());
323 const TArray<FInstancedStaticMeshInstanceData>& PerInstanceSMData =
ISMComp->PerInstanceSMData;
325 const FTransform ParentTransform =
ISMComp->GetComponentTransform();
327 for(
auto& InstSMIData : PerInstanceSMData)
329 const FTransform Transform = FTransform(InstSMIData.Transform) * ParentTransform;
338 const TArray<UStaticMeshComponent*>& StaticMeshComps,
339 TArray<FBoundingBox>& OutBB,
340 TArray<uint8>& OutTag,
344 bool FilterByTagEnabled = (TagQueried != crp::CityObjectLabel::Any);
346 for(UStaticMeshComponent* Comp : StaticMeshComps)
349 bool isCrosswalk = Comp->GetOwner()->GetName().Contains(
"crosswalk");
352 if( (!Comp->IsVisible() && !isCrosswalk) || Cast<UInstancedStaticMeshComponent>(Comp))
359 if(FilterByTagEnabled && Tag != TagQueried)
continue;
361 UStaticMesh* StaticMesh = Comp->GetStaticMesh();
367 const FTransform& CompToWorldTransform = Comp->GetComponentTransform();
370 OutTag.Emplace(
static_cast<uint8
>(Tag));
376 const TArray<USkeletalMeshComponent*>& SkeletalMeshComps,
377 TArray<FBoundingBox>& OutBB,
378 TArray<uint8>& OutTag,
382 bool FilterByTagEnabled = (TagQueried != crp::CityObjectLabel::Any);
384 for(USkeletalMeshComponent* Comp : SkeletalMeshComps)
389 if(!Comp->IsVisible() || (FilterByTagEnabled && Tag != TagQueried))
continue;
391 USkeletalMesh* SkeletalMesh = Comp->SkeletalMesh;
395 UE_LOG(LogCarla, Error, TEXT(
"%s has no SKM assigned"), *Comp->GetOwner()->GetName());
400 const FTransform& CompToWorldTransform = Comp->GetComponentTransform();
403 OutTag.Emplace(
static_cast<uint8
>(Tag));
409 const TArray<AActor*>& Actors,
412 TArray<FBoundingBox> Result;
413 for(
AActor* Actor : Actors)
415 TArray<FBoundingBox> BBs =
GetBBsOfActor(Actor, InTagQueried);
416 Result.Append(BBs.GetData(), BBs.Num());
426 TArray<FBoundingBox> Result;
429 bool FilterByTagEnabled = (TagQueried != crp::CityObjectLabel::Any);
431 FString ClassName = Actor->GetClass()->GetName();
437 if( ClassName.Contains(
"Procedural_Bulding") )
return Result;
472 TArray<UInstancedStaticMeshComponent *> ISMComps;
473 Actor->GetComponents<UInstancedStaticMeshComponent>(ISMComps);
474 for(UInstancedStaticMeshComponent* Comp: ISMComps)
478 if(FilterByTagEnabled && Tag != TagQueried)
continue;
484 TArray<UStaticMeshComponent*> StaticMeshComps;
486 Actor->GetComponents<UStaticMeshComponent>(StaticMeshComps);
490 TArray<USkeletalMeshComponent*> SkeletalMeshComps;
492 Actor->GetComponents<USkeletalMeshComponent>(SkeletalMeshComps);
500 TArray<FBoundingBox>& OutBB,
501 TArray<uint8>& OutTag,
502 const float DistanceThreshold,
507 TArray<FBoundingBox> BBsOfTL;
508 TArray<uint8> InternalOutTags;
509 TArray<UStaticMeshComponent*> StaticMeshComps;
510 Actor->GetComponents<UStaticMeshComponent>(StaticMeshComps);
513 bool IgnoreDistanceFilter = (DistanceThreshold <= 0.0f);
514 bool IgnoreTag = (TagToCombine == 0);
516 TSet<int> IndicesDiscarded;
517 for(
int i = 0; i < BBsOfTL.Num(); i++)
520 if(IndicesDiscarded.Contains(i))
continue;
522 TArray<FBoundingBox> BBsToCombine;
524 uint8 Tag1 = InternalOutTags[i];
526 for(
int j = i + 1; j < BBsOfTL.Num(); j++)
529 if(IndicesDiscarded.Contains(j))
continue;
532 uint8 Tag2 = InternalOutTags[j];
534 float Distance = FVector::DistSquared(BB1.
Origin, BB2.
Origin);
537 if( ((Distance <= DistanceThreshold) || IgnoreDistanceFilter) &&
538 ((Tag1 == Tag2) || IgnoreTag) )
540 BBsToCombine.Emplace(BB2);
541 IndicesDiscarded.Emplace(j);
544 if(BBsToCombine.Num() > 0)
546 BBsToCombine.Emplace(BB1);
547 IndicesDiscarded.Emplace(i);
550 OutBB.Emplace(MergedBB);
551 OutTag.Emplace(InternalOutTags[i]);
556 for(
int i = 0; i < BBsOfTL.Num(); i++)
559 if(IndicesDiscarded.Contains(i))
continue;
562 OutTag.Emplace(InternalOutTags[i]);
566template <
typename Collection,
typename ExtractAABB>
568 Collection&& collection,
569 ExtractAABB&& extract_aabb)
571 FVector Max(std::numeric_limits<float>::lowest());
572 FVector Min(std::numeric_limits<float>::max());
574 for (
auto& e : collection)
576 auto BB = extract_aabb(e);
577 auto LocalMax = BB.Origin + BB.Rotation.RotateVector(BB.Extent);
578 auto LocalMin = BB.Origin - BB.Rotation.RotateVector(BB.Extent);
580 LocalMin = LocalMin.ComponentMin(LocalMax);
581 LocalMax = LocalMax.ComponentMax(Tmp);
582 Max = Max.ComponentMax(LocalMax);
583 Min = Min.ComponentMin(LocalMin);
586 auto Extent = (Max - Min) * 0.5f;
587 auto Origin = Min + Extent;
589 return { Origin, Extent };
592template <
typename Collection>
595 using T = std::remove_reference_t<
decltype(collection[0])>;
610 e->GetComponentLocation(),
611 e->GetScaledBoxExtent(),
612 e->GetComponentRotation()
620 TArray<UStaticMeshComponent*>& OutStaticMeshComps)
625 const float DistanceThreshold = 100.0f * 100.0f;
627 TArray<UStaticMeshComponent*> SMComps;
628 Actor->GetComponents<UStaticMeshComponent>(SMComps);
630 for(UStaticMeshComponent* Comp : SMComps)
632 if(!Comp->IsVisible())
continue;
634 TArray<FBoundingBox> BBs;
635 TArray<uint8> InternalOutTags;
638 if(BBs.Num() == 0)
continue;
641 float Distance = FVector::DistSquared(InBB.
Origin, BB.
Origin);
642 if(Distance <= DistanceThreshold)
644 OutStaticMeshComps.Emplace(Comp);
static FBoundingBox ApplyTransformToBB(FBoundingBox InBB, const FTransform &Transform)
static FBoundingBox CombineBoundingBoxesGeneric(Collection &&collection, ExtractAABB &&extract_aabb)
Base class for CARLA wheeled vehicles.
static crp::CityObjectLabel GetTagOfTaggedComponent(const UPrimitiveComponent &Component)
Retrieve the tag of an already tagged component.
static void GetBBsOfSkeletalMeshComponents(const TArray< USkeletalMeshComponent * > &SkeletalMeshComps, TArray< FBoundingBox > &OutBB, TArray< uint8 > &OutTag, uint8 InTagQueried=0xFF)
static TArray< FBoundingBox > GetBBsOfActor(const AActor *Actor, uint8 InTagQueried=0xFF)
static FBoundingBox GetCharacterBoundingBox(const ACharacter *Character, uint8 InTagQueried=0xFF)
static void GetISMBoundingBox(UInstancedStaticMeshComponent *ISMComp, TArray< FBoundingBox > &OutBoundingBox)
static FBoundingBox GetSkeletalMeshBoundingBox(const USkeletalMesh *SkeletalMesh)
static FBoundingBox GetStaticMeshBoundingBox(const UStaticMesh *StaticMesh)
static void GetTrafficLightBoundingBox(const ATrafficLightBase *TrafficLight, TArray< FBoundingBox > &OutBB, TArray< uint8 > &OutTag, uint8 InTagQueried=0xFF)
static FBoundingBox CombineBBs(const TArray< FBoundingBox > &BBsToCombine)
static void GetBBsOfStaticMeshComponents(const TArray< UStaticMeshComponent * > &StaticMeshComps, TArray< FBoundingBox > &OutBB, TArray< uint8 > &OutTag, uint8 InTagQueried=0xFF)
static FBoundingBox GetVehicleBoundingBox(const ACarlaWheeledVehicle *Vehicle, uint8 InTagQueried=0xFF)
static void CombineBBsOfActor(const AActor *Actor, TArray< FBoundingBox > &OutBB, TArray< uint8 > &OutTag, const float DistanceThreshold=0.0f, uint8 TagToCombine=0xFF)
static FBoundingBox GetActorBoundingBox(const AActor *Actor, uint8 InTagQueried=0xFF)
Compute the bounding box of the given Carla actor.
static void GetMeshCompsFromActorBoundingBox(const AActor *Actor, const FBoundingBox &InBB, TArray< UStaticMeshComponent * > &OutStaticMeshComps)
static FBoundingBox CombineBoxes(const TArray< UBoxComponent * > &BBsToCombine)
static TArray< FBoundingBox > GetBoundingBoxOfActors(const TArray< AActor * > &Actors, uint8 InTagQueried=0xFF)
FRotator Rotation
Rotation of the bounding box.
FVector Origin
Origin of the bounding box relative to its owner.
FVector Extent
Radii extent of the bounding box.