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();
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;
416 Result.Append(BBs.GetData(), BBs.Num());
426 TArray<FBoundingBox> Result;
429 bool FilterByTagEnabled = (TagQueried != crp::CityObjectLabel::Any);
431 FString ClassName =
Actor->GetClass()->GetName();
436 if( ClassName.Contains(
"Procedural_Bulding") )
return Result;
471 TArray<UInstancedStaticMeshComponent *> ISMComps;
472 Actor->GetComponents<UInstancedStaticMeshComponent>(ISMComps);
473 for(UInstancedStaticMeshComponent* Comp: ISMComps)
477 if(FilterByTagEnabled && Tag != TagQueried)
continue;
483 TArray<UStaticMeshComponent*> StaticMeshComps;
485 Actor->GetComponents<UStaticMeshComponent>(StaticMeshComps);
489 TArray<USkeletalMeshComponent*> SkeletalMeshComps;
491 Actor->GetComponents<USkeletalMeshComponent>(SkeletalMeshComps);
499 TArray<FBoundingBox>& OutBB,
500 TArray<uint8>& OutTag,
501 const float DistanceThreshold,
506 TArray<FBoundingBox> BBsOfTL;
507 TArray<uint8> InternalOutTags;
508 TArray<UStaticMeshComponent*> StaticMeshComps;
509 Actor->GetComponents<UStaticMeshComponent>(StaticMeshComps);
512 bool IgnoreDistanceFilter = (DistanceThreshold <= 0.0f);
513 bool IgnoreTag = (TagToCombine == 0);
515 TSet<int> IndicesDiscarded;
516 for(
int i = 0; i < BBsOfTL.Num(); i++)
519 if(IndicesDiscarded.Contains(i))
continue;
521 TArray<FBoundingBox> BBsToCombine;
523 uint8 Tag1 = InternalOutTags[i];
525 for(
int j = i + 1; j < BBsOfTL.Num(); j++)
528 if(IndicesDiscarded.Contains(j))
continue;
531 uint8 Tag2 = InternalOutTags[j];
533 float Distance = FVector::DistSquared(BB1.
Origin, BB2.
Origin);
536 if( ((Distance <= DistanceThreshold) || IgnoreDistanceFilter) &&
537 ((Tag1 == Tag2) || IgnoreTag) )
539 BBsToCombine.Emplace(BB2);
540 IndicesDiscarded.Emplace(j);
543 if(BBsToCombine.Num() > 0)
545 BBsToCombine.Emplace(BB1);
546 IndicesDiscarded.Emplace(i);
549 OutBB.Emplace(MergedBB);
550 OutTag.Emplace(InternalOutTags[i]);
555 for(
int i = 0; i < BBsOfTL.Num(); i++)
558 if(IndicesDiscarded.Contains(i))
continue;
561 OutTag.Emplace(InternalOutTags[i]);
565template <
typename Collection,
typename ExtractAABB>
567 Collection&& collection,
568 ExtractAABB&& extract_aabb)
570 FVector Max(std::numeric_limits<float>::lowest());
571 FVector Min(std::numeric_limits<float>::max());
573 for (
auto& e : collection)
575 auto BB = extract_aabb(e);
576 auto LocalMax = BB.Origin + BB.Rotation.RotateVector(BB.Extent);
577 auto LocalMin = BB.Origin - BB.Rotation.RotateVector(BB.Extent);
579 LocalMin = LocalMin.ComponentMin(LocalMax);
580 LocalMax = LocalMax.ComponentMax(Tmp);
581 Max = Max.ComponentMax(LocalMax);
582 Min = Min.ComponentMin(LocalMin);
585 auto Extent = (Max - Min) * 0.5f;
586 auto Origin = Min + Extent;
588 return { Origin, Extent };
591template <
typename Collection>
594 using T = std::remove_reference_t<
decltype(collection[0])>;
609 e->GetComponentLocation(),
610 e->GetScaledBoxExtent(),
611 e->GetComponentRotation()
619 TArray<UStaticMeshComponent*>& OutStaticMeshComps)
624 const float DistanceThreshold = 100.0f * 100.0f;
626 TArray<UStaticMeshComponent*> SMComps;
627 Actor->GetComponents<UStaticMeshComponent>(SMComps);
629 for(UStaticMeshComponent* Comp : SMComps)
631 if(!Comp->IsVisible())
continue;
633 TArray<FBoundingBox> BBs;
634 TArray<uint8> InternalOutTags;
637 if(BBs.Num() == 0)
continue;
640 float Distance = FVector::DistSquared(InBB.
Origin, BB.
Origin);
641 if(Distance <= DistanceThreshold)
643 OutStaticMeshComps.Emplace(Comp);
UE_LOG(LogCarla, Log, TEXT("UActorDispatcher::Destroying actor: '%s' %x"), *Id, Actor)
TMap< IdType, AActor * > Actors
static FBoundingBox ApplyTransformToBB(FBoundingBox InBB, const FTransform &Transform)
static FBoundingBox CombineBoundingBoxesGeneric(Collection &&collection, ExtractAABB &&extract_aabb)
TSharedPtr< const FActorInfo > carla::rpc::ActorState UWorld Actor
Base class for CARLA wheeled vehicles.
static crp::CityObjectLabel GetTagOfTaggedComponent(const UPrimitiveComponent &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)
计算给定 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)
FVector Origin
边界框相对于其所有者的原点