12#include "UObject/ConstructorHelpers.h"
13#include "DrawDebugHelpers.h"
15#include "ConstructorHelpers.h"
16#include "Materials/MaterialExpressionTextureSample.h"
18#include "DrawDebugHelpers.h"
28#include <unordered_set>
31 : Super(ObjectInitializer)
33 PrimaryActorTick.bCanEverTick =
false;
36 static struct FConstructorStatics
39 ConstructorHelpers::FObjectFinderOptional<UTexture2D> TextureObject;
44 : TextureObject(TEXT(
"/Carla/Icons/OpenDriveActorIcon")),
45 Category(TEXT(
"OpenDriveActor")),
46 Name(NSLOCTEXT(
"SpriteCategory",
"OpenDriveActor",
"OpenDriveActor"))
51 USceneComponent *SceneComponent =
52 ObjectInitializer.CreateDefaultSubobject<USceneComponent>(
this, TEXT(
"SceneComp"));
53 RootComponent = SceneComponent;
54 RootComponent->Mobility = EComponentMobility::Static;
56#if WITH_EDITORONLY_DATA
58 ObjectInitializer.CreateEditorOnlyDefaultSubobject<UBillboardComponent>(
this, TEXT(
"Sprite"));
78void AOpenDriveActor::PostEditChangeProperty(
struct FPropertyChangedEvent &Event)
81 Super::PostEditChangeProperty(Event);
84 const FName PropertyName = (Event.Property != NULL ? Event.Property->GetFName() : NAME_None);
86 if (PropertyName == GET_MEMBER_NAME_CHECKED(
AOpenDriveActor, bGenerateRoutes))
91 bGenerateRoutes =
false;
110 if (PropertyName == GET_MEMBER_NAME_CHECKED(
AOpenDriveActor, bRemoveRoutes))
116 bRemoveRoutes =
false;
124 if (PropertyName == GET_MEMBER_NAME_CHECKED(
AOpenDriveActor, bShowDebug))
138 if (PropertyName == GET_MEMBER_NAME_CHECKED(
AOpenDriveActor, bRemoveCurrentSpawners))
141 if (bRemoveCurrentSpawners)
144 bRemoveCurrentSpawners =
false;
167 if (!map.has_value())
169 UE_LOG(LogCarla, Error, TEXT(
"Failed to parse OpenDrive file."));
174 const std::vector<Waypoint> LaneWaypoints =
175 map->GenerateWaypointsOnRoadEntries();
177 std::unordered_map<Waypoint, std::vector<Waypoint>> PredecessorMap;
179 for (
auto &Wp : LaneWaypoints)
181 const auto PredecessorsList = map->GetPredecessors(Wp);
182 if (PredecessorsList.empty())
186 const auto MinRoadId = *std::min_element(
187 PredecessorsList.begin(),
188 PredecessorsList.end(),
189 [](
const auto &WaypointA,
const auto &WaypointB) {
190 return WaypointA.road_id < WaypointB.road_id;
192 PredecessorMap[MinRoadId].emplace_back(Wp);
195 for (
auto &&PredecessorWp : PredecessorMap)
199 for (
auto &&Wp : PredecessorWp.second)
201 std::vector<Waypoint> Waypoints;
206 Waypoints.emplace_back(CurrentWp);
207 const auto Successors = map->GetNext(CurrentWp,
RoadAccuracy);
208 if (Successors.empty())
212 if (Successors.front().road_id != Wp.road_id)
216 CurrentWp = Successors.front();
217 }
while (CurrentWp.road_id == Wp.road_id);
220 const auto FollowingWp = map->GetSuccessors(CurrentWp);
221 if (!FollowingWp.empty())
223 Waypoints.emplace_back(FollowingWp.front());
226 if (Waypoints.size() >= 2)
228 TArray<FVector> Positions;
229 Positions.Reserve(Waypoints.size());
230 for (
int i = 0; i < Waypoints.size(); ++i)
233 Positions.Add(map->ComputeTransform(Waypoints[i]).location +
238 if (RoutePlanner ==
nullptr )
240 const auto WpTransform = map->ComputeTransform(Wp);
244 RoutePlanner->SetActorRotation(WpTransform.rotation);
245 RoutePlanner->SetActorLocation(WpTransform.location +
249 if (RoutePlanner !=
nullptr)
251 RoutePlanner->
AddRoute(1.f, Positions);
262 for (
int i = 0; i < rp_num; i++)
286 FlushPersistentDebugLines(GetWorld());
304 Spawner->SetActorRotation(Trans.GetRotation());
305 Spawner->SetActorLocation(Trans.GetTranslation() + FVector(0.f, 0.f,
SpawnersHeight));
315 for (
int i = 0; i < vs_num; i++)
UE_LOG(LogCarla, Log, TEXT("UActorDispatcher::Destroying actor: '%s' %x"), *Id, Actor)
float TriggersHeight
触发器的高程
float SpawnersHeight
确定生成器放置的高度,相对于每个RoutePlanner。
AOpenDriveActor(const FObjectInitializer &ObjectInitializer)
bool bOnIntersections
如果为true,在交叉路口也放置生成器
float RoadAccuracy
车辆行驶的路径点之间的距离。
bool bAddSpawners
如果编译时包含编辑器数据。
void RemoveRoutes()
根据地图名称构建路径
UBillboardComponent * SpriteComponent
Billboard组件用于显示图标精灵。
TArray< ARoutePlanner * > RoutePlanners
TArray< AVehicleSpawnPoint * > VehicleSpawners
定义一个数组属性,存储VehicleSpawnPoint对象
void RemoveDebugRoutes() const
为每个进入触发体积的 ACarlaWheeledVehicle 分配一条随机路线。 将此参与者放入世界后,必须在编辑器中添加路线。样条线切线将被忽略,仅考虑位置来制定路线。
void AddRoute(float probability, const TArray< FVector > &routePoints)
void SetBoxExtent(const FVector &Extent)
static FString LoadXODR(const FString &MapName)
static boost::optional< road::Map > Load(const std::string &opendrive)