CARLA
Loading...
Searching...
No Matches
DebugShapeDrawer.cpp
Go to the documentation of this file.
1// Copyright (c) 2026 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
8#include "Carla.h"
12#include "DrawDebugHelpers.h"
13#include "Components/LineBatchComponent.h"
14
17#include <carla/rpc/String.h>
19
20
21
22
24{
26
27 FShapeVisitor(UWorld &InWorld, FColor InColor, float InLifeTime, bool bInPersistentLines)
28 : World(&InWorld),
29 Color(InColor.ReinterpretAsLinear() * BrightMultiplier),
30 LifeTime(InLifeTime),
31 bPersistentLines(bInPersistentLines)
32 {
33 World->GetLineBatcher(UWorld::ELineBatcherType::WorldPersistent)->SetCollisionEnabled(ECollisionEnabled::NoCollision);
34 }
35
36 void operator()(const Shape::Point &Point) const
37 {
38 FVector Location = FVector(Point.location);
40 if (LargeMap)
41 {
42 Location = LargeMap->GlobalToLocalLocation(Location);
43 }
44 World->GetLineBatcher(UWorld::ELineBatcherType::WorldPersistent)->DrawPoint(
45 Location,
46 Color,
47 1e2f * Point.size,
49 LifeTime);
50 }
51
52 void operator()(const Shape::Line &Line) const
53 {
54 FVector Begin = FVector(Line.begin);
55 FVector End = FVector(Line.end);
57 if (LargeMap)
58 {
59 Begin = LargeMap->GlobalToLocalLocation(Begin);
60 End = LargeMap->GlobalToLocalLocation(End);
61 }
62 World->GetLineBatcher(UWorld::ELineBatcherType::WorldPersistent)->DrawLine(
63 Begin,
64 End,
65 Color,
67 1e2f * Line.thickness,
68 LifeTime);
69 }
70
71 void operator()(const Shape::Arrow &Arrow) const
72 {
73 FVector Begin = FVector(Arrow.line.begin);
74 FVector End = FVector(Arrow.line.end);
76 if (LargeMap)
77 {
78 Begin = LargeMap->GlobalToLocalLocation(Begin);
79 End = LargeMap->GlobalToLocalLocation(End);
80 }
81 const auto Diff = End - Begin;
82 const FRotator LookAt = FRotationMatrix::MakeFromX(Diff).Rotator();
83 const FTransform Transform = {LookAt, Begin};
84
85 // Everything in centimeters
86 const auto Dist = Diff.Size();
87 const auto ArrowSize = 1e2f * Arrow.arrow_size;
88 const auto ArrowTipDist = Dist - ArrowSize;
89 const auto Thickness = 1e2f * Arrow.line.thickness;
90
91 FBatchedLine BatchedLines[] =
92 {
93 FBatchedLine(
94 Begin,
95 End,
96 Color,
98 Thickness,
100 FBatchedLine(
101 Transform.TransformPosition(FVector(ArrowTipDist, +ArrowSize, +ArrowSize)),
102 End,
103 Color,
104 LifeTime,
105 Thickness,
107 FBatchedLine(
108 Transform.TransformPosition(FVector(ArrowTipDist, +ArrowSize, -ArrowSize)),
109 End,
110 Color,
111 LifeTime,
112 Thickness,
114 FBatchedLine(
115 Transform.TransformPosition(FVector(ArrowTipDist, -ArrowSize, +ArrowSize)),
116 End,
117 Color,
118 LifeTime,
119 Thickness,
121 FBatchedLine(
122 Transform.TransformPosition(FVector(ArrowTipDist, -ArrowSize, -ArrowSize)),
123 End,
124 Color,
125 LifeTime,
126 Thickness,
128 };
129
130 World->GetLineBatcher(UWorld::ELineBatcherType::WorldPersistent)->DrawLines(TArrayView<FBatchedLine>(BatchedLines, 5));
131 }
132
133 void operator()(const Shape::Box &Box) const
134 {
135 const FVector Extent = 1e2f * FVector{Box.box.extent.x, Box.box.extent.y, Box.box.extent.z};
136 FTransform Transform = {FRotator(Box.rotation), Box.box.location};
137 const auto Thickness = 1e2f * Box.thickness;
138
140 if (LargeMap)
141 {
142 Transform = LargeMap->GlobalToLocalTransform(Transform);
143 }
144
145 FVector B[2], P, Q;
146 B[0] = -Extent;
147 B[1] = Extent;
148
149 for(int32 i = 0; i < 2; ++i)
150 {
151 for(int32 j = 0; j < 2; ++j)
152 {
153 P.X=B[i].X;
154 Q.X=B[i].X;
155 P.Y=B[j].Y;
156 Q.Y=B[j].Y;
157 P.Z=B[0].Z;
158 Q.Z=B[1].Z;
159 World->GetLineBatcher(UWorld::ELineBatcherType::WorldPersistent)->DrawLine(
160 Transform.TransformPosition(P),
161 Transform.TransformPosition(Q),
162 Color,
164 Thickness,
165 LifeTime);
166
167 P.Y=B[i].Y;
168 Q.Y=B[i].Y;
169 P.Z=B[j].Z;
170 Q.Z=B[j].Z;
171 P.X=B[0].X;
172 Q.X=B[1].X;
173 World->GetLineBatcher(UWorld::ELineBatcherType::WorldPersistent)->DrawLine(
174 Transform.TransformPosition(P),
175 Transform.TransformPosition(Q),
176 Color,
178 Thickness,
179 LifeTime);
180
181 P.Z=B[i].Z;
182 Q.Z=B[i].Z;
183 P.X=B[j].X;
184 Q.X=B[j].X;
185 P.Y=B[0].Y;
186 Q.Y=B[1].Y;
187 World->GetLineBatcher(UWorld::ELineBatcherType::WorldPersistent)->DrawLine(
188 Transform.TransformPosition(P),
189 Transform.TransformPosition(Q),
190 Color,
192 Thickness,
193 LifeTime);
194 }
195 }
196 }
197
198 void operator()(const Shape::String &Str) const
199 {
200 auto PlayerController = UGameplayStatics::GetPlayerController(World, 0);
201 if (PlayerController == nullptr)
202 {
203 UE_LOG(LogCarla, Error, TEXT("Can't find player controller!"));
204 return;
205 }
206 FVector Location = FVector(Str.location);
208 if (LargeMap)
209 {
210 Location = LargeMap->GlobalToLocalLocation(Location);
211 }
212 ACarlaHUD *Hud = Cast<ACarlaHUD>(PlayerController->GetHUD());
213 Hud->AddHUDString(carla::rpc::ToFString(Str.text), Location, Color.QuantizeRound(), LifeTime);
214 }
215
216private:
217
218 UWorld *World;
219
220 FLinearColor Color;
221
222 float LifeTime;
223
225
226 uint8 DepthPriority = SDPG_World;
227
228 // Debug lines are way more dark in the package, that's why this
229 // multiplier is needed.
230#if UE_BUILD_SHIPPING
231 static constexpr double BrightMultiplier = 1000.0;
232#else
233 // @TODO: Use UKismetSystemLibrary::IsStandalone to support colors
234 // in Editor's standalone mode.
235 static constexpr double BrightMultiplier = 1.0;
236#endif
237
238};
239
241{
242 auto Visitor = FShapeVisitor(World, Shape.color, Shape.life_time, Shape.persistent_lines);
243 std::visit(Visitor, Shape.primitive);
244}
245
247{
248 ULineBatchComponent* LineBatcher = World.GetLineBatcher(UWorld::ELineBatcherType::WorldPersistent);
249 if (LineBatcher != nullptr)
250 {
251 LineBatcher->Flush();
252 }
253}
Class to draw on HUD.
Definition CarlaHUD.h:45
void AddHUDString(const FString Str, const FVector Location, const FColor Color, double LifeTime)
Definition CarlaHUD.cpp:56
FTransform GlobalToLocalTransform(const FTransform &InTransform) const
FVector GlobalToLocalLocation(const FVector &InLocation) const
void Draw(const carla::rpc::DebugShape &Shape)
static ALargeMapManager * GetLargeMapManager(const UObject *WorldContextObject)
std::variant< Point, Line, Arrow, Box, String > primitive
Definition DebugShape.h:65
void operator()(const Shape::Box &Box) const
void operator()(const Shape::Line &Line) const
void operator()(const Shape::Arrow &Arrow) const
void operator()(const Shape::String &Str) const
void operator()(const Shape::Point &Point) const
static constexpr double BrightMultiplier
FShapeVisitor(UWorld &InWorld, FColor InColor, float InLifeTime, bool bInPersistentLines)