CARLA
CustomTerrainPhysicsComponent.h
Go to the documentation of this file.
1 // Copyright (c) 2022 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 
9 #include "Components/ActorComponent.h"
10 #include "Components/PrimitiveComponent.h"
11 #include "Engine/StaticMeshActor.h"
12 #include "Misc/ScopeLock.h"
13 
14 #include "Carla/Math/DVector.h"
16 #include "Engine/TextureRenderTarget2D.h"
18 #include "Engine/DataAsset.h"
19 #include "Async/Future.h"
20 #ifdef WITH_PYTORCH
21 THIRD_PARTY_INCLUDES_START
22 #include <carla/pytorch/pytorch.h>
23 THIRD_PARTY_INCLUDES_END
24 #endif
25 
26 #include <unordered_map>
27 #include <vector>
28 #include "Misc/ScopeLock.h"
29 #include <string>
30 
31 #include "CustomTerrainPhysicsComponent.generated.h"
32 
33 
34 UENUM(BlueprintType)
36 {
37  E256M = 0 UMETA(DisplayName = "256M"),
38  E512M = 1 UMETA(DisplayName = "512M"),
39  E1K = 2 UMETA(DisplayName = "1K"),
40  E2K = 3 UMETA(DisplayName = "2K"),
41 };
42 
43 UCLASS(BlueprintType)
45 {
46  GENERATED_BODY()
47 public:
48 
49  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = HeightMapDataAsset)
50  int SizeX = 0;
51  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category = HeightMapDataAsset)
52  int SizeY = 0;
53  UPROPERTY(BlueprintReadWrite, Category = HeightMapDataAsset)
54  TArray<float> HeightValues;
55 };
56 
57 struct FParticle
58 {
59  FDVector Position; // position in m
60  FVector Velocity;
61  float Radius = 0.02f;
62 };
63 
65 {
67  UHeightMapDataAsset* DataAsset, FDVector Size, FDVector Origin,
68  FDVector Tile0, float ScaleZ);
69  float GetHeight(FDVector Position) const; // get height at a given global 2d position
70  void Clear();
71 // private:
74  uint32_t Size_X;
75  uint32_t Size_Y;
76  float MinHeight = 0.0f;
77  float MaxHeight = 10.0f;
78  float Scale_Z = 1;
80  std::vector<float> Pixels;
81 };
82 
83 struct FDenseTile
84 {
85  FDenseTile();
86  ~FDenseTile();
87  FDenseTile(const FDenseTile& Origin);
88  FDenseTile(FDenseTile&& Origin);
89  FDenseTile& operator=(FDenseTile&& Origin);
90 
91  void InitializeTile(uint32_t TextureSize, float AffectedRadius, float ParticleSize, float Depth,
92  FDVector TileOrigin, FDVector TileEnd, const FString& SavePath, const FHeightMapData &HeightMap);
93  std::vector<FParticle*> GetParticlesInRadius(FDVector Position, float Radius);
94  void GetParticlesInRadius(FDVector Position, float Radius, std::vector<FParticle*> &ParticlesInRadius);
95  void GetParticlesInBox(const FOrientedBox& OBox, std::vector<FParticle*> &ParticlesInRadius);
96  void GetAllParticles(std::vector<FParticle*> &ParticlesInRadius);
97  void InitializeDataStructure();
98 
99  void UpdateLocalHeightmap();
100  std::vector<FParticle> Particles;
101  std::vector<float> ParticlesHeightMap;
102  std::vector<std::multiset<float,std::greater<float>>> ParticlesZOrdered;
103  bool bParticlesZOrderedInitialized = false;
105  FString SavePath;
106  bool bHeightmapNeedToUpdate = false;
107  uint32_t PartialHeightMapSize = 0;
108  uint32_t TileSize = 0;
109 };
110 
112 {
113 public:
114  friend struct FTilesWorker;
115 
116  FSparseHighDetailMap(float ParticleDiameter = 0.02f, float Depth = 0.4f)
117  : ParticleSize(ParticleDiameter), TerrainDepth(Depth) {};
118 
119  void Init( uint32 NewTextureSize, float NewAffectedRadius, float ParticleDiameter,
120  float Depth, float NewFloorHeight )
121  {
122  ParticleSize = ParticleDiameter;
123  TerrainDepth = Depth;
124  TextureSize = NewTextureSize;
125  AffectedRadius = NewAffectedRadius;
126  FloorHeight = NewFloorHeight;
127  UE_LOG(LogCarla, Warning,
128  TEXT("ParticleSize %f"), ParticleSize);
129  }
130 
131  inline float GetTileSize() const {
132  return TileSize;
133  }
134 
135  std::vector<FParticle*> GetParticlesInRadius(FDVector Position, float Radius);
136  std::vector<FParticle*> GetParticlesInTileRadius(FDVector Position, float Radius);
137  std::vector<FParticle*> GetParticlesInBox(const FOrientedBox& OBox);
138  std::vector<uint64_t> GetIntersectingTiles(const FOrientedBox& OBox);
139  std::vector<uint64_t> GetLoadedTilesInRange(FDVector Position, float Radius);
140 
141 
142  FDenseTile& GetTile(uint32_t Tile_X, uint32_t Tile_Y);
143  FDenseTile& GetTile(FDVector Position);
144  FDenseTile& GetTile(uint64_t TileId);
145 
146  FDenseTile& InitializeRegion(uint32_t Tile_X, uint32_t Tile_Y);
147  FDenseTile& InitializeRegion(uint64_t TileId);
148  FDenseTile& InitializeRegionInCache(uint64_t TileId);
149 
150  uint64_t GetTileId(uint32_t Tile_X, uint32_t Tile_Y);
151  uint64_t GetTileId(uint64_t TileId);
152  uint64_t GetTileId(FDVector Position);
153  FIntVector GetVectorTileId(FDVector Position);
154  FIntVector GetVectorTileId(uint64_t TileId);
155  FDVector GetTilePosition(uint64_t TileId);
156  FDVector GetTilePosition(uint32_t Tile_X, uint32_t Tile_Y);
157 
158  float GetHeight(FDVector Position) {
159  return Heightmap.GetHeight(Position);
160  }
161 
162  void InitializeMap(UHeightMapDataAsset* DataAsset,
163  FDVector Origin, FDVector MapSize, float Size, float ScaleZ);
164 
165  void UpdateHeightMap(UHeightMapDataAsset* DataAsset,
166  FDVector Origin, FDVector MapSize, float Size, float ScaleZ);
167 
168  void UpdateMaps(FDVector Position, float RadiusX, float RadiusY, float CacheRadiusX, float CacheRadiusY);
169 
170  void Update(FVector Position, float RadiusX, float RadiusY);
171 
172  void SaveMap();
173 
174  void Clear();
175 
176  void LockMutex()
177  {
178  Lock_Map.Lock();
179  }
180 
181  void UnLockMutex()
182  {
183  Lock_Map.Unlock();
184  }
185 
186  std::vector<uint64_t> GetTileIdInMap()
187  {
188  std::vector<uint64_t> Result;
189  for (auto& Iter : Map)
190  {
191  Result.emplace_back(Iter.first);
192  }
193  return Result;
194  }
195  std::vector<uint64_t> GetTileIdInCache()
196  {
197  std::vector<uint64_t> Result;
198  for (auto& Iter : CacheMap)
199  {
200  Result.emplace_back(Iter.first);
201  }
202  return Result;
203  }
204 
205  std::unordered_map<uint64_t, FDenseTile> Map;
206  std::unordered_map<uint64_t, FDenseTile> CacheMap;
207  FString SavePath;
208  FCriticalSection Lock_Particles;
209 private:
210  std::unordered_map<uint64_t, FDenseTile> TilesToWrite;
213  float TileSize = 1.f; // 1m per tile
215  float ParticleSize = 0.02f;
216  float TerrainDepth = 0.4f;
217  float FloorHeight = 0.0f;
218  uint32 TextureSize = 0;
219  float AffectedRadius = 0.0f;
221  FCriticalSection Lock_Map; // UE4 Mutex
222  FCriticalSection Lock_CacheMap; // UE4 Mutex
223  FCriticalSection Lock_GetTile;
224  FCriticalSection Lock_Position; // UE4 Mutex
225 
226 };
227 
228 USTRUCT(BlueprintType)
230 {
231  GENERATED_BODY()
232 
233  UPROPERTY(EditAnywhere, BlueprintReadWrite)
234  FVector Force;
235  UPROPERTY(EditAnywhere, BlueprintReadWrite)
236  FVector Location;
237 };
238 
239 UCLASS( ClassGroup=(Custom), meta=(BlueprintSpawnableComponent) )
240 class CARLA_API UCustomTerrainPhysicsComponent : public UActorComponent
241 {
242  GENERATED_BODY()
243  friend struct FTilesWorker;
244 public:
245 
246  UCustomTerrainPhysicsComponent();
247 
248  virtual void BeginPlay() override;
249  virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
250 
251  virtual void TickComponent(float DeltaTime,
252  ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction);
253 
254  // UFUNCTION(BlueprintCallable)
255  // TArray<FHitResult> SampleTerrainRayCast(const TArray<FVector> &Locations);
256 
257  UFUNCTION(BlueprintCallable)
258  void AddForces(const TArray<FForceAtLocation> &Forces);
259 
260  UFUNCTION(BlueprintCallable)
261  static void BuildLandscapeHeightMapDataAasset(ALandscapeProxy* Landscape,
262  int Resolution, FVector MapSize, FString AssetPath, FString AssetName);
263 
264  UFUNCTION(BlueprintCallable)
265  float GetHeightAtLocation(ALandscapeProxy * Landscape, FVector Location);
266 
267  UFUNCTION(BlueprintCallable)
268  TArray<FVector> GetParticlesInRadius(FVector Position, float Radius);
269 
270  UFUNCTION(BlueprintCallable)
271  TArray<FVector> GetParticlesInTileRadius(FVector Position, float Radius);
272 
273  UFUNCTION(BlueprintCallable)
274  FVector GetTileCenter(FVector Position);
275 
276  UFUNCTION(BlueprintCallable, Category="Tiles")
277  void UpdateMaps(FVector Position, float RadiusX, float RadiusY, float CacheRadiusX, float CacheRadiusY);
278 
279  UFUNCTION(BlueprintCallable, Category="Texture")
280  void InitTexture();
281 
282  UFUNCTION(BlueprintCallable, Category="Texture")
283  void UpdateTexture();
284 
285  UFUNCTION(BlueprintCallable, Category="Texture")
286  void UpdateLoadedTextureDataRegions();
287 
288  UPROPERTY(EditAnywhere, BlueprintReadWrite)
289  UHeightMapDataAsset* DataAsset;
290 
291  UFUNCTION(BlueprintCallable, Category="Texture")
292  void UpdateLargeTexture();
293 
294  UFUNCTION(BlueprintCallable, Category="Texture")
295  void UpdateLargeTextureData();
296 
297  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="MaterialParameters")
298  UTexture2D* TextureToUpdate;
299  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="MaterialParameters")
300  float MinDisplacement = -100;
301  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="MaterialParameters")
302  float MaxDisplacement = 100;
303 
304  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="MaterialParameters")
305  UTexture2D* LargeTextureToUpdate;
306 
307  UPROPERTY(EditAnywhere, BlueprintReadWrite, Category="MaterialParameters")
308  UMaterialParameterCollection* MPC;
309 
310  UPROPERTY(EditAnywhere, BlueprintReadWrite)
311  FString NeuralModelFile = "";
312 
313  UPROPERTY(EditAnywhere, BlueprintReadWrite)
314  FVector NextPositionToUpdate = FVector(0,0,0);
315 
316  FVector LastUpdatedPosition;
317  FVector CachePosition;
318 
319  FString SavePath;
320 
321  UPROPERTY(EditAnywhere, BlueprintReadWrite)
322  float ForceMulFactor = 1.0;
323  UPROPERTY(EditAnywhere, BlueprintReadWrite)
324  float ParticleForceMulFactor = 1.0;
325  UPROPERTY(EditAnywhere, BlueprintReadWrite)
326  int SoilType = 0;
327  UPROPERTY(EditAnywhere, BlueprintReadWrite)
328  bool bUseSoilType = false;
329  UPROPERTY(EditAnywhere)
330  bool NNVerbose = false;
331  UPROPERTY(EditAnywhere, BlueprintReadWrite)
332  bool bUseLocalFrame = false;
333 private:
334 
335  void RunNNPhysicsSimulation(
336  ACarlaWheeledVehicle *Vehicle, float DeltaTime);
337  // TArray<FParticle*> GetParticlesInRange(...);
338  void SetUpParticleArrays(std::vector<FParticle*>& ParticlesIn,
339  TArray<float>& ParticlePosOut,
340  TArray<float>& ParticleVelOut,
341  const FTransform &WheelTransform);
342  void SetUpWheelArrays(ACarlaWheeledVehicle *Vehicle, int WheelIdx,
343  TArray<float>& WheelPos,
344  TArray<float>& WheelOrientation,
345  TArray<float>& WheelLinearVelocity,
346  TArray<float>& WheelAngularVelocity);
347  void UpdateParticles(
348  std::vector<FParticle*> Particles, std::vector<float> Forces,
349  float DeltaTime, const FTransform& WheelTransform);
350  void ApplyForcesToVehicle(
351  ACarlaWheeledVehicle *Vehicle,
352  FVector ForceWheel0, FVector ForceWheel1, FVector ForceWheel2, FVector ForceWheel3,
353  FVector TorqueWheel0, FVector TorqueWheel1, FVector TorqueWheel2, FVector TorqueWheel3);
354  void ApplyMeanAccelerationToVehicle(
355  ACarlaWheeledVehicle *Vehicle,
356  FVector ForceWheel0, FVector ForceWheel1, FVector ForceWheel2, FVector ForceWheel3);
357  void ApplyAccelerationToVehicle(
358  ACarlaWheeledVehicle *Vehicle,
359  FVector ForceWheel0, FVector ForceWheel1, FVector ForceWheel2, FVector ForceWheel3);
360 
361  void ApplyForces();
362  void LimitParticlesPerWheel(std::vector<FParticle*> &Particles);
363  void DrawParticles(UWorld* World, std::vector<FParticle*>& Particles,
364  FLinearColor Color = FLinearColor(1.f, 0.f, 0.f));
365  void DrawParticlesArray(UWorld* World, TArray<float>& ParticlesArray,
366  FLinearColor Color = FLinearColor(1.f, 0.f, 0.f));
367  void DrawOrientedBox(UWorld* World, const TArray<FOrientedBox>& Boxes);
368  void DrawTiles(UWorld* World, const std::vector<uint64_t>& TilesIds, float Height = 0,
369  FLinearColor Color = FLinearColor(0.0,1.0,0.0,1.0));
370  void GenerateBenchmarkParticles(std::vector<FParticle>& BenchParticles,
371  std::vector<FParticle*> &ParticlesWheel0, std::vector<FParticle*> &ParticlesWheel1,
372  std::vector<FParticle*> &ParticlesWheel2, std::vector<FParticle*> &ParticlesWheel3,
373  FOrientedBox &BboxWheel0, FOrientedBox &BboxWheel1,
374  FOrientedBox &BboxWheel2, FOrientedBox &BboxWheel3);
375 
376  void UpdateParticlesDebug(std::vector<FParticle*> Particles);
377 
378  void OnLevelAddedToWorld(ULevel* InLevel, UWorld* InWorld);
379 
380  void UpdateTilesHeightMaps( const std::vector<FParticle*>& Particles);
381  void RemoveParticlesFromOrderedContainer(const std::vector<FParticle*>& Particles);
382  void AddParticlesToOrderedContainer(const std::vector<FParticle*>& Particles);
383  void FlagTilesToRedoOrderedContainer(const std::vector<FParticle*>& Particles);
384  void UpdateTilesHeightMapsInRadius(FDVector Position, uint32 Rad );
385 
386  void AddForceToSingleWheel(USkeletalMeshComponent* SkeletalMeshComponent,
387  FVector WheelPosition, FVector WheelNormalForce);
388 
389  UPROPERTY(EditAnywhere)
390  TArray<FForceAtLocation> ForcesToApply;
391  UPROPERTY(EditAnywhere)
392  UPrimitiveComponent* RootComponent;
393  UPROPERTY(EditAnywhere)
394  float RayCastRange = 10.0f;
395 
396 public:
397  UPROPERTY(EditAnywhere)
398  FVector WorldSize = FVector(200000,200000,0);
399  UPROPERTY(EditAnywhere)
400  bool DrawDebugInfo = true;
401  UPROPERTY(EditAnywhere)
402  bool bUpdateParticles = false;
403  // Radius of the data loaded in memory
404  UPROPERTY(EditAnywhere, Category="Tiles")
405  FVector TileRadius = FVector( 100, 100, 0 );
406  // Radius of the data loaded in memory
407  UPROPERTY(EditAnywhere, Category="Tiles")
408  FVector CacheRadius = FVector( 50, 50, 0 );
409  UPROPERTY(EditAnywhere, Category="Tiles")
410  bool bDrawLoadedTiles = false;
411  UPROPERTY(EditAnywhere, Category="Tiles")
412  int32 TileSize = 1;
413  UPROPERTY(EditAnywhere, Category="Tiles")
414  bool bRemoveLandscapeColliders = false;
415 private:
416  // TimeToTriggerCacheReload In seconds
417  UPROPERTY(EditAnywhere, Category="Tiles")
418  float TimeToTriggerCacheReload = 20.0f;
419  // TimeToTriggerLoadTiles in MS
420  UPROPERTY(EditAnywhere, Category="Tiles")
421  float TimeToTriggerLoadTiles = 1.0f;
422  UPROPERTY(EditAnywhere, Category="Tiles")
423  float TimeToTriggerUnLoadTiles = 5.0f;
424  // Radius of the data collected by the texture in METERS
425  UPROPERTY(EditAnywhere, Category="MaterialParameters")
426  float TextureRadius = 4.0f;
427  // Radius of the data collected by the texture in METERS
428  UPROPERTY(EditAnywhere, Category="MaterialParameters")
429  float LargeTextureRadius = 50.0f;
430  // Scalar Factor of deformation effect applied in the landscape
431  UPROPERTY(EditAnywhere, Category="MaterialParameters")
432  float EffectMultiplayer = 10.0f;
433 
434  UPROPERTY(EditAnywhere, Category="MaterialParameters")
435  TEnumAsByte<EDefResolutionType> ChosenRes = EDefResolutionType::E1K;
436  UPROPERTY(EditAnywhere, Category="MaterialParameters")
437  TMap<TEnumAsByte<EDefResolutionType>, UTexture2D*> TexturesRes;
438 
439  bool bVisualization = false;
440 
441  UPROPERTY(EditAnywhere, Category="DeformationMesh")
442  bool bUseDeformationPlane = false;
443  UPROPERTY(EditAnywhere, Category="DeformationMesh")
444  UStaticMesh* DeformationPlaneMesh = nullptr;
445  UPROPERTY(EditAnywhere, Category="DeformationMesh")
446  UMaterialInstance* DeformationPlaneMaterial = nullptr;
447  UPROPERTY(VisibleAnywhere, Category="DeformationMesh")
448  AStaticMeshActor* DeformationPlaneActor = nullptr;
449 
450  UPROPERTY()
451  UMaterialParameterCollectionInstance* MPCInstance;
452 
453  UPROPERTY(EditAnywhere, Category="Forces")
454  float NormalForceIntensity = 100;
455 
456  UPROPERTY(EditAnywhere)
457  float SearchRadius = 100;
458  UPROPERTY(EditAnywhere)
459  float ParticleDiameter = 2;
460  UPROPERTY(EditAnywhere)
461  float TerrainDepth = 40;
462  UPROPERTY(EditAnywhere)
463  AActor *FloorActor = nullptr;
464  UPROPERTY(EditAnywhere)
465  bool bUseDynamicModel = false;
466  UPROPERTY(EditAnywhere)
467  bool bUseCUDAModel = false;
468 
469  UPROPERTY(EditAnywhere)
470  float TireRadius = 33.0229f;
471  UPROPERTY(EditAnywhere)
472  float TireWidth = 21.21f;
473  UPROPERTY(EditAnywhere)
474  float BoxSearchForwardDistance = 114.39f;
475  UPROPERTY(EditAnywhere)
476  float BoxSearchLateralDistance = 31.815f;
477  UPROPERTY(EditAnywhere)
478  float BoxSearchDepthDistance = 20.f;
479  UPROPERTY(EditAnywhere)
480  bool bDisableVehicleGravity = false;
481  UPROPERTY(EditAnywhere)
482  float MaxForceMagnitude = 1000000.f;
483  UPROPERTY(EditAnywhere)
484  float FloorHeight = 0.f;
485  UPROPERTY(EditAnywhere)
486  bool bUseImpulse = false;
487  UPROPERTY(EditAnywhere)
488  bool bUseMeanAcceleration = false;
489  UPROPERTY(EditAnywhere)
490  bool bShowForces = true;
491  UPROPERTY(EditAnywhere)
492  float MinHeight = 0;
493  UPROPERTY(EditAnywhere)
494  float MaxHeight = 10;
495  UPROPERTY(EditAnywhere)
496  FVector Tile0Origin;
497  UPROPERTY(EditAnywhere)
498  bool bDrawHeightMap = false;
499  UPROPERTY(EditAnywhere)
500  FVector DrawStart = FVector(0);
501  UPROPERTY(EditAnywhere)
502  FVector DrawEnd = FVector(1000, 1000, 0);
503  UPROPERTY(EditAnywhere)
504  FVector DrawInterval = FVector(100,100,0);
505  UPROPERTY(EditAnywhere)
506  int CUDADevice = 0;
507  UPROPERTY(EditAnywhere)
508  FVector HeightMapScaleFactor = FVector(1, 1, 1);
509  UPROPERTY(EditAnywhere)
510  FVector HeightMapOffset = FVector(0, 0, 0);
511  UPROPERTY(EditAnywhere)
512  bool bBenchMark = false;
513  UPROPERTY(EditAnywhere)
514  int MaxParticlesPerWheel = 6000;
515 
516  UPROPERTY(EditAnywhere)
517  FVector Radius = FVector(10,10,10);
518 
519  UPROPERTY(VisibleAnywhere)
520  FIntVector CurrentLargeMapTileId = FIntVector(-1,-1,0);
521  UPROPERTY(VisibleAnywhere)
522  ALargeMapManager* LargeMapManager = nullptr;
523 
524  TArray<ACarlaWheeledVehicle*> Vehicles;
525  FSparseHighDetailMap SparseMap;
526  TArray<uint8> Data;
527  TArray<uint8> LargeData;
528  #ifdef WITH_PYTORCH
529  carla::learning::NeuralModel TerramechanicsModel;
530  #endif
531 
532  TFuture<bool> IterationCompleted;
533 
534  class FRunnableThread* Thread;
535  struct FTilesWorker* TilesWorker;
536 };
537 
538 struct FTilesWorker : public FRunnable
539 {
540  FTilesWorker(class UCustomTerrainPhysicsComponent* TerrainComp, FVector NewPosition, float NewRadiusX, float NewRadiusY );
541 
542  virtual ~FTilesWorker() override;
543 
544  virtual uint32 Run() override;
545 
546  class UCustomTerrainPhysicsComponent* CustomTerrainComp;
547  FVector Position;
548 
549  double RadiusX;
550  double RadiusY;
551 
552  volatile bool bShouldContinue = true;
553 };
float GetHeight(FDVector Position) const
sensor::data::Color Color
void InitializeHeightmap(UHeightMapDataAsset *DataAsset, FDVector Size, FDVector Origin, FDVector Tile0, float ScaleZ)
std::vector< std::multiset< float, std::greater< float > > > ParticlesZOrdered
float GetHeight(FDVector Position)
std::unordered_map< uint64_t, FDenseTile > Map
std::vector< uint64_t > GetTileIdInCache()
FSparseHighDetailMap(float ParticleDiameter=0.02f, float Depth=0.4f)
geom::Location Location
Definition: rpc/Location.h:14
void Init(uint32 NewTextureSize, float NewAffectedRadius, float ParticleDiameter, float Depth, float NewFloorHeight)
std::unordered_map< uint64_t, FDenseTile > TilesToWrite
std::vector< float > ParticlesHeightMap
std::unordered_map< uint64_t, FDenseTile > CacheMap
std::vector< FParticle > Particles
class UCustomTerrainPhysicsComponent * CustomTerrainComp
std::vector< float > Pixels
std::vector< uint64_t > GetTileIdInMap()
Base class for CARLA wheeled vehicles.