CARLA
SceneCaptureSensor.h
Go to the documentation of this file.
1 // Copyright (c) 2017 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 #pragma once
8 
10 #include "Carla/Sensor/Sensor.h"
12 #include "Carla/Sensor/ImageUtil.h"
13 
14 #include "Async/Async.h"
15 #include "Renderer/Public/GBufferView.h"
16 
17 #include <type_traits>
18 
19 #include "SceneCaptureSensor.generated.h"
20 
21 
22 
23 class UDrawFrustumComponent;
24 class UStaticMeshComponent;
25 class UTextureRenderTarget2D;
26 
27 
28 
30 {
31  /// Prevent this sensor to be spawned by users.
32  using not_spawnable = void;
33 
34  void SetDataStream(FDataStream InStream)
35  {
36  Stream = std::move(InStream);
37  }
38 
39  /// Replace the Stream associated with this sensor.
40  void SetStream(FDataMultiStream InStream)
41  {
42  Stream = std::move(InStream);
43  }
44  /// Return the token that allows subscribing to this sensor's stream.
45  auto GetToken() const
46  {
47  bIsUsed = true;
48  return Stream.GetToken();
49  }
50 
51  /// Dummy. Required for compatibility with other sensors only.
52  FTransform GetActorTransform() const
53  {
54  return {};
55  }
56  /// Return the FDataStream associated with this sensor.
57  ///
58  /// You need to provide a reference to self, this is necessary for template
59  /// deduction.
60  template <typename SensorT>
61  FAsyncDataStream GetDataStream(const SensorT &Self)
62  {
63  return Stream.MakeAsyncDataStream(Self, Self.GetEpisode().GetElapsedGameTime());
64  }
65 
66  mutable bool bIsUsed = false;
68 };
69 
70 
71 
73 {
74  /// Prevent this sensor to be spawned by users.
75  using not_spawnable = void;
76 
77  void SetDataStream(FDataStream InStream)
78  {
79  Stream = std::move(InStream);
80  }
81 
82  /// Replace the Stream associated with this sensor.
83  void SetStream(FDataMultiStream InStream)
84  {
85  Stream = std::move(InStream);
86  }
87  /// Return the token that allows subscribing to this sensor's stream.
88  auto GetToken() const
89  {
90  bIsUsed = true;
91  return Stream.GetToken();
92  }
93  /// Dummy. Required for compatibility with other sensors only.
94  FTransform GetActorTransform() const
95  {
96  return {};
97  }
98  /// Return the FDataStream associated with this sensor.
99  ///
100  /// You need to provide a reference to self, this is necessary for template
101  /// deduction.
102  template <typename SensorT>
103  FAsyncDataStream GetDataStream(const SensorT &Self)
104  {
105  return Stream.MakeAsyncDataStream(Self, Self.GetEpisode().GetElapsedGameTime());
106  }
107 
108  mutable bool bIsUsed = false;
110 };
111 
112 
113 
114 
115 
116 
117 /// Base class for sensors using a USceneCaptureComponent2D for rendering the
118 /// scene. This class does not capture data, use
119 /// `FPixelReader::SendPixelsInRenderThread(*this)` in derived classes.
120 ///
121 /// To access the USceneCaptureComponent2D override the
122 /// SetUpSceneCaptureComponent function.
123 ///
124 /// @warning All the setters should be called before BeginPlay.
125 UCLASS(Abstract)
126 class CARLA_API ASceneCaptureSensor : public ASensor
127 {
128  GENERATED_BODY()
129 
130  friend class ACarlaGameModeBase;
131  friend class FPixelReader;
132  friend class FPixelReader2;
133 
134 public:
135 
136  ASceneCaptureSensor(const FObjectInitializer &ObjectInitializer);
137 
138  void Set(const FActorDescription &ActorDescription) override;
139 
140  void SetImageSize(uint32 Width, uint32 Height);
141 
142  uint32 GetImageWidth() const
143  {
144  return ImageWidth;
145  }
146 
147  uint32 GetImageHeight() const
148  {
149  return ImageHeight;
150  }
151 
152  UFUNCTION(BlueprintCallable)
153  void EnablePostProcessingEffects(bool Enable = true)
154  {
155  bEnablePostProcessingEffects = Enable;
156  }
157 
158  UFUNCTION(BlueprintCallable)
159  bool ArePostProcessingEffectsEnabled() const
160  {
161  return bEnablePostProcessingEffects;
162  }
163 
164  UFUNCTION(BlueprintCallable)
165  void Enable16BitFormat(bool Enable = false)
166  {
167  bEnable16BitFormat = Enable;
168  }
169 
170  UFUNCTION(BlueprintCallable)
171  bool Is16BitFormatEnabled() const
172  {
173  return bEnable16BitFormat;
174  }
175 
176  UFUNCTION(BlueprintCallable)
177  void SetFOVAngle(float FOVAngle);
178 
179  UFUNCTION(BlueprintCallable)
180  float GetFOVAngle() const;
181 
182  UFUNCTION(BlueprintCallable)
183  void SetTargetGamma(float InTargetGamma)
184  {
185  TargetGamma = InTargetGamma;
186  }
187 
188  UFUNCTION(BlueprintCallable)
189  float GetTargetGamma() const
190  {
191  return TargetGamma;
192  }
193 
194  UFUNCTION(BlueprintCallable)
195  void SetExposureMethod(EAutoExposureMethod Method);
196 
197  UFUNCTION(BlueprintCallable)
198  EAutoExposureMethod GetExposureMethod() const;
199 
200  UFUNCTION(BlueprintCallable)
201  void SetExposureCompensation(float Compensation);
202 
203  UFUNCTION(BlueprintCallable)
204  float GetExposureCompensation() const;
205 
206  UFUNCTION(BlueprintCallable)
207  void SetShutterSpeed(float Speed);
208 
209  UFUNCTION(BlueprintCallable)
210  float GetShutterSpeed() const;
211 
212  UFUNCTION(BlueprintCallable)
213  void SetISO(float ISO);
214 
215  UFUNCTION(BlueprintCallable)
216  float GetISO() const;
217 
218  UFUNCTION(BlueprintCallable)
219  void SetAperture(float Aperture);
220 
221  UFUNCTION(BlueprintCallable)
222  float GetAperture() const;
223 
224  UFUNCTION(BlueprintCallable)
225  void SetFocalDistance(float Distance);
226 
227  UFUNCTION(BlueprintCallable)
228  float GetFocalDistance() const;
229 
230  UFUNCTION(BlueprintCallable)
231  void SetDepthBlurAmount(float Amount);
232 
233  UFUNCTION(BlueprintCallable)
234  float GetDepthBlurAmount() const;
235 
236  UFUNCTION(BlueprintCallable)
237  void SetDepthBlurRadius(float Radius);
238 
239  UFUNCTION(BlueprintCallable)
240  float GetDepthBlurRadius() const;
241 
242  UFUNCTION(BlueprintCallable)
243  void SetBladeCount(int Count);
244 
245  UFUNCTION(BlueprintCallable)
246  int GetBladeCount() const;
247 
248  UFUNCTION(BlueprintCallable)
249  void SetDepthOfFieldMinFstop(float MinFstop);
250 
251  UFUNCTION(BlueprintCallable)
252  float GetDepthOfFieldMinFstop() const;
253 
254  UFUNCTION(BlueprintCallable)
255  void SetFilmSlope(float Slope);
256 
257  UFUNCTION(BlueprintCallable)
258  float GetFilmSlope() const;
259 
260  UFUNCTION(BlueprintCallable)
261  void SetFilmToe(float Toe);
262 
263  UFUNCTION(BlueprintCallable)
264  float GetFilmToe() const;
265 
266  UFUNCTION(BlueprintCallable)
267  void SetFilmShoulder(float Shoulder);
268 
269  UFUNCTION(BlueprintCallable)
270  float GetFilmShoulder() const;
271 
272  UFUNCTION(BlueprintCallable)
273  void SetFilmBlackClip(float BlackClip);
274 
275  UFUNCTION(BlueprintCallable)
276  float GetFilmBlackClip() const;
277 
278  UFUNCTION(BlueprintCallable)
279  void SetFilmWhiteClip(float WhiteClip);
280 
281  UFUNCTION(BlueprintCallable)
282  float GetFilmWhiteClip() const;
283 
284  UFUNCTION(BlueprintCallable)
285  void SetExposureMinBrightness(float Brightness);
286 
287  UFUNCTION(BlueprintCallable)
288  float GetExposureMinBrightness() const;
289 
290  UFUNCTION(BlueprintCallable)
291  void SetExposureMaxBrightness(float Brightness);
292 
293  UFUNCTION(BlueprintCallable)
294  float GetExposureMaxBrightness() const;
295 
296  UFUNCTION(BlueprintCallable)
297  void SetExposureSpeedDown(float Speed);
298 
299  UFUNCTION(BlueprintCallable)
300  float GetExposureSpeedDown() const;
301 
302  UFUNCTION(BlueprintCallable)
303  void SetExposureSpeedUp(float Speed);
304 
305  UFUNCTION(BlueprintCallable)
306  float GetExposureSpeedUp() const;
307 
308  UFUNCTION(BlueprintCallable)
309  void SetExposureCalibrationConstant(float Constant);
310 
311  UFUNCTION(BlueprintCallable)
312  float GetExposureCalibrationConstant() const;
313 
314  UFUNCTION(BlueprintCallable)
315  void SetMotionBlurIntensity(float Intensity);
316 
317  UFUNCTION(BlueprintCallable)
318  float GetMotionBlurIntensity() const;
319 
320  UFUNCTION(BlueprintCallable)
321  void SetMotionBlurMaxDistortion(float MaxDistortion);
322 
323  UFUNCTION(BlueprintCallable)
324  float GetMotionBlurMaxDistortion() const;
325 
326  UFUNCTION(BlueprintCallable)
327  void SetMotionBlurMinObjectScreenSize(float ScreenSize);
328 
329  UFUNCTION(BlueprintCallable)
330  float GetMotionBlurMinObjectScreenSize() const;
331 
332  UFUNCTION(BlueprintCallable)
333  void SetLensFlareIntensity(float Intensity);
334 
335  UFUNCTION(BlueprintCallable)
336  float GetLensFlareIntensity() const;
337 
338  UFUNCTION(BlueprintCallable)
339  void SetBloomIntensity(float Intensity);
340 
341  UFUNCTION(BlueprintCallable)
342  float GetBloomIntensity() const;
343 
344  UFUNCTION(BlueprintCallable)
345  void SetWhiteTemp(float Temp);
346 
347  UFUNCTION(BlueprintCallable)
348  float GetWhiteTemp() const;
349 
350  UFUNCTION(BlueprintCallable)
351  void SetWhiteTint(float Tint);
352 
353  UFUNCTION(BlueprintCallable)
354  float GetWhiteTint() const;
355 
356  UFUNCTION(BlueprintCallable)
357  void SetChromAberrIntensity(float Intensity);
358 
359  UFUNCTION(BlueprintCallable)
360  float GetChromAberrIntensity() const;
361 
362  UFUNCTION(BlueprintCallable)
363  void SetChromAberrOffset(float ChromAberrOffset);
364 
365  UFUNCTION(BlueprintCallable)
366  float GetChromAberrOffset() const;
367 
368  /// Use for debugging purposes only.
369  UFUNCTION(BlueprintCallable)
370  bool ReadPixels(TArray<FColor> &BitMap) const
371  {
372  check(CaptureRenderTarget != nullptr);
373  return FPixelReader::WritePixelsToArray(*CaptureRenderTarget, BitMap);
374  }
375 
376  /// Use for debugging purposes only.
377  UFUNCTION(BlueprintCallable)
378  void SaveCaptureToDisk(const FString &FilePath) const
379  {
380  check(CaptureRenderTarget != nullptr);
381  FPixelReader::SavePixelsToDisk(*CaptureRenderTarget, FilePath);
382  }
383 
384  UFUNCTION(BlueprintCallable)
385  USceneCaptureComponent2D *GetCaptureComponent2D()
386  {
387  return CaptureComponent2D;
388  }
389 
390  UFUNCTION(BlueprintCallable)
391  UTextureRenderTarget2D *GetCaptureRenderTarget()
392  {
393  return CaptureRenderTarget;
394  }
395 
396  /// Immediate enqueues render commands of the scene at the current time.
397  void EnqueueRenderSceneImmediate();
398 
399  /// Blocks until the render thread has finished all it's tasks.
401  TRACE_CPUPROFILER_EVENT_SCOPE(ASceneCaptureSensor::WaitForRenderThreadToFinish);
402  // FlushRenderingCommands();
403  }
404 
405  struct
406  {
420  } CameraGBuffers;
421 
422 protected:
423 
424  void CaptureSceneExtended();
425 
426  virtual void SendGBufferTextures(FGBufferRequest& GBuffer);
427 
428  virtual void BeginPlay() override;
429 
430  virtual void PrePhysTick(float DeltaSeconds) override;
431  virtual void PostPhysTick(UWorld *World, ELevelTick TickType, float DeltaTime) override;
432 
433  virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
434 
436 
437  /// Render target necessary for scene capture.
438  UPROPERTY(EditAnywhere)
439  UTextureRenderTarget2D *CaptureRenderTarget = nullptr;
440 
441  /// Scene capture component.
442  UPROPERTY(EditAnywhere)
443  USceneCaptureComponent2D_CARLA *CaptureComponent2D = nullptr;
444 
445  UPROPERTY(EditAnywhere)
446  float TargetGamma = 2.4f;
447 
448  /// Image width in pixels.
449  UPROPERTY(EditAnywhere)
450  uint32 ImageWidth = 800u;
451 
452  /// Image height in pixels.
453  UPROPERTY(EditAnywhere)
454  uint32 ImageHeight = 600u;
455 
456  /// Whether to render the post-processing effects present in the scene.
457  UPROPERTY(EditAnywhere)
458  bool bEnablePostProcessingEffects = true;
459 
460  /// Whether to change render target format to PF_A16B16G16R16, offering 16bit / channel
461  UPROPERTY(EditAnywhere)
462  bool bEnable16BitFormat = false;
463 
464 private:
465 
466  template <
467  typename SensorT,
468  typename CameraGBufferT>
469  static void SendGBuffer(
470  SensorT& Self,
471  CameraGBufferT& CameraGBuffer,
472  FGBufferRequest& GBufferData,
473  EGBufferTextureID TextureID)
474  {
475  using PixelType = typename std::conditional<
476  std::is_same<std::remove_reference_t<CameraGBufferT>, FCameraGBufferUint8>::value,
477  FColor,
478  FLinearColor>::type;
479  FIntPoint ViewSize;
480  TArray<PixelType> Pixels;
481  if (GBufferData.WaitForTextureTransfer(TextureID))
482  {
483  TRACE_CPUPROFILER_EVENT_SCOPE_STR("GBuffer Decode");
484  void* PixelData;
485  int32 SourcePitch;
486  FIntPoint SourceExtent;
487  GBufferData.MapTextureData(
488  TextureID,
489  PixelData,
490  SourcePitch,
491  SourceExtent);
492  auto Format = GBufferData.Readbacks[(size_t)TextureID]->GetFormat();
493  ViewSize = GBufferData.ViewRect.Size();
494  Pixels.AddUninitialized(ViewSize.X * ViewSize.Y);
495  FReadSurfaceDataFlags Flags = {};
496  Flags.SetLinearToGamma(true);
498  PixelData,
499  SourcePitch,
500  SourceExtent,
501  ViewSize,
502  Format,
503  Flags,
504  Pixels);
505  GBufferData.UnmapTextureData(TextureID);
506  }
507  else
508  {
509  ViewSize = GBufferData.ViewRect.Size();
510  Pixels.SetNum(ViewSize.X * ViewSize.Y);
511  for (auto& Pixel : Pixels)
512  Pixel = PixelType::Black;
513  }
514  auto GBufferStream = CameraGBuffer.GetDataStream(Self);
515  auto Buffer = GBufferStream.PopBufferFromPool();
516  Buffer.copy_from(
518  Pixels);
519  if (Buffer.empty()) {
520  return;
521  }
522  SCOPE_CYCLE_COUNTER(STAT_CarlaSensorStreamSend);
523  TRACE_CPUPROFILER_EVENT_SCOPE_STR("Stream Send");
524  GBufferStream.SerializeAndSend(
525  CameraGBuffer,
526  std::move(Buffer),
527  ViewSize.X,
528  ViewSize.Y,
529  Self.GetFOVAngle());
530  }
531 
532 protected:
533 
534  template <typename T>
535  void SendGBufferTexturesInternal(T& Self, FGBufferRequest& GBufferData)
536  {
537  for (size_t i = 0; i != FGBufferRequest::TextureCount; ++i)
538  {
539  if ((GBufferData.DesiredTexturesMask & (UINT64_C(1) << i)) == 0) {
540  continue;
541  }
542  auto& C = CameraGBuffers;
543  EGBufferTextureID ID = (EGBufferTextureID)i;
544  switch (ID)
545  {
546  case EGBufferTextureID::SceneColor:
547  SendGBuffer(Self, C.SceneColor, GBufferData, ID);
548  break;
549  case EGBufferTextureID::SceneDepth:
550  SendGBuffer(Self, C.SceneDepth, GBufferData, ID);
551  break;
552  case EGBufferTextureID::SceneStencil:
553  SendGBuffer(Self, C.SceneStencil, GBufferData, ID);
554  break;
555  case EGBufferTextureID::GBufferA:
556  SendGBuffer(Self, C.GBufferA, GBufferData, ID);
557  break;
558  case EGBufferTextureID::GBufferB:
559  SendGBuffer(Self, C.GBufferB, GBufferData, ID);
560  break;
561  case EGBufferTextureID::GBufferC:
562  SendGBuffer(Self, C.GBufferC, GBufferData, ID);
563  break;
564  case EGBufferTextureID::GBufferD:
565  SendGBuffer(Self, C.GBufferD, GBufferData, ID);
566  break;
567  case EGBufferTextureID::GBufferE:
568  SendGBuffer(Self, C.GBufferE, GBufferData, ID);
569  break;
570  case EGBufferTextureID::GBufferF:
571  SendGBuffer(Self, C.GBufferF, GBufferData, ID);
572  break;
573  case EGBufferTextureID::Velocity:
574  SendGBuffer(Self, C.Velocity, GBufferData, ID);
575  break;
576  case EGBufferTextureID::SSAO:
577  SendGBuffer(Self, C.SSAO, GBufferData, ID);
578  break;
579  case EGBufferTextureID::CustomDepth:
580  SendGBuffer(Self, C.CustomDepth, GBufferData, ID);
581  break;
582  case EGBufferTextureID::CustomStencil:
583  SendGBuffer(Self, C.CustomStencil, GBufferData, ID);
584  break;
585  default:
586  abort();
587  }
588  }
589  }
590 
591 };
FCameraGBufferUint8 GBufferF
FAsyncDataStream GetDataStream(const SensorT &Self)
Return the FDataStream associated with this sensor.
static bool WritePixelsToArray(UTextureRenderTarget2D &RenderTarget, TArray< FColor > &BitMap)
Copy the pixels in RenderTarget into BitMap.
Definition: PixelReader.cpp:83
void not_spawnable
Prevent this sensor to be spawned by users.
FCameraGBufferUint8 SceneDepth
FAsyncDataStreamTmpl< T > MakeAsyncDataStream(const SensorT &Sensor, double Timestamp)
Create a FAsyncDataStream object.
Definition: DataStream.h:40
typename detail::CompileTimeTypeMapImpl< sizeof...(Items), Items... >::template get< InKey > get
FCameraGBufferUint8 CustomStencil
FCameraGBufferUint8 SceneStencil
void SetDataStream(FDataStream InStream)
auto GetToken() const
Return the token that allows subscribing to this sensor&#39;s stream.
FCameraGBufferUint8 GBufferE
std::deque< std::shared_ptr< SimpleWaypoint > > Buffer
Utils for reading pixels from UTextureRenderTarget2D.
Definition: PixelReader.h:34
void DecodePixelsByFormat(void *PixelData, int32 SourcePitch, FIntPoint SourceExtent, FIntPoint DestinationExtent, EPixelFormat Format, FReadSurfaceDataFlags Flags, TArrayView< FLinearColor > Out)
Definition: ImageUtil.cpp:15
FTransform GetActorTransform() const
Dummy. Required for compatibility with other sensors only.
FCameraGBufferUint8 GBufferD
FCameraGBufferUint8 SSAO
FCameraGBufferUint8 GBufferA
void not_spawnable
Prevent this sensor to be spawned by users.
auto GetToken() const
Return the token that allows subscribing to this stream.
Definition: DataStream.h:52
virtual void SetUpSceneCaptureComponent(USceneCaptureComponent2D &SceneCapture)
FCameraGBufferUint8 SceneColor
A description of a Carla Actor with all its variation.
FTransform GetActorTransform() const
Dummy. Required for compatibility with other sensors only.
FAsyncDataStream GetDataStream(const SensorT &Self)
Return the FDataStream associated with this sensor.
FCameraGBufferUint8 CustomDepth
uint32 GetImageHeight() const
Base class for sensors using a USceneCaptureComponent2D for rendering the scene.
void SetDataStream(FDataStream InStream)
A streaming channel for sending sensor data to clients, supports sending data asynchronously.
FCameraGBufferUint8 GBufferC
FCameraGBufferUint8 Velocity
void WaitForRenderThreadToFinish()
Blocks until the render thread has finished all it&#39;s tasks.
Base class for the CARLA Game Mode.
void SetStream(FDataMultiStream InStream)
Replace the Stream associated with this sensor.
void SendGBufferTexturesInternal(T &Self, FGBufferRequest &GBufferData)
void SetStream(FDataMultiStream InStream)
Replace the Stream associated with this sensor.
static TFuture< bool > SavePixelsToDisk(UTextureRenderTarget2D &RenderTarget, const FString &FilePath)
Asynchronously save the pixels in RenderTarget to disk.
auto GetToken() const
Return the token that allows subscribing to this sensor&#39;s stream.
FCameraGBufferUint8 GBufferB