CARLA
 
载入中...
搜索中...
未找到
ObjectRegister.cpp
浏览该文件的文档.
1// Copyright (c) 2020 Computer Vision Center (CVC) at the Universitat Autonoma
2// de Barcelona (UAB).
3//
4// This work is licensed under the terms of the MIT license.
5// For a copy, see <https://opensource.org/licenses/MIT>.
6
7#include "Carla.h"
9
10#include "Carla/Game/Tagger.h"
12
13#include "InstancedFoliageActor.h"
14#include "GameFramework/Character.h"
15
16#if WITH_EDITOR
17#include "FileHelper.h"
18#include "Paths.h"
19#endif // WITH_EDITOR
20
21namespace crp = carla::rpc;
22
23TArray<FEnvironmentObject> UObjectRegister::GetEnvironmentObjects(uint8 InTagQueried) const
24{
25 TArray<FEnvironmentObject> Result;
26
27 crp::CityObjectLabel TagQueried = (crp::CityObjectLabel)InTagQueried;
28 bool FilterByTagEnabled = (TagQueried != crp::CityObjectLabel::Any);
29
31 {
32 if(!FilterByTagEnabled || (It.ObjectLabel == TagQueried))
33 {
34 Result.Emplace(It);
35 }
36 }
37
38 return Result;
39}
40
41void UObjectRegister::RegisterObjects(TArray<AActor*> Actors)
42{
43 // Empties the array but doesn't change memory allocations
44 EnvironmentObjects.Reset();
45
46 for(AActor* Actor : Actors)
47 {
48
49 FString ClassName = Actor->GetClass()->GetName();
50 // Discard Sky to not break the global ilumination
51 if(ClassName.Equals("BP_Sky_C")) continue;
52
53 ACarlaWheeledVehicle* Vehicle = Cast<ACarlaWheeledVehicle>(Actor);
54 if (Vehicle)
55 {
57 continue;
58 }
59
60 ACharacter* Character = Cast<ACharacter>(Actor);
61 if (Character)
62 {
64 continue;
65 }
66
67 ATrafficLightBase* TrafficLight = Cast<ATrafficLightBase>(Actor);
68 if(TrafficLight)
69 {
71 continue;
72 }
73
75
77
79 }
80
81#if WITH_EDITOR
82 // To help debug
83 FString FileContent;
84 FileContent += FString::Printf(TEXT("Num actors %d\n"), Actors.Num());
85 FileContent += FString::Printf(TEXT("Num registered objects %d\n\n"), EnvironmentObjects.Num());
86
87 for(const FEnvironmentObject& Object : EnvironmentObjects)
88 {
89 FileContent += FString::Printf(TEXT("%llu\t"), Object.Id);
90 FileContent += FString::Printf(TEXT("%s\t"), *Object.Name);
91 FileContent += FString::Printf(TEXT("%s\t"), *Object.IdStr);
92 FileContent += FString::Printf(TEXT("%d\n"), static_cast<int32>(Object.Type));
93 }
94
95
96 FString FilePath = FPaths::ProjectSavedDir() + "RegisteredObjects.txt";
97 FFileHelper::SaveStringToFile(
98 FileContent,
99 *FilePath,
100 FFileHelper::EEncodingOptions::AutoDetect,
101 &IFileManager::Get(),
102 EFileWrite::FILEWRITE_Silent);
103
104#endif // WITH_EDITOR
105
106}
107
108void UObjectRegister::EnableEnvironmentObjects(const TSet<uint64>& EnvObjectIds, bool Enable)
109{
110 for(uint64 It : EnvObjectIds)
111 {
112 bool found = false;
113 for(FEnvironmentObject& EnvironmentObject : EnvironmentObjects)
114 {
115 if(It == EnvironmentObject.Id)
116 {
117 EnableEnvironmentObject(EnvironmentObject, Enable);
118 found = true;
119 break;
120 }
121 }
122 if(!found)
123 {
124 UE_LOG(LogCarla, Error, TEXT("EnableEnvironmentObjects id not found %llu"), It);
125 }
126 }
127
128}
129
131 AActor* Actor,
134 uint8 Tag)
135{
136 const FString ActorName = Actor->GetName();
137 const char* ActorNameChar = TCHAR_TO_ANSI(*ActorName);
138
139 FEnvironmentObject EnvironmentObject;
140 EnvironmentObject.Transform = Actor->GetActorTransform();
141 EnvironmentObject.Id = CityHash64(ActorNameChar, ActorName.Len());
142 EnvironmentObject.Name = ActorName;
143 EnvironmentObject.Actor = Actor;
144 EnvironmentObject.CanTick = Actor->IsActorTickEnabled();
145 EnvironmentObject.BoundingBox = BoundingBox;
146 EnvironmentObject.ObjectLabel = static_cast<crp::CityObjectLabel>(Tag);
147 EnvironmentObject.Type = Type;
148 EnvironmentObjects.Emplace(std::move(EnvironmentObject));
149}
150
158
165
167{
168 check(TrafficLight);
169
170 TArray<FBoundingBox> BBs;
171 TArray<uint8> Tags;
172
174 check(BBs.Num() == Tags.Num());
175
176 const FTransform Transform = TrafficLight->GetTransform();
177 const FString ActorName = TrafficLight->GetName();
178 const bool IsActorTickEnabled = TrafficLight->IsActorTickEnabled();
179
180 for(int i = 0; i < BBs.Num(); i++)
181 {
182 const FBoundingBox& BB = BBs[i];
183 const uint8 Tag = Tags[i];
184
185 crp::CityObjectLabel ObjectLabel = static_cast<crp::CityObjectLabel>(Tag);
186
187 const FString TagString = ATagger::GetTagAsString(ObjectLabel);
188 const FString SMName = FString::Printf(TEXT("%s_%s_%d"), *ActorName, *TagString, i);
189
190 FEnvironmentObject EnvironmentObject;
191 EnvironmentObject.Transform = Transform;
192 EnvironmentObject.Id = CityHash64(TCHAR_TO_ANSI(*SMName), SMName.Len());
193 EnvironmentObject.Name = SMName;
194 EnvironmentObject.Actor = TrafficLight;
195 EnvironmentObject.CanTick = IsActorTickEnabled;
196 EnvironmentObject.BoundingBox = BB;
197 EnvironmentObject.Type = EnvironmentObjectType::TrafficLight;
198 EnvironmentObject.ObjectLabel = ObjectLabel;
199 EnvironmentObjects.Emplace(EnvironmentObject);
200
201 // Register components with its ID; it's not the best solution since we are recalculating the BBs
202 // But this is only calculated when the level is loaded
203 TArray<UStaticMeshComponent*> StaticMeshComps;
205 for(const UStaticMeshComponent* Comp : StaticMeshComps)
206 {
207 ObjectIdToComp.Emplace(EnvironmentObject.Id, Comp);
208 }
209 }
210}
211
213{
214 check(Actor);
215
216 TArray<UInstancedStaticMeshComponent*> ISMComps;
217 Actor->GetComponents<UInstancedStaticMeshComponent>(ISMComps);
218
219 const FString ActorName = Actor->GetName();
220 int InstanceCount = 0;
221 bool IsActorTickEnabled = Actor->IsActorTickEnabled();
222
223 // Foliage actor is a special case, it can appear more than once while traversing the actor list
224 if(Cast<AInstancedFoliageActor>(Actor))
225 {
226 InstanceCount = FoliageActorInstanceCount;
227 }
228
229 for(UInstancedStaticMeshComponent* Comp : ISMComps)
230 {
231 const TArray<FInstancedStaticMeshInstanceData>& PerInstanceSMData = Comp->PerInstanceSMData;
232 const FTransform CompTransform = Comp->GetComponentTransform();
233
234 TArray<FBoundingBox> BoundingBoxes;
236
237 FString CompName = Comp->GetName();
239
240 for(int i = 0; i < PerInstanceSMData.Num(); i++)
241 {
242 const FInstancedStaticMeshInstanceData& It = PerInstanceSMData[i];
243 const FTransform InstanceTransform = FTransform(It.Transform);
244 const FVector InstanceLocation = InstanceTransform.GetLocation();
245
246 // Discard decimal part
247 const int32 X = static_cast<int32>(InstanceLocation.X);
248 const int32 Y = static_cast<int32>(InstanceLocation.Y);
249 const int32 Z = static_cast<int32>(InstanceLocation.Z);
250
251 const FString InstanceName = FString::Printf(TEXT("%s_Inst_%d_%d"), *ActorName, InstanceCount, i);
252 const FString InstanceIdStr = FString::Printf(TEXT("%s_%s_%d_%d_%d_%d"), *ActorName, *CompName, X, Y, Z, InstanceCount);
253 uint64 InstanceId = CityHash64(TCHAR_TO_ANSI(*InstanceIdStr), InstanceIdStr.Len());
254
255 FEnvironmentObject EnvironmentObject;
256 EnvironmentObject.Transform = InstanceTransform * CompTransform;
257 EnvironmentObject.Id = InstanceId;
258 EnvironmentObject.Name = InstanceName;
259 EnvironmentObject.IdStr = InstanceIdStr;
260 EnvironmentObject.Actor = Actor;
261 EnvironmentObject.CanTick = IsActorTickEnabled;
262 if( i < BoundingBoxes.Num())
263 {
264 EnvironmentObject.BoundingBox = BoundingBoxes[i];
265 }
266
267 EnvironmentObject.Type = EnvironmentObjectType::ISMComp;
268 EnvironmentObject.ObjectLabel = static_cast<crp::CityObjectLabel>(Tag);
269 EnvironmentObjects.Emplace(EnvironmentObject);
270
271 ObjectIdToComp.Emplace(InstanceId, Comp);
272 InstanceCount++;
273 }
274 }
275
276 if(Cast<AInstancedFoliageActor>(Actor))
277 {
278 FoliageActorInstanceCount = InstanceCount;
279 }
280}
281
283{
284 check(Actor);
285
286 TArray<UStaticMeshComponent*> StaticMeshComps;
287 Actor->GetComponents<UStaticMeshComponent>(StaticMeshComps);
288
289 TArray<FBoundingBox> BBs;
290 TArray<uint8> Tags;
292 check(BBs.Num() == Tags.Num());
293
294 const FTransform Transform = Actor->GetTransform();
295 const FString ActorName = Actor->GetName();
296 const bool IsActorTickEnabled = Actor->IsActorTickEnabled();
297
298 for(int i = 0; i < BBs.Num(); i++)
299 {
300 const FString SMName = FString::Printf(TEXT("%s_SM_%d"), *ActorName, i);
301
302 FEnvironmentObject EnvironmentObject;
303 EnvironmentObject.Transform = Transform;
304 EnvironmentObject.Id = CityHash64(TCHAR_TO_ANSI(*SMName), SMName.Len());
305 EnvironmentObject.Name = SMName;
306 EnvironmentObject.Actor = Actor;
307 EnvironmentObject.CanTick = IsActorTickEnabled;
308 EnvironmentObject.BoundingBox = BBs[i];
309 EnvironmentObject.Type = EnvironmentObjectType::SMComp;
310 EnvironmentObject.ObjectLabel = static_cast<crp::CityObjectLabel>(Tags[i]);
311 EnvironmentObjects.Emplace(EnvironmentObject);
312 }
313}
314
316{
317 check(Actor);
318
319 TArray<USkeletalMeshComponent*> SkeletalMeshComps;
320 Actor->GetComponents<USkeletalMeshComponent>(SkeletalMeshComps);
321
322 TArray<FBoundingBox> BBs;
323 TArray<uint8> Tags;
324 UBoundingBoxCalculator::GetBBsOfSkeletalMeshComponents(SkeletalMeshComps, BBs, Tags);
325 check(BBs.Num() == Tags.Num());
326
327 const FTransform Transform = Actor->GetTransform();
328 const FString ActorName = Actor->GetName();
329 const bool IsActorTickEnabled = Actor->IsActorTickEnabled();
330
331 for(int i = 0; i < BBs.Num(); i++)
332 {
333 const FString SKMName = FString::Printf(TEXT("%s_SKM_%d"), *ActorName, i);
334
335 FEnvironmentObject EnvironmentObject;
336 EnvironmentObject.Transform = Transform;
337 EnvironmentObject.Id = CityHash64(TCHAR_TO_ANSI(*SKMName), SKMName.Len());
338 EnvironmentObject.Name = SKMName;
339 EnvironmentObject.Actor = Actor;
340 EnvironmentObject.CanTick = IsActorTickEnabled;
341 EnvironmentObject.BoundingBox = BBs[i];
342 EnvironmentObject.Type = EnvironmentObjectType::SKMComp;
343 EnvironmentObject.ObjectLabel = static_cast<crp::CityObjectLabel>(Tags[i]);
344 EnvironmentObjects.Emplace(EnvironmentObject);
345
346 }
347
348}
349
351 FEnvironmentObject& EnvironmentObject,
352 bool Enable)
353{
354 switch (EnvironmentObject.Type)
355 {
360 EnableActor(EnvironmentObject, Enable);
361 break;
363 EnableTrafficLight(EnvironmentObject, Enable);
364 break;
366 EnableISMComp(EnvironmentObject, Enable);
367 break;
368 default:
369 check(false);
370 break;
371 }
372
373}
374
375void UObjectRegister::EnableActor(FEnvironmentObject& EnvironmentObject, bool Enable)
376{
377 AActor* Actor = EnvironmentObject.Actor;
378
379 Actor->SetActorHiddenInGame(!Enable);
380 Actor->SetActorEnableCollision(Enable);
381 if(EnvironmentObject.CanTick)
382 {
383 Actor->SetActorTickEnabled(Enable);
384 }
385}
386
387void UObjectRegister::EnableTrafficLight(FEnvironmentObject& EnvironmentObject, bool Enable)
388{
389 // We need to look for the component(s) that form the EnvironmentObject
390 // i.e.: The light box is composed by various SMComponents, one per light,
391 // we need to enable/disable all of them
392
393 TArray<const UStaticMeshComponent*> ObjectComps;
394 ObjectIdToComp.MultiFind(EnvironmentObject.Id, ObjectComps);
395
396 for(const UStaticMeshComponent* Comp : ObjectComps)
397 {
398 UStaticMeshComponent* SMComp = const_cast<UStaticMeshComponent*>(Comp);
399 SMComp->SetHiddenInGame(!Enable);
400 ECollisionEnabled::Type CollisionType = Enable ? ECollisionEnabled::Type::QueryAndPhysics : ECollisionEnabled::Type::NoCollision;
401 SMComp->SetCollisionEnabled(CollisionType);
402 }
403
404}
405
406void UObjectRegister::EnableISMComp(FEnvironmentObject& EnvironmentObject, bool Enable)
407{
408 TArray<const UStaticMeshComponent*> ObjectComps;
409 TArray<FString> InstanceName;
410 FTransform InstanceTransform = EnvironmentObject.Transform;
411
412 ObjectIdToComp.MultiFind(EnvironmentObject.Id, ObjectComps);
413 EnvironmentObject.Name.ParseIntoArray(InstanceName, TEXT("_"), false);
414
415 int Index = FCString::Atoi(*InstanceName[InstanceName.Num() - 1]);
416
417 if(!Enable)
418 {
419 InstanceTransform.SetTranslation(FVector(1000000.0f));
420 InstanceTransform.SetScale3D(FVector(0.0f));
421 }
422
423 UStaticMeshComponent* SMComp = const_cast<UStaticMeshComponent*>(ObjectComps[0]);
424 UInstancedStaticMeshComponent* ISMComp = Cast<UInstancedStaticMeshComponent>(SMComp);
425 bool Result = ISMComp->UpdateInstanceTransform(Index, InstanceTransform, true, true);
426
427}
Base class for CARLA wheeled vehicles.
static crp::CityObjectLabel GetTagOfTaggedComponent(const UPrimitiveComponent &Component)
Retrieve the tag of an already tagged component.
Definition Tagger.h:52
static FString GetTagAsString(crp::CityObjectLabel Tag)
Retrieve the tags of an already tagged actor.
Definition Tagger.cpp:251
static void GetBBsOfSkeletalMeshComponents(const TArray< USkeletalMeshComponent * > &SkeletalMeshComps, TArray< FBoundingBox > &OutBB, TArray< uint8 > &OutTag, uint8 InTagQueried=0xFF)
static FBoundingBox GetCharacterBoundingBox(const ACharacter *Character, uint8 InTagQueried=0xFF)
static void GetISMBoundingBox(UInstancedStaticMeshComponent *ISMComp, TArray< FBoundingBox > &OutBoundingBox)
static void GetTrafficLightBoundingBox(const ATrafficLightBase *TrafficLight, TArray< FBoundingBox > &OutBB, TArray< uint8 > &OutTag, uint8 InTagQueried=0xFF)
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 GetMeshCompsFromActorBoundingBox(const AActor *Actor, const FBoundingBox &InBB, TArray< UStaticMeshComponent * > &OutStaticMeshComps)
void RegisterVehicle(ACarlaWheeledVehicle *Vehicle)
void RegisterSMComponents(AActor *Actor)
TArray< FEnvironmentObject > EnvironmentObjects
void EnableEnvironmentObject(FEnvironmentObject &EnvironmentObject, bool Enable)
void EnableISMComp(FEnvironmentObject &EnvironmentObject, bool Enable)
void EnableEnvironmentObjects(const TSet< uint64 > &EnvObjectIds, bool Enable)
void RegisterTrafficLight(ATrafficLightBase *TrafficLight)
void RegisterEnvironmentObject(AActor *Actor, FBoundingBox &BoundingBox, EnvironmentObjectType Type, uint8 Tag)
void RegisterObjects(TArray< AActor * > Actors)
void RegisterSKMComponents(AActor *Actor)
TArray< FEnvironmentObject > GetEnvironmentObjects(uint8 InTagQueried=0xFF) const
void RegisterCharacter(ACharacter *Character)
void EnableActor(FEnvironmentObject &EnvironmentObject, bool Enable)
TMultiMap< uint64, const UStaticMeshComponent * > ObjectIdToComp
void EnableTrafficLight(FEnvironmentObject &EnvironmentObject, bool Enable)
void RegisterISMComponents(AActor *Actor)