10 #include "Runtime/Core/Public/Async/ParallelFor.h" 11 #include "Engine/CollisionProfile.h" 12 #include "Engine/StaticMeshActor.h" 13 #include "StaticMeshResources.h" 14 #include "CollisionQueryParams.h" 20 #include "HAL/PlatformFilemanager.h" 21 #include "HAL/RunnableThread.h" 22 #include "Misc/Paths.h" 23 #include "Engine/World.h" 24 #include "Math/UnrealMathUtility.h" 25 #include "Engine/World.h" 26 #include "Landscape.h" 27 #include "LandscapeHeightfieldCollisionComponent.h" 28 #include "LandscapeComponent.h" 30 #include "RHICommandList.h" 31 #include "TextureResource.h" 32 #include "Rendering/Texture2DResource.h" 33 #include "GenericPlatform/GenericPlatformProcess.h" 34 #include "Materials/MaterialParameterCollection.h" 35 #include "Materials/MaterialParameterCollectionInstance.h" 36 #include "Materials/MaterialInterface.h" 37 #include "Materials/MaterialInstance.h" 40 #include "Components/SkinnedMeshComponent.h" 41 #include "GenericPlatform/GenericPlatformFile.h" 42 #include "Async/Async.h" 43 #include "Async/Future.h" 44 #include "LandscapeProxy.h" 48 #include "HAL/PlatformFilemanager.h" 49 #include "HAL/RunnableThread.h" 50 #include "Misc/Paths.h" 51 #include "Engine/World.h" 52 #include "Math/UnrealMathUtility.h" 53 #include "GenericPlatform/GenericPlatformFile.h" 54 #include "Engine/Texture2D.h" 55 #include "Engine/Texture.h" 56 #include "Rendering/Texture2DResource.h" 57 #include "Engine/TextureRenderTarget2D.h" 58 #include "Components/PrimitiveComponent.h" 59 #include "DrawDebugHelpers.h" 60 #include "Kismet/KismetSystemLibrary.h" 61 #include "CommandLine.h" 62 #include "Components/LineBatchComponent.h" 63 #include "Math/OrientedBox.h" 64 #include "Misc/DateTime.h" 65 #include "EngineUtils.h" 83 std::string
_filesBaseFolder = std::string(getenv(
"USERPROFILE")) +
"/carlaCache/";
90 return MToCM * FVector(In.X, -In.Y, In.Z);
95 return FVector(In.X, -In.Y, In.Z);
100 return CMToM*FVector(In.X, -In.Y, In.Z);
105 return FVector(In.X, -In.Y, In.Z);
143 ParticlesHeightMap.clear();
144 TilePosition =
FDVector(0.0,0.0,0.0);
145 SavePath = FString(
"NotValidPath");
146 bHeightmapNeedToUpdate =
false;
151 ParticlesHeightMap.clear();
152 ParticlesZOrdered.clear();
153 TilePosition =
FDVector(0.0,0.0,0.0);
154 SavePath = FString(
"NotValidPath");
155 bHeightmapNeedToUpdate =
false;
161 bHeightmapNeedToUpdate =
false;
168 TilePosition = Origin.TilePosition;
169 SavePath = Origin.SavePath;
170 bHeightmapNeedToUpdate =
false;
171 Particles = std::move(Origin.Particles);
172 ParticlesHeightMap = std::move(Origin.ParticlesHeightMap);
173 ParticlesZOrdered = std::move(Origin.ParticlesZOrdered);
179 SavePath = Origin.SavePath;
180 bHeightmapNeedToUpdate =
false;
181 Particles = std::move(Origin.Particles);
182 ParticlesHeightMap = std::move(Origin.ParticlesHeightMap);
183 ParticlesZOrdered = std::move(Origin.ParticlesZOrdered);
192 TileSize = (TileEnd.
X - TileOrigin.
X );
193 PartialHeightMapSize = TileSize * TextureSize / (2*AffectedRadius);
194 std::string FileName = std::string(TCHAR_TO_UTF8(*( SavePath + TileOrigin.
ToString() +
".tile" ) ) );
197 if( FPaths::FileExists(FString(FileName.c_str())) )
200 TRACE_CPUPROFILER_EVENT_SCOPE(DenseTile::InitializeTile::Read);
201 std::ifstream ReadStream(FileName);
202 FVector VectorToRead;
204 TilePosition =
FDVector(VectorToRead);
205 ReadStdVector<FParticle> (ReadStream, Particles);
210 TRACE_CPUPROFILER_EVENT_SCOPE(DenseTile::InitializeTile::Create);
212 TilePosition = TileOrigin;
213 uint32_t NumParticles_X = (TileEnd.
X - TileOrigin.
X) / ParticleSize;
214 uint32_t NumParticles_Y = FMath::Abs(TileEnd.
Y - TileOrigin.
Y) / ParticleSize;
215 uint32_t NumParticles_Z = (Depth) / ParticleSize;
216 Particles = std::vector<FParticle>(NumParticles_X*NumParticles_Y*NumParticles_Z);
221 for(uint32_t i = 0; i < NumParticles_X; i++)
223 for(uint32_t j = 0; j < NumParticles_Y; j++)
225 FDVector ParticleLocalPosition =
FDVector(i*ParticleSize, j*ParticleSize, 0.0f);
226 FDVector ParticlePosition = TileOrigin + ParticleLocalPosition;
227 float Height = HeightMap.
GetHeight(ParticlePosition);
228 for(uint32_t k = 0; k < NumParticles_Z; k++)
230 ParticlePosition.
Z = TileOrigin.
Z + Height - k*ParticleSize;
231 Particles[k*NumParticles_X*NumParticles_Y + j*NumParticles_X + i] =
232 {ParticlePosition, FVector(0), ParticleSize/2.f};
240 ParticlesZOrdered.resize( PartialHeightMapSize*PartialHeightMapSize );
242 for(
float& Height : ParticlesHeightMap)
247 bParticlesZOrderedInitialized =
false;
248 bHeightmapNeedToUpdate =
true;
254 TRACE_CPUPROFILER_EVENT_SCOPE(DenseTile::InitializeTile::ParticlesZOrdered);
255 ParticlesHeightMap.clear();
256 ParticlesHeightMap.resize( PartialHeightMapSize*PartialHeightMapSize );
257 float InverseTileSize = 1.f/TileSize;
258 float Transformation = InverseTileSize * PartialHeightMapSize;
260 for (
size_t i = 0; i < Particles.size(); i++)
265 FIntVector HeightMapCoords = FIntVector(
266 ParticleLocalPosition.
X * Transformation,
267 ParticleLocalPosition.
Y * Transformation, 0);
269 uint32_t Index = HeightMapCoords.Y * PartialHeightMapSize + HeightMapCoords.X;
271 if(Index < ParticlesZOrdered.size() ){
272 ParticlesZOrdered[Index].insert(P.
Position.
Z);
277 bParticlesZOrderedInitialized =
true;
278 bHeightmapNeedToUpdate =
true;
287 if((particle.Position - Position).SizeSquared() < Radius*Radius)
289 ParticlesInRadius.emplace_back(&particle);
297 std::vector<FParticle*> ParticlesInRadius;
300 if((particle.Position - Position).SizeSquared() < Radius*Radius)
302 ParticlesInRadius.emplace_back(&particle);
305 return ParticlesInRadius;
309 const FOrientedBox& OBox, std::vector<FParticle*> &ParticlesInRadius)
314 FVector PToCenter =
SIToUEFrame(Particle.Position.ToFVector()) - OBox.Center;
315 if((FMath::Abs(FVector::DotProduct(PToCenter, OBox.AxisX)) < OBox.ExtentX) &&
316 (FMath::Abs(FVector::DotProduct(PToCenter, OBox.AxisY)) < OBox.ExtentY) &&
317 (FMath::Abs(FVector::DotProduct(PToCenter, OBox.AxisZ)) < OBox.ExtentZ))
319 ParticlesInRadius.emplace_back(&Particle);
328 ParticlesInRadius.emplace_back(&Particle);
334 if( bHeightmapNeedToUpdate && bParticlesZOrderedInitialized ){
336 for( uint32_t i = 0; i < ParticlesHeightMap.size() ; ++i ){
337 if( ParticlesZOrdered.size() == ParticlesHeightMap.size() ){
338 float Value = * ( ParticlesZOrdered[i].begin() );
339 ParticlesHeightMap[i] = Value;
342 bHeightmapNeedToUpdate =
false;
353 uint64_t TileId = GetTileId(Position);
354 uint32_t Tile_X = (uint32_t)(TileId >> 32);
355 uint32_t Tile_Y = (uint32_t)(TileId & (uint32_t)(~0));
359 std::vector<FParticle*> ParticlesInRadius;
361 GetTile(Tile_X-1, Tile_Y-1).GetParticlesInRadius(Position, Radius, ParticlesInRadius);
362 GetTile(Tile_X, Tile_Y-1).GetParticlesInRadius(Position, Radius, ParticlesInRadius);
363 GetTile(Tile_X+1, Tile_Y-1).GetParticlesInRadius(Position, Radius, ParticlesInRadius);
364 GetTile(Tile_X-1, Tile_Y).GetParticlesInRadius(Position, Radius, ParticlesInRadius);
365 GetTile(Tile_X, Tile_Y).GetParticlesInRadius(Position, Radius, ParticlesInRadius);
366 GetTile(Tile_X+1, Tile_Y).GetParticlesInRadius(Position, Radius, ParticlesInRadius);
367 GetTile(Tile_X-1, Tile_Y+1).GetParticlesInRadius(Position, Radius, ParticlesInRadius);
368 GetTile(Tile_X, Tile_Y+1).GetParticlesInRadius(Position, Radius, ParticlesInRadius);
369 GetTile(Tile_X+1, Tile_Y+1).GetParticlesInRadius(Position, Radius, ParticlesInRadius);
371 return ParticlesInRadius;
379 uint64_t TileId = GetTileId(Position);
380 uint32_t Tile_X = (uint32_t)(TileId >> 32);
381 uint32_t Tile_Y = (uint32_t)(TileId & (uint32_t)(~0));
383 uint32_t RadiusInTiles = (Radius/TileSize);
384 uint32_t MinX,MinY,MaxX,MaxY = 0;
386 if( Tile_X < RadiusInTiles){
389 MinX = Tile_X - RadiusInTiles;
392 if( Tile_Y < RadiusInTiles){
395 MinY = Tile_Y - RadiusInTiles;
398 if( ((Extension.X) / TileSize - RadiusInTiles) < Tile_X ){
399 MaxX = (Extension.X) / TileSize;
401 MaxX = Tile_X + RadiusInTiles;
404 if( ((-Extension.Y) / TileSize) - RadiusInTiles < Tile_Y ){
405 MaxY = (-Extension.Y) / TileSize;
407 MaxY = Tile_Y + RadiusInTiles;
422 std::vector<FParticle*> ParticlesInRadius;
423 for( uint32_t X = MinX; X <= MaxX; ++X )
425 for( uint32_t Y = MinY; Y <= MaxY; ++Y )
427 uint64_t CurrentTileId = GetTileId(X,Y);
428 if( Map.count(CurrentTileId) )
430 GetTile(X, Y).GetParticlesInRadius(Position, Radius, ParticlesInRadius);
434 return ParticlesInRadius;
441 std::vector<uint64_t> TilesToCheck = GetIntersectingTiles(OBox);
443 std::vector<FParticle*> ParticlesInRadius;
444 for(uint64_t TileId : TilesToCheck)
446 GetTile(TileId).GetParticlesInBox(OBox, ParticlesInRadius);
448 return ParticlesInRadius;
452 const FOrientedBox& OBox)
455 std::vector<uint64_t> IntersectingTiles;
459 float ExtentXSqr = ExtentX*ExtentX;
462 float ExtentYSqr = ExtentY*ExtentY;
465 uint64_t CenterTileId = GetTileId(BoxCenter);
466 uint32_t CenterTile_X = (uint32_t)(CenterTileId >> 32);
467 uint32_t CenterTile_Y = (uint32_t)(CenterTileId & (uint32_t)(~0));
468 uint32_t TileRange = 1;
469 IntersectingTiles.emplace_back(CenterTileId);
470 FVector2D BoxVert0 = FVector2D(BoxCenter - AxisX*ExtentX - AxisY*ExtentY);
471 FVector2D BoxVert1 = FVector2D(BoxCenter + AxisX*ExtentX - AxisY*ExtentY);
472 FVector2D BoxVert2 = FVector2D(BoxCenter + AxisX*ExtentX + AxisY*ExtentY);
473 FVector2D BoxVert3 = FVector2D(BoxCenter - AxisX*ExtentX + AxisY*ExtentY);
478 FVector2D V1, V2, V3, V4;
479 std::vector<FVector2D> ComputeNormals()
const 481 FVector2D V12 = (V2 - V1).GetSafeNormal();
482 FVector2D V23 = (V3 - V2).GetSafeNormal();
483 return {FVector2D(-V12.Y, V12.X), FVector2D(-V23.Y, V23.X)};
486 auto SATtest = [&](
const FVector2D& Axis,
const F2DRectangle &
Shape,
487 float &MinAlong,
float &MaxAlong)
489 for (
const FVector2D& Vert : {Shape.V1, Shape.V2, Shape.V3, Shape.V4})
491 float DotVal = FVector2D::DotProduct(Vert, Axis);
492 if( DotVal < MinAlong )
494 if( DotVal > MaxAlong )
498 auto IsBetweenOrdered = [&](
float Val,
float LowerBound,
float UpperBound ) ->
bool 500 return LowerBound <= Val && Val <= UpperBound ;
502 auto Overlaps = [&](
float Min1,
float Max1,
float Min2,
float Max2 ) ->
bool 504 return IsBetweenOrdered( Min2, Min1, Max1 ) || IsBetweenOrdered( Min1, Min2, Max2 ) ;
506 auto RectangleIntersect = [&](
507 const F2DRectangle& Rectangle1,
508 const F2DRectangle& Rectangle2) ->
bool 510 for (
const FVector2D& Normal : Rectangle1.ComputeNormals())
512 constexpr
float LargeNumber = 10000000;
513 float Shape1Min = LargeNumber, Shape1Max = -LargeNumber;
514 float Shape2Min = LargeNumber, Shape2Max = -LargeNumber;
515 SATtest(Normal, Rectangle1, Shape1Min, Shape1Max);
516 SATtest(Normal, Rectangle2, Shape2Min, Shape2Max);
517 if (!Overlaps(Shape1Min, Shape1Max, Shape2Min, Shape2Max))
522 for (
const FVector2D& Normal : Rectangle2.ComputeNormals())
524 constexpr
float LargeNumber = 10000000;
525 float Shape1Min = LargeNumber, Shape1Max = -LargeNumber;
526 float Shape2Min = LargeNumber, Shape2Max = -LargeNumber;
527 SATtest(Normal, Rectangle1, Shape1Min, Shape1Max);
528 SATtest(Normal, Rectangle2, Shape2Min, Shape2Max);
529 if (!Overlaps(Shape1Min, Shape1Max, Shape2Min, Shape2Max))
537 std::vector<std::pair<uint32_t, uint32_t>> TilesToCheck = {
538 {CenterTile_X-1, CenterTile_Y-1}, {CenterTile_X, CenterTile_Y-1},
539 {CenterTile_X+1, CenterTile_Y-1}, {CenterTile_X-1, CenterTile_Y},
540 {CenterTile_X+1, CenterTile_Y}, {CenterTile_X-1, CenterTile_Y+1},
541 {CenterTile_X, CenterTile_Y+1}, {CenterTile_X+1, CenterTile_Y+1}};
542 for (
auto& TileIdPair : TilesToCheck)
544 uint32_t &Tile_X = TileIdPair.first;
545 uint32_t &Tile_Y = TileIdPair.second;
546 FVector2D V1 = FVector2D(GetTilePosition(Tile_X, Tile_Y).ToFVector());
547 FVector2D V2 = FVector2D(GetTilePosition(Tile_X+1, Tile_Y).ToFVector());
548 FVector2D V3 = FVector2D(GetTilePosition(Tile_X+1, Tile_Y+1).ToFVector());
549 FVector2D V4 = FVector2D(GetTilePosition(Tile_X, Tile_Y+1).ToFVector());
550 if (RectangleIntersect(
551 F2DRectangle{BoxVert0,BoxVert1,BoxVert2,BoxVert3},
552 F2DRectangle{V1,V2,V3,V4}))
554 IntersectingTiles.emplace_back(GetTileId(Tile_X, Tile_Y));
558 return IntersectingTiles;
565 uint64_t TileId = GetTileId(Position);
566 uint32_t Tile_X = (uint32_t)(TileId >> 32);
567 uint32_t Tile_Y = (uint32_t)(TileId & (uint32_t)(~0));
569 uint32_t RadiusInTiles = (Radius/TileSize);
570 uint32_t MinX = 0,MinY = 0,MaxX = 0,MaxY = 0;
572 TRACE_CPUPROFILER_EVENT_SCOPE(Comparisons);
573 if( Tile_X < RadiusInTiles){
576 MinX = Tile_X - RadiusInTiles;
579 if( Tile_Y < RadiusInTiles){
582 MinY = Tile_Y - RadiusInTiles;
585 MaxX = Tile_X + RadiusInTiles;
586 MaxY = Tile_Y + RadiusInTiles;
589 std::vector<uint64_t> LoadedTiles;
591 TRACE_CPUPROFILER_EVENT_SCOPE(Looping);
592 for( uint32_t X = MinX; X < MaxX; ++X )
594 for( uint32_t Y = MinY; Y < MaxY; ++Y )
596 uint64_t CurrentTileId = GetTileId(X,Y);
597 if( Map.find(CurrentTileId) != Map.end() )
599 LoadedTiles.emplace_back(CurrentTileId);
609 return (uint64_t) Tile_X << 32 | Tile_Y;
614 uint32_t Tile_X =
static_cast<uint32_t
>((Position.
X -
Tile0Position.
X) / TileSize);
615 uint32_t Tile_Y =
static_cast<uint32_t
>((Position.
Y -
Tile0Position.
Y) / TileSize);
617 return GetTileId(Tile_X, Tile_Y);
622 uint32_t Tile_X = (uint32_t)(TileId >> 32);
623 uint32_t Tile_Y = (uint32_t)(TileId & (uint32_t)(~0));
624 return GetTilePosition(Tile_X, Tile_Y);
636 uint64_t TileId = GetTileId(Position);
637 return GetTile(TileId);
642 uint64_t TileId = GetTileId(Tile_X, Tile_Y);
643 return GetTile(TileId);
647 auto Iterator = Map.find(TileId);
648 if (Iterator == Map.end())
653 bool bGotCacheLock = Lock_CacheMap.TryLock();
656 auto CacheIterator = CacheMap.find(TileId);
657 if (CacheIterator != CacheMap.end())
659 Map.emplace(TileId, std::move(CacheIterator->second));
660 CacheMap.erase(CacheIterator);
661 Lock_CacheMap.Unlock();
662 Lock_GetTile.Unlock();
665 Lock_CacheMap.Unlock();
668 Lock_GetTile.Unlock();
669 return InitializeRegion(TileId);
671 return Iterator->second;
676 uint32_t Tile_X =
static_cast<uint32_t
>((Position.
X -
Tile0Position.
X) / TileSize);
677 uint32_t Tile_Y =
static_cast<uint32_t
>((Position.
Y -
Tile0Position.
Y) / TileSize);
678 return FIntVector(Tile_X, Tile_Y, 0);
682 uint32_t Tile_X = (uint32_t)(TileId >> 32);
683 uint32_t Tile_Y = (uint32_t)(TileId & (uint32_t)(~0));
684 return FIntVector(Tile_X, Tile_Y, 0);
689 uint64_t TileId = GetTileId(Tile_X, Tile_Y);
690 return InitializeRegion(TileId);
695 FDVector TileCenter = GetTilePosition(TileId);
700 TextureSize, AffectedRadius,
701 ParticleSize, TerrainDepth,
702 TileCenter, TileCenter +
FDVector(TileSize, TileSize, 0.f),
703 SavePath, Heightmap);
709 FDVector TileCenter = GetTilePosition(TileId);
715 TextureSize, AffectedRadius,
716 ParticleSize, TerrainDepth,
717 TileCenter, TileCenter +
FDVector(TileSize, TileSize, 0.f),
718 SavePath, Heightmap);
719 Lock_CacheMap.Unlock();
729 Heightmap.InitializeHeightmap(
732 UE_LOG(LogCarla, Log,
733 TEXT(
"Sparse Map initialized"));
734 UE_LOG(LogCarla, Log,
735 TEXT(
"Map Extension %f %f %f"), MapSize.
X, MapSize.
Y, MapSize.
Z );
743 Heightmap.InitializeHeightmap(
744 DataAsset, Extension, Origin,
746 UE_LOG(LogCarla, Log,
747 TEXT(
"Height map updated"));
756 FDVector Position,
float RadiusX,
float RadiusY,
float CacheRadiusX,
float CacheRadiusY)
759 double MinX = Position.
X - RadiusX;
760 double MinY = Position.
Y - RadiusY;
761 double MaxX = Position.
X + RadiusX;
762 double MaxY = Position.
Y + RadiusY;
764 FIntVector MinVector = GetVectorTileId(
FDVector(MinX, MinY, 0));
765 FIntVector MaxVector = GetVectorTileId(
FDVector(MaxX, MaxY, 0));
767 FIntVector CacheMinVector = GetVectorTileId(
768 FDVector(Position.
X - CacheRadiusX, Position.
Y - CacheRadiusY, 0));
769 FIntVector CacheMaxVector = GetVectorTileId(
770 FDVector(Position.
X + CacheRadiusX, Position.
Y + CacheRadiusY, 0));
772 auto IsInCacheRange = [&](int32_t Tile_X, int32_t Tile_Y) ->
bool 774 return Tile_X >= CacheMinVector.X && Tile_X <= CacheMaxVector.X &&
775 Tile_Y >= CacheMinVector.Y && Tile_Y <= CacheMaxVector.Y;
777 auto IsInMapRange = [&](int32_t Tile_X, int32_t Tile_Y) ->
bool 779 return Tile_X >= MinVector.X && Tile_X <= MaxVector.X &&
780 Tile_Y >= MinVector.Y && Tile_Y <= MaxVector.Y;
783 FScopeLock ScopeLock(&Lock_Map);
784 FScopeLock ScopeCacheLock(&Lock_CacheMap);
785 TRACE_CPUPROFILER_EVENT_SCOPE(UpdateMap);
787 std::vector<uint64_t> TilesToErase;
788 for (
auto &Element : Map)
790 uint64_t TileId = Element.first;
791 FIntVector VectorTileId = GetVectorTileId(TileId);
792 if (!IsInMapRange(VectorTileId.X, VectorTileId.Y))
794 CacheMap.emplace(TileId, std::move(Element.second));
795 TilesToErase.emplace_back(TileId);
798 for (uint64_t TileId : TilesToErase)
804 FScopeLock ScopeCacheLock(&Lock_CacheMap);
805 TRACE_CPUPROFILER_EVENT_SCOPE(UpdateCache);
808 std::vector<uint64_t> TilesToErase;
810 TRACE_CPUPROFILER_EVENT_SCOPE(GetTilesToErase);
811 for (
auto &Element : CacheMap)
813 uint64_t TileId = Element.first;
814 FIntVector VectorTileId = GetVectorTileId(TileId);
815 if (!IsInCacheRange(VectorTileId.X, VectorTileId.Y))
817 TilesToErase.emplace_back(TileId);
823 TRACE_CPUPROFILER_EVENT_SCOPE(EraseTiles);
824 ParallelFor(TilesToErase.size(), [&](int32 Idx)
826 TRACE_CPUPROFILER_EVENT_SCOPE(SaveData);
827 uint64_t TileId = TilesToErase[Idx];
828 auto& Tile = CacheMap[TileId];
829 std::string FileToSavePath = std::string(
830 TCHAR_TO_UTF8(*( SavePath + Tile.TilePosition.ToString() +
".tile")));
831 std::ofstream OutputStream(FileToSavePath.c_str());
832 WriteFVector(OutputStream, Tile.TilePosition.ToFVector());
833 WriteStdVector<FParticle> (OutputStream, Tile.Particles);
834 OutputStream.close();
837 TRACE_CPUPROFILER_EVENT_SCOPE(CacheMap.erase);
838 for (uint64_t TileId : TilesToErase)
840 CacheMap.erase(TileId);
850 FVector PositionTranslated;
851 PositionTranslated.X = ( Position.X * 0.01 ) + (Extension.X * 0.5f);
852 PositionTranslated.Y = (-Position.Y * 0.01 ) + ( (-Extension.Y) * 0.5f);
853 PositionTranslated.Z = ( Position.Z * 0.01 ) + (Extension.Z * 0.5f);
854 PositionToUpdate = PositionTranslated;
856 double MinX =
std::min( std::max( PositionTranslated.X - RadiusX, 0.0f) , static_cast<float>(Extension.X - 1.0f) );
857 double MinY =
std::min( std::max( PositionTranslated.Y - RadiusY, 0.0f) , static_cast<float>(-Extension.Y + 1.0f) );
858 double MaxX =
std::min( std::max( PositionTranslated.X + RadiusX, 0.0f) , static_cast<float>(Extension.X - 1.0f) );
859 double MaxY =
std::min( std::max( PositionTranslated.Y + RadiusY, 0.0f) , static_cast<float>(-Extension.Y + 1.0f) );
861 FIntVector MinVector = GetVectorTileId(
FDVector(std::floor(MinX), std::floor(MinY), 0));
862 FIntVector MaxVector = GetVectorTileId(
FDVector(std::floor(MaxX), std::floor(MaxY), 0));
865 TRACE_CPUPROFILER_EVENT_SCOPE(TEXT(
"FSparseHighDetailMap::WaitUntilProperTilesAreLoaded"));
866 for(int32_t X = MinVector.X; X < MaxVector.X; X++ )
868 for(int32_t Y = MinVector.Y; Y < MaxVector.Y; Y++ )
870 bool ConditionToStopWaiting =
true;
874 while(ConditionToStopWaiting)
876 uint64_t CurrentTileID = GetTileId(X,Y);
878 TRACE_CPUPROFILER_EVENT_SCOPE(TEXT(
"FSparseHighDetailMap::WaitUntilProperTilesAreLoaded::TimeLocked"));
879 ConditionToStopWaiting = Map.find(CurrentTileID) == Map.end();
891 UE_LOG(LogCarla, Warning, TEXT(
"Save directory %s"), *SavePath );
893 ParallelFor(Map.size(), [
this](int32 Idx)
895 std::pair<uint64_t, FDenseTile> it = *(std::next(this->Map.begin(), Idx) );
896 std::string FileToSavePath = std::string(TCHAR_TO_UTF8(*( this->SavePath + it.second.TilePosition.ToString() +
".tile")));
897 std::ofstream OutputStream(FileToSavePath.c_str());
898 WriteFVector(OutputStream, it.second.TilePosition.ToFVector());
899 WriteStdVector<FParticle> (OutputStream, it.second.Particles);
900 OutputStream.close();
903 ParallelFor(CacheMap.size(), [
this](int32 Idx)
905 std::pair<uint64_t, FDenseTile> it = *(std::next(this->CacheMap.begin(), Idx) );
906 std::string FileToSavePath = std::string(TCHAR_TO_UTF8(*( this->SavePath + it.second.TilePosition.ToString() +
".tile")));
907 std::ofstream OutputStream(FileToSavePath.c_str());
908 WriteFVector(OutputStream, it.second.TilePosition.ToFVector());
909 WriteStdVector<FParticle> (OutputStream, it.second.Particles);
910 OutputStream.close();
915 void UCustomTerrainPhysicsComponent::UpdateTexture()
917 UpdateLoadedTextureDataRegions();
919 ENQUEUE_RENDER_COMMAND(UpdateDynamicTextureCode)
921 [NewData=Data, Texture=TextureToUpdate](
auto &InRHICmdList)
mutable 923 TRACE_CPUPROFILER_EVENT_SCOPE(TEXT(
"UCustomTerrainPhysicsComponent::TickComponent Renderthread"));
924 FUpdateTextureRegion2D region;
929 region.Width = Texture->GetSizeX();
930 region.Height = Texture->GetSizeY();
932 FTexture2DResource* resource = (FTexture2DResource*)Texture->Resource;
934 resource->GetTexture2DRHI(), 0, region, region.Width *
sizeof(uint8_t), &NewData[0]);
938 void UCustomTerrainPhysicsComponent::InitTexture(){
939 if( Data.Num() == 0 && TextureToUpdate ){
940 float LimitX = TextureToUpdate->GetSizeX();
941 float LimitY = TextureToUpdate->GetSizeY();
942 Data.Init(128, LimitX * LimitY);
945 if( LargeData.Num() == 0 && LargeTextureToUpdate ){
946 float LimitX = LargeTextureToUpdate->GetSizeX();
947 float LimitY = LargeTextureToUpdate->GetSizeY();
948 LargeData.Init(128, LimitX * LimitY);
952 void UCustomTerrainPhysicsComponent::UpdateLoadedTextureDataRegions()
954 TRACE_CPUPROFILER_EVENT_SCOPE(
"UCustomTerrainPhysicsComponent::UpdateLoadedTextureDataRegions");
955 const int32_t TextureSizeX = TextureToUpdate->GetSizeX();
956 if ( TextureSizeX == 0)
return;
961 std::vector<uint64_t> LoadedTiles =
962 SparseMap.GetLoadedTilesInRange(TextureCenterPosition, TextureRadius );
963 FDVector TextureOrigin = TextureCenterPosition -
FDVector(TextureRadius, TextureRadius, 0);
964 float GlobalTexelSize = (2.0f * TextureRadius) / TextureSizeX;
965 int32_t PartialHeightMapSize = std::floor( SparseMap.GetTileSize() * TextureSizeX / (2*TextureRadius) );
967 float LocalTexelSize = SparseMap.GetTileSize() / PartialHeightMapSize;
968 LocalTexelSize = std::floor( LocalTexelSize * 1000.0f ) / 1000.0f;
970 Data.Init( 128, Data.Num() );
971 float DisplacementRange = MaxDisplacement - MinDisplacement;
972 float InverseDisplacementRange = 1.0f / DisplacementRange;
974 for (uint64_t TileId : LoadedTiles)
976 FDenseTile& CurrentTile = SparseMap.GetTile(TileId);
984 for (int32_t Local_Y = 0; Local_Y < PartialHeightMapSize; ++Local_Y)
986 for (int32_t Local_X = 0; Local_X < PartialHeightMapSize; ++Local_X)
988 int32_t LocalIndex = Local_Y * PartialHeightMapSize + Local_X;
990 FDVector LocalTexelPosition =
991 TilePosition + FDVector(Local_X*LocalTexelSize, Local_Y*LocalTexelSize, 0);
992 int32_t Coord_X = std::floor( (LocalTexelPosition.
X - TextureOrigin.
X ) / GlobalTexelSize );
993 int32_t Coord_Y = std::floor( (LocalTexelPosition.
Y - TextureOrigin.
Y ) / GlobalTexelSize );
995 if ( Coord_X >= 0 && Coord_X < TextureSizeX &&
996 Coord_Y >= 0 && Coord_Y < TextureToUpdate->GetSizeY() )
998 float OriginalHeight = SparseMap.GetHeight(LocalTexelPosition);
999 float Displacement = Height - OriginalHeight;
1000 float Fraction = (Displacement - MinDisplacement) * InverseDisplacementRange;
1001 Fraction = FMath::Clamp(Fraction, 0.f, 1.f) * 255;
1002 Data[Coord_X * TextureToUpdate->GetSizeY() + Coord_Y] =
static_cast<uint8_t
>(Fraction );
1009 void UCustomTerrainPhysicsComponent::UpdateLargeTexture()
1011 UpdateLargeTextureData();
1013 ENQUEUE_RENDER_COMMAND(UpdateDynamicTextureCode)
1015 [NewData=LargeData, Texture=LargeTextureToUpdate](
auto &InRHICmdList)
mutable 1017 TRACE_CPUPROFILER_EVENT_SCOPE(TEXT(
"UCustomTerrainPhysicsComponent::TickComponent Renderthread"));
1018 FUpdateTextureRegion2D region;
1023 region.Width = Texture->GetSizeX();
1024 region.Height = Texture->GetSizeY();
1026 FTexture2DResource* resource = (FTexture2DResource*)Texture->Resource;
1028 resource->GetTexture2DRHI(), 0, region, region.Width *
sizeof(uint8_t), &NewData[0]);
1032 void UCustomTerrainPhysicsComponent::UpdateLargeTextureData()
1034 uint32_t NumberOfParticlesIn1AxisInLocalHeightmap = TextureToUpdate->GetSizeX() / (TextureRadius * 2) / TileSize;
1035 uint32_t NumberOfParticlesIn1AxisInLargeHeightmap = LargeTextureToUpdate->GetSizeX() / (CacheRadius.X * 2) / TileSize;
1037 std::vector<float> ParticlesPositions;
1039 TRACE_CPUPROFILER_EVENT_SCOPE(TEXT(
"UCustomTerrainPhysicsComponent::UpdateLargeTextureData::GettingHeightMaps"));
1040 FVector OriginPosition;
1041 OriginPosition.X = CachePosition.X + (
WorldSize.
X * 0.5f);
1042 OriginPosition.Y = -CachePosition.Y - (
WorldSize.
Y * 0.5f);
1047 int32_t OffsetX = 0;
1048 int32_t OffsetY = 0;
1049 float* Ptr = &ParticlesPositions[0];
1050 while( OffsetY < LargeTextureToUpdate->GetSizeY() )
1052 for(uint32_t y = 0; y < NumberOfParticlesIn1AxisInLocalHeightmap; y++)
1054 float LocalYTransformed = std::floor(y / NumberOfParticlesIn1AxisInLocalHeightmap * NumberOfParticlesIn1AxisInLargeHeightmap);
1055 for(uint32_t x = 0; x < NumberOfParticlesIn1AxisInLocalHeightmap; x++)
1057 uint32_t LocalIndex = x + y * NumberOfParticlesIn1AxisInLocalHeightmap;
1058 float LocalXTransformed = std::floor(x / NumberOfParticlesIn1AxisInLocalHeightmap * NumberOfParticlesIn1AxisInLargeHeightmap);
1064 Ptr += (NumberOfParticlesIn1AxisInLocalHeightmap* NumberOfParticlesIn1AxisInLocalHeightmap);
1066 OffsetX += NumberOfParticlesIn1AxisInLargeHeightmap;
1067 if( OffsetX >= LargeTextureToUpdate->GetSizeX() )
1070 OffsetY += NumberOfParticlesIn1AxisInLargeHeightmap;
1076 UCustomTerrainPhysicsComponent::UCustomTerrainPhysicsComponent()
1079 PrimaryComponentTick.bCanEverTick =
true;
1082 void UCustomTerrainPhysicsComponent::BeginPlay()
1084 TRACE_CPUPROFILER_EVENT_SCOPE(UCustomTerrainPhysicsComponent::BeginPlay);
1089 RootComponent = Cast<UPrimitiveComponent>(GetOwner()->GetRootComponent());
1092 UE_LOG(LogCarla, Error,
1093 TEXT(
"UCustomTerrainPhysicsComponent: Root component is not a UPrimitiveComponent"));
1096 bUpdateParticles =
true;
1097 DrawDebugInfo =
false;
1098 bUseDynamicModel =
false;
1099 bDisableVehicleGravity =
false;
1101 bUseImpulse =
false;
1102 bUseMeanAcceleration =
false;
1105 bDrawHeightMap =
false;
1106 ForceMulFactor = 1.f;
1107 ParticleForceMulFactor = 1.f;
1109 bDrawLoadedTiles =
false;
1110 bUseSoilType =
true;
1111 EffectMultiplayer = 200.0f;
1112 MinDisplacement = -10.0f;
1113 MaxDisplacement = 10.0f;
1114 bRemoveLandscapeColliders =
false;
1120 CUDADevice = IntValue;
1122 if (FParse::Value(
FCommandLine::Get(), TEXT(
"-max-particles-per-wheel="), IntValue))
1124 MaxParticlesPerWheel = IntValue;
1129 ParticleDiameter =
MToCM*Value;
1133 TerrainDepth =
MToCM*Value;
1137 SearchRadius =
MToCM*Value;
1141 BoxSearchForwardDistance =
MToCM*Value;
1145 BoxSearchLateralDistance =
MToCM*Value;
1149 BoxSearchDepthDistance =
MToCM*Value;
1153 ForceMulFactor = Value;
1157 EffectMultiplayer = Value;
1165 MinDisplacement = Value;
1169 MaxDisplacement = Value;
1171 if (FParse::Value(
FCommandLine::Get(), TEXT(
"-particle-force-mul-factor="), Value))
1173 ParticleForceMulFactor = Value;
1177 MaxForceMagnitude =
MToCM*Value;
1181 FloorHeight =
MToCM*Value;
1189 TileRadius =
MToCM*FVector(Value, Value, 0.f);
1193 CacheRadius =
MToCM*FVector(Value, Value, 0.f);
1197 bUpdateParticles =
true;
1201 DrawDebugInfo =
true;
1205 bUseLocalFrame =
true;
1210 NeuralModelFile =
Path;
1220 bUseDynamicModel =
true;
1224 bDisableVehicleGravity =
true;
1232 bUseSoilType =
true;
1240 bUseMeanAcceleration =
true;
1244 bShowForces =
false;
1252 bDrawLoadedTiles =
true;
1256 bRemoveLandscapeColliders =
true;
1260 SetComponentTickEnabled(
false);
1264 if(bRemoveLandscapeColliders)
1266 FWorldDelegates::LevelAddedToWorld.AddUObject(
1267 this, &UCustomTerrainPhysicsComponent::OnLevelAddedToWorld);
1271 if( TexturesRes.Contains(ChosenRes) ){
1272 TextureToUpdate = TexturesRes[ChosenRes];
1276 TRACE_CPUPROFILER_EVENT_SCOPE(InitializeDenseMap);
1278 UE_LOG(LogCarla, Warning,
1279 TEXT(
"ParticleDiameter %f"), ParticleDiameter);
1281 SparseMap.Init(TextureToUpdate->GetSizeX(), TextureRadius, ParticleDiameter *
CMToM, TerrainDepth *
CMToM, FloorHeight *
CMToM );
1282 RootComponent = Cast<UPrimitiveComponent>(GetOwner()->GetRootComponent());
1285 FIntVector NumTiles = LargeMapManager->GetNumTilesInXY();
1295 TileSize, HeightMapScaleFactor.Z);
1300 TRACE_CPUPROFILER_EVENT_SCOPE(LoadNNModel);
1302 TerramechanicsModel.LoadModel(TCHAR_TO_ANSI(*NeuralModelFile), CUDADevice);
1306 FString LevelName = GetWorld()->GetMapName();
1307 LevelName.RemoveFromStart(GetWorld()->StreamingLevelsPrefix);
1309 SavePath = FString(_filesBaseFolder.c_str()) + LevelName +
"_Terrain/";
1310 SparseMap.SavePath = SavePath;
1313 if( FileManager.CreateDirectory(*SavePath)){
1314 UE_LOG(LogCarla, Warning,
1315 TEXT(
"Folder was created at %s"), *SavePath);
1317 UE_LOG(LogCarla, Error,
1318 TEXT(
"Folder was not created at %s"), *SavePath);
1321 if(bUseDeformationPlane){
1322 DeformationPlaneActor = GetWorld()->SpawnActor<AStaticMeshActor>();
1324 if( DeformationPlaneActor )
1326 DeformationPlaneActor->GetStaticMeshComponent()->SetStaticMesh( DeformationPlaneMesh );
1327 DeformationPlaneActor->GetStaticMeshComponent()->SetMaterial( 0, DeformationPlaneMaterial );
1328 DeformationPlaneActor->GetRootComponent()->SetMobility(EComponentMobility::Movable);
1334 UE_LOG(LogCarla, Log, TEXT(
"MainThread Data ArraySize %d "), Data.Num());
1335 UE_LOG(LogCarla, Log, TEXT(
"Map Size %d "), SparseMap.Map.size() );
1337 if (TilesWorker ==
nullptr)
1339 TilesWorker =
new FTilesWorker(
this, GetOwner()->GetActorLocation(), TileRadius.X, TileRadius.Y);
1340 Thread = FRunnableThread::Create(TilesWorker, TEXT(
"TilesWorker"));
1345 void UCustomTerrainPhysicsComponent::BuildLandscapeHeightMapDataAasset(ALandscapeProxy* Landscape,
1346 int Resolution, FVector MapSize, FString AssetPath, FString AssetName)
1348 TRACE_CPUPROFILER_EVENT_SCOPE(UCustomTerrainPhysicsComponent::BuildLandscapeHeightMapTexture);
1349 TArray<float> HeightMap;
1350 HeightMap.Reserve(Resolution*Resolution);
1351 FVector Origin = Landscape->GetActorLocation();
1352 float DeltaX = MapSize.X / Resolution;
1353 float DeltaY = MapSize.Y / Resolution;
1354 for (
size_t i = 0; i < Resolution; ++i)
1356 float PosX = Origin.X + i*DeltaX;
1357 for (
size_t j = 0; j < Resolution; ++j)
1359 float PosY = Origin.Y + j*DeltaY;
1360 FVector
Location = FVector(PosX, PosY, 0);
1361 float Height = Landscape->GetHeightAtLocation(Location).Get(-1);
1362 HeightMap.Emplace(Height);
1365 int TextureWidth = Resolution;
1366 int TextureHeight = Resolution;
1367 FString PackageName = AssetPath;
1368 PackageName += AssetName;
1369 UPackage* Package = CreatePackage(NULL, *PackageName);
1370 Package->FullyLoad();
1372 UHeightMapDataAsset* HeightMapAsset = NewObject<UHeightMapDataAsset>(Package, *AssetName, RF_Public | RF_Standalone | RF_MarkAsRootSet);
1373 HeightMapAsset->AddToRoot();
1374 HeightMapAsset->
SizeX = TextureWidth;
1375 HeightMapAsset->
SizeY = TextureHeight;
1378 Package->MarkPackageDirty();
1381 FString PackageFileName = FPackageName::LongPackageNameToFilename(PackageName, FPackageName::GetAssetPackageExtension());
1382 bool bSaved = UPackage::SavePackage(Package, HeightMapAsset, EObjectFlags::RF_Public | EObjectFlags::RF_Standalone, *PackageFileName, GError,
nullptr,
true,
true, SAVE_NoError);
1386 float UCustomTerrainPhysicsComponent::GetHeightAtLocation(ALandscapeProxy * Landscape, FVector
Location)
1388 TOptional<float> OptionalHeight = Landscape->GetHeightAtLocation(Location);
1389 if(OptionalHeight.IsSet())
1390 return OptionalHeight.GetValue();
1394 void UCustomTerrainPhysicsComponent::EndPlay(
const EEndPlayReason::Type EndPlayReason){
1395 Super::EndPlay(EndPlayReason);
1396 if( Thread && TilesWorker){
1397 TilesWorker->bShouldContinue =
false;
1398 Thread->WaitForCompletion();
1399 Thread->Kill(
false);
1401 TilesWorker =
nullptr;
1405 SparseMap.SaveMap();
1408 void UCustomTerrainPhysicsComponent::TickComponent(
float DeltaTime,
1409 ELevelTick TickType, FActorComponentTickFunction* ThisTickFunction)
1411 TRACE_CPUPROFILER_EVENT_SCOPE(UCustomTerrainPhysicsComponent::TickComponent);
1412 Super::TickComponent(DeltaTime,TickType,ThisTickFunction);
1414 TArray<AActor*> VehiclesActors;
1415 UGameplayStatics::GetAllActorsOfClass(GetWorld(), ACarlaWheeledVehicle::StaticClass(), VehiclesActors);
1417 for (
AActor* VehicleActor : VehiclesActors)
1426 const FActorInfo* ActorInfo = CarlaActor->GetActorInfo();
1435 FVector GlobalLocation = Vehicle->GetActorLocation();
1438 GlobalLocation = LargeMapManager->LocalToGlobalLocation(Vehicle->GetActorLocation());
1440 uint64_t TileId = LargeMapManager->GetTileID(GlobalLocation);
1441 FIntVector CurrentTileId =
1442 LargeMapManager->GetTileVectorID(GlobalLocation);
1443 if(CurrentLargeMapTileId != CurrentTileId)
1446 FCarlaMapTile* LargeMapTile = LargeMapManager->GetCarlaMapTile(TileId);
1449 CurrentLargeMapTileId = CurrentTileId;
1450 FString FullTileNamePath = LargeMapTile->
Name;
1451 FString TileDirectory;
1454 FPaths::Split(FullTileNamePath, TileDirectory, TileName, Extension);
1455 FString AssetPath = TileDirectory +
"/HeightMaps/" + TileName +
"." + TileName;
1456 UE_LOG(LogCarla, Log, TEXT(
"Enter tile %s, %s \n %s \n %s \n %s"), *CurrentTileId.ToString(),
1457 *FullTileNamePath, *TileDirectory, *TileName, *Extension);
1459 UObject* DataAssetObject = StaticLoadObject(UHeightMapDataAsset::StaticClass(),
nullptr, *(AssetPath));
1463 if (HeightMapDataAsset !=
nullptr)
1465 FVector TilePosition = HeightMapOffset + LargeMapManager->GetTileLocation(CurrentLargeMapTileId) - 0.5f*FVector(LargeMapManager->GetTileSize(), -LargeMapManager->GetTileSize(), 0);
1466 UE_LOG(LogCarla, Log, TEXT(
"Updating height map to location %s in tile location %s"),
1467 *TilePosition.ToString(), *LargeMapManager->GetTileLocation(CurrentLargeMapTileId).ToString());
1469 SparseMap.UpdateHeightMap(
1471 LargeMapManager->GetTileSize(),-LargeMapManager->GetTileSize(), 0)),
1472 1.f, HeightMapScaleFactor.Z);
1485 SparseMap.LockMutex();
1486 RunNNPhysicsSimulation(Vehicle, DeltaTime);
1487 LastUpdatedPosition = GlobalLocation;
1488 SparseMap.UnLockMutex();
1490 if (bDrawLoadedTiles)
1492 DrawTiles(GetWorld(), SparseMap.GetTileIdInMap(), GlobalLocation.Z + 300, FLinearColor(0.0,0.0,1.0,0.0));
1493 DrawTiles(GetWorld(), SparseMap.GetTileIdInCache(), GlobalLocation.Z + 300, FLinearColor(1.0,0.0,0.0,0.0));
1496 if( MPCInstance ==
nullptr )
1499 MPCInstance = GetWorld()->GetParameterCollectionInstance( MPC );
1504 MPCInstance->SetVectorParameterValue(
"PositionToUpdate", GetTileCenter(LastUpdatedPosition));
1506 MPCInstance->SetScalarParameterValue(
"TextureRadius", TextureRadius * 100);
1507 MPCInstance->SetScalarParameterValue(
"LargeTextureRadius", TextureRadius * 100);
1508 MPCInstance->SetScalarParameterValue(
"EffectMultiplayer", EffectMultiplayer);
1509 MPCInstance->SetScalarParameterValue(
"MinDisplacement", MinDisplacement);
1510 MPCInstance->SetScalarParameterValue(
"MaxDisplacement", MinDisplacement);
1511 if(TextureToUpdate){
1512 MPCInstance->SetScalarParameterValue(
"TexSizeX", TextureToUpdate->GetSizeX());
1516 if(bUseDeformationPlane){
1517 if( DeformationPlaneActor ){
1518 DeformationPlaneActor->SetActorLocation(LastUpdatedPosition,
false,
nullptr);
1520 DeformationPlaneActor = GetWorld()->SpawnActor<AStaticMeshActor>();
1522 if( DeformationPlaneActor )
1524 DeformationPlaneActor->GetStaticMeshComponent()->SetStaticMesh( DeformationPlaneMesh );
1525 DeformationPlaneActor->GetStaticMeshComponent()->SetMaterial( 0, DeformationPlaneMaterial );
1526 DeformationPlaneActor->GetRootComponent()->SetMobility(EComponentMobility::Movable);
1534 TRACE_CPUPROFILER_EVENT_SCOPE(DrawHeightMap);
1535 float LifeTime = 0.3f;
1536 bool bPersistentLines =
false;
1537 bool bDepthIsForeground = (0 == SDPG_Foreground);
1538 UWorld* World = GetWorld();
1539 ULineBatchComponent* LineBatcher =
1540 (World ? (bDepthIsForeground ? World->ForegroundLineBatcher :
1541 (( bPersistentLines || (LifeTime > 0.f) ) ? World->PersistentLineBatcher : World->LineBatcher)) :
nullptr);
1544 UE_LOG(LogCarla, Error, TEXT(
"Missing linebatcher"));
1547 float DrawPos_X = DrawStart.X;
1548 float DrawPos_Y = DrawStart.Y;
1549 for (DrawPos_X = DrawStart.X; DrawPos_X < DrawEnd.X; DrawPos_X += DrawInterval.X)
1551 for (DrawPos_Y = DrawStart.Y; DrawPos_Y < DrawEnd.Y; DrawPos_Y += DrawInterval.Y)
1553 float Height = SparseMap.GetHeight(
UEFrameToSI(FVector(DrawPos_X, DrawPos_Y, 0)));
1554 FVector Point = FVector(DrawPos_X, DrawPos_Y,
SIToUEFrame(Height));
1557 Point = LargeMapManager->GlobalToLocalLocation(Point);
1559 LineBatcher->DrawPoint(Point,
1560 FLinearColor(1.f, 0.f, 0.f), 10.0, 0, LifeTime);
1567 void UCustomTerrainPhysicsComponent::DrawParticles(UWorld* World, std::vector<FParticle*>& Particles,
1570 float LifeTime = 0.3f;
1571 bool bPersistentLines =
false;
1572 bool bDepthIsForeground = (0 == SDPG_Foreground);
1573 ULineBatchComponent* LineBatcher =
1574 (World ? (bDepthIsForeground ? World->ForegroundLineBatcher :
1575 (( bPersistentLines || (LifeTime > 0.f) ) ? World->PersistentLineBatcher : World->LineBatcher)) :
nullptr);
1578 UE_LOG(LogCarla, Error, TEXT(
"Missing linebatcher"));
1584 FVector Point =
SIToUEFrame(Particle->Position.ToFVector());
1587 Point = LargeMapManager->GlobalToLocalLocation(Point);
1589 LineBatcher->DrawPoint(Point,
1590 Color, 1.0, 0, LifeTime);
1594 void UCustomTerrainPhysicsComponent::DrawParticlesArray(UWorld* World, TArray<float>& ParticlesArray,
1597 float LifeTime = 0.3f;
1598 bool bPersistentLines =
false;
1599 bool bDepthIsForeground = (0 == SDPG_Foreground);
1600 ULineBatchComponent* LineBatcher =
1601 (World ? (bDepthIsForeground ? World->ForegroundLineBatcher :
1602 (( bPersistentLines || (LifeTime > 0.f) ) ? World->PersistentLineBatcher : World->LineBatcher)) :
nullptr);
1605 UE_LOG(LogCarla, Error, TEXT(
"Missing linebatcher"));
1607 for(
int i = 0; i < ParticlesArray.Num(); i+=3)
1609 FVector
Position = FVector(ParticlesArray[i+0], ParticlesArray[i+1], ParticlesArray[i+2]);
1613 LineBatcher->DrawPoint(Point,
1614 Color, 1.0, 0, LifeTime);
1618 void UCustomTerrainPhysicsComponent::DrawOrientedBox(UWorld* World,
const TArray<FOrientedBox>& Boxes)
1620 float LifeTime = 0.3f;
1621 bool bPersistentLines =
false;
1622 bool bDepthIsForeground = (0 == SDPG_Foreground);
1623 float Thickness = 2.0f;
1624 ULineBatchComponent* LineBatcher =
1625 (World ? (bDepthIsForeground ? World->ForegroundLineBatcher :
1626 (( bPersistentLines || (LifeTime > 0.f) ) ? World->PersistentLineBatcher : World->LineBatcher)) :
nullptr);
1629 UE_LOG(LogCarla, Error, TEXT(
"Missing linebatcher"));
1631 for (
const FOrientedBox& OBox : Boxes)
1633 TArray<FVector> Vertices;
1635 OBox.CalcVertices(&Vertices[0]);
1638 for(FVector& Point : Vertices)
1640 Point = LargeMapManager->GlobalToLocalLocation(Point);
1643 LineBatcher->DrawLines({
1644 FBatchedLine(Vertices[0], Vertices[1],
1645 FLinearColor(0.0,0.0,1.0), LifeTime, Thickness, 0),
1646 FBatchedLine(Vertices[0], Vertices[2],
1647 FLinearColor(0.0,0.0,1.0), LifeTime, Thickness, 0),
1648 FBatchedLine(Vertices[2], Vertices[3],
1649 FLinearColor(0.0,0.0,1.0), LifeTime, Thickness, 0),
1650 FBatchedLine(Vertices[3], Vertices[1],
1651 FLinearColor(0.0,0.0,1.0), LifeTime, Thickness, 0),
1653 FBatchedLine(Vertices[4], Vertices[5],
1654 FLinearColor(0.0,0.0,1.0), LifeTime, Thickness, 0),
1655 FBatchedLine(Vertices[4], Vertices[6],
1656 FLinearColor(0.0,0.0,1.0), LifeTime, Thickness, 0),
1657 FBatchedLine(Vertices[6], Vertices[7],
1658 FLinearColor(0.0,0.0,1.0), LifeTime, Thickness, 0),
1659 FBatchedLine(Vertices[7], Vertices[5],
1660 FLinearColor(0.0,0.0,1.0), LifeTime, Thickness, 0),
1662 FBatchedLine(Vertices[0], Vertices[4],
1663 FLinearColor(0.0,0.0,1.0), LifeTime, Thickness, 0),
1664 FBatchedLine(Vertices[1], Vertices[5],
1665 FLinearColor(0.0,0.0,1.0), LifeTime, Thickness, 0),
1666 FBatchedLine(Vertices[2], Vertices[6],
1667 FLinearColor(0.0,0.0,1.0), LifeTime, Thickness, 0),
1668 FBatchedLine(Vertices[3], Vertices[7],
1669 FLinearColor(0.0,0.0,1.0), LifeTime, Thickness, 0)});
1673 void UCustomTerrainPhysicsComponent::DrawTiles(UWorld* World,
const std::vector<uint64_t>& TilesIds,
float Height,
1676 float LifeTime = 0.3f;
1677 bool bPersistentLines =
false;
1678 bool bDepthIsForeground = (0 == SDPG_Foreground);
1679 float Thickness = 2.0f;
1680 ULineBatchComponent* LineBatcher =
1681 (World ? (bDepthIsForeground ? World->ForegroundLineBatcher :
1682 (( bPersistentLines || (LifeTime > 0.f) ) ? World->PersistentLineBatcher : World->LineBatcher)) :
nullptr);
1685 UE_LOG(LogCarla, Error, TEXT(
"Missing linebatcher"));
1688 for (
const uint64_t& TileId : TilesIds)
1690 FVector TileCenter = SparseMap.GetTilePosition(TileId).ToFVector();
1692 FVector V2 =
SIToUEFrame(TileCenter + FVector(SparseMap.GetTileSize(),0,0));
1693 FVector V3 =
SIToUEFrame(TileCenter + FVector(0,SparseMap.GetTileSize(),0));
1694 FVector V4 =
SIToUEFrame(TileCenter + FVector(SparseMap.GetTileSize(),SparseMap.GetTileSize(),0));
1697 V1 = LargeMapManager->GlobalToLocalLocation(V1);
1698 V2 = LargeMapManager->GlobalToLocalLocation(V2);
1699 V3 = LargeMapManager->GlobalToLocalLocation(V3);
1700 V4 = LargeMapManager->GlobalToLocalLocation(V4);
1706 LineBatcher->DrawLines({
1707 FBatchedLine(V1, V2,
1708 Color, LifeTime, Thickness, 0),
1709 FBatchedLine(V2, V4,
1710 Color, LifeTime, Thickness, 0),
1711 FBatchedLine(V1, V3,
1712 Color, LifeTime, Thickness, 0),
1713 FBatchedLine(V3, V4,
1714 Color, LifeTime, Thickness, 0)});
1720 void UCustomTerrainPhysicsComponent::LimitParticlesPerWheel(std::vector<FParticle*> &Particles)
1722 TRACE_CPUPROFILER_EVENT_SCOPE(LimitParticlesPerWheel);
1723 if (Particles.size() < MaxParticlesPerWheel)
1731 Particles.resize(MaxParticlesPerWheel);
1734 void UCustomTerrainPhysicsComponent::GenerateBenchmarkParticles(std::vector<FParticle>& BenchParticles,
1735 std::vector<FParticle*> &ParticlesWheel0, std::vector<FParticle*> &ParticlesWheel1,
1736 std::vector<FParticle*> &ParticlesWheel2, std::vector<FParticle*> &ParticlesWheel3,
1737 FOrientedBox &BboxWheel0, FOrientedBox &BboxWheel1,
1738 FOrientedBox &BboxWheel2, FOrientedBox &BboxWheel3)
1740 TRACE_CPUPROFILER_EVENT_SCOPE(GenerateBenchmarkParticles);
1741 BenchParticles.reserve(100000);
1742 auto GenerateBoxParticles = [&](FOrientedBox &BboxWheel, std::vector<FParticle*> &ParticlesWheel)
1744 ParticlesWheel.clear();
1745 FVector TileOrigin = FVector(0,0,0);
1746 FVector BoxSize = FVector(2*BboxWheel.ExtentX, 2*BboxWheel.ExtentY, BboxWheel.ExtentZ);
1747 uint32_t NumParticles_X = BoxSize.X / ParticleDiameter;
1748 uint32_t NumParticles_Y = BoxSize.Y / ParticleDiameter;
1749 uint32_t NumParticles_Z = BoxSize.Z / ParticleDiameter;
1750 UE_LOG(LogCarla, Log, TEXT(
"Generating (%d,%d,%d) particles"),
1751 NumParticles_X,NumParticles_Y,NumParticles_Z);
1752 for(uint32_t i = 0; i < NumParticles_X; i++)
1754 float XPos = i*ParticleDiameter;
1755 for(uint32_t j = 0; j < NumParticles_Y; j++)
1757 float YPos = j*ParticleDiameter;
1758 for(uint32_t k = 0; k < NumParticles_Z; k++)
1760 float ZPos = k*ParticleDiameter;
1761 FVector ParticlePosition = TileOrigin + FVector(XPos, YPos, ZPos);
1762 ParticlePosition = (ParticlePosition.X - BboxWheel.ExtentX) * BboxWheel0.AxisX +
1763 (ParticlePosition.Y - BboxWheel.ExtentY) * BboxWheel0.AxisY +
1764 (ParticlePosition.Z - BboxWheel.ExtentZ) * BboxWheel0.AxisZ + BboxWheel.Center;
1766 BenchParticles.emplace_back(
FParticle{ParticlePosition, FVector(0), ParticleDiameter/2.f});
1767 ParticlesWheel.emplace_back(&BenchParticles.back());
1772 GenerateBoxParticles(BboxWheel0, ParticlesWheel0);
1773 GenerateBoxParticles(BboxWheel1, ParticlesWheel1);
1774 GenerateBoxParticles(BboxWheel2, ParticlesWheel2);
1775 GenerateBoxParticles(BboxWheel3, ParticlesWheel3);
1777 UE_LOG(LogCarla, Log, TEXT(
"Generated %d particles"), BenchParticles.size());
1780 void UCustomTerrainPhysicsComponent::RunNNPhysicsSimulation(
1783 TRACE_CPUPROFILER_EVENT_SCOPE(RunNNPhysicsSimulation);
1785 FTransform VehicleTransform = Vehicle->GetTransform();
1786 FTransform WheelTransform0 = VehicleTransform;
1787 FTransform WheelTransform1 = VehicleTransform;
1788 FTransform WheelTransform2 = VehicleTransform;
1789 FTransform WheelTransform3 = VehicleTransform;
1790 FVector WheelPosition0 = VehicleTransform.TransformPosition(FVector(140, -70, 40));
1791 FVector WheelPosition1 = VehicleTransform.TransformPosition(FVector(140, 70, 40));
1792 FVector WheelPosition2 = VehicleTransform.TransformPosition(FVector(-140, -70, 40));
1793 FVector WheelPosition3 = VehicleTransform.TransformPosition(FVector(-140, 70, 40));
1794 WheelTransform0.SetLocation(WheelPosition0);
1795 WheelTransform1.SetLocation(WheelPosition1);
1796 WheelTransform2.SetLocation(WheelPosition2);
1797 WheelTransform3.SetLocation(WheelPosition3);
1800 WheelPosition0 = LargeMapManager->LocalToGlobalLocation(WheelPosition0);
1801 WheelPosition1 = LargeMapManager->LocalToGlobalLocation(WheelPosition1);
1802 WheelPosition2 = LargeMapManager->LocalToGlobalLocation(WheelPosition2);
1803 WheelPosition3 = LargeMapManager->LocalToGlobalLocation(WheelPosition3);
1805 FOrientedBox BboxWheel0;
1806 BboxWheel0.AxisX = VehicleTransform.GetUnitAxis(EAxis::X);
1807 BboxWheel0.AxisY = VehicleTransform.GetUnitAxis(EAxis::Y);
1808 BboxWheel0.AxisZ = VehicleTransform.GetUnitAxis(EAxis::Z);
1809 BboxWheel0.Center = WheelPosition0 + FVector(0,0,-TireRadius);
1810 BboxWheel0.ExtentX = BoxSearchForwardDistance;
1811 BboxWheel0.ExtentY = BoxSearchLateralDistance;
1812 BboxWheel0.ExtentZ = BoxSearchDepthDistance;
1813 FOrientedBox BboxWheel1 = BboxWheel0;
1814 BboxWheel1.Center = WheelPosition1 + FVector(0,0,-TireRadius);
1815 FOrientedBox BboxWheel2 = BboxWheel0;
1816 BboxWheel2.Center = WheelPosition2 + FVector(0,0,-TireRadius);
1817 FOrientedBox BboxWheel3 = BboxWheel0;
1818 BboxWheel3.Center = WheelPosition3 + FVector(0,0,-TireRadius);
1821 DrawOrientedBox(GetWorld(), {BboxWheel0, BboxWheel1, BboxWheel2, BboxWheel3});
1824 std::vector<FParticle*> ParticlesWheel0, ParticlesWheel1, ParticlesWheel2, ParticlesWheel3;
1826 TRACE_CPUPROFILER_EVENT_SCOPE(ParticleSearch);
1827 auto GetAndFilterParticlesInBox =
1828 [&] (FOrientedBox& OBox) -> std::vector<FParticle*>
1830 std::vector<FParticle*> Particles;
1831 Particles = SparseMap.GetParticlesInBox(OBox);
1832 LimitParticlesPerWheel(Particles);
1835 auto FutureParticles0 = Async(EAsyncExecution::ThreadPool,
1836 [&]() {
return GetAndFilterParticlesInBox(BboxWheel0);});
1837 auto FutureParticles2 = Async(EAsyncExecution::ThreadPool,
1838 [&]() {
return GetAndFilterParticlesInBox(BboxWheel2);});
1839 auto FutureParticles1 = Async(EAsyncExecution::ThreadPool,
1840 [&]() {
return GetAndFilterParticlesInBox(BboxWheel1);});
1841 auto FutureParticles3 = Async(EAsyncExecution::ThreadPool,
1842 [&]() {
return GetAndFilterParticlesInBox(BboxWheel3);});
1843 ParticlesWheel0 = FutureParticles0.Get();
1844 ParticlesWheel2 = FutureParticles2.Get();
1845 ParticlesWheel1 = FutureParticles1.Get();
1846 ParticlesWheel3 = FutureParticles3.Get();
1849 std::vector<FParticle> BenchParticles;
1852 GenerateBenchmarkParticles(BenchParticles,
1853 ParticlesWheel0, ParticlesWheel1, ParticlesWheel2, ParticlesWheel3,
1854 BboxWheel0, BboxWheel1, BboxWheel2, BboxWheel3);
1855 UE_LOG(LogCarla, Log, TEXT(
"Generated %d particles"), BenchParticles.size());
1860 DrawParticles(GetWorld(), ParticlesWheel0);
1861 DrawParticles(GetWorld(), ParticlesWheel1);
1862 DrawParticles(GetWorld(), ParticlesWheel2);
1863 DrawParticles(GetWorld(), ParticlesWheel3);
1864 DrawTiles(GetWorld(), SparseMap.GetIntersectingTiles(BboxWheel0), BboxWheel0.Center.Z);
1865 DrawTiles(GetWorld(), SparseMap.GetIntersectingTiles(BboxWheel1), BboxWheel1.Center.Z);
1866 DrawTiles(GetWorld(), SparseMap.GetIntersectingTiles(BboxWheel2), BboxWheel2.Center.Z);
1867 DrawTiles(GetWorld(), SparseMap.GetIntersectingTiles(BboxWheel3), BboxWheel3.Center.Z);
1870 TArray<float> ParticlePos0, ParticleVel0, ParticlePos1, ParticleVel1,
1871 ParticlePos2, ParticleVel2, ParticlePos3, ParticleVel3;
1872 TArray<float> WheelPos0, WheelOrient0, WheelLinVel0, WheelAngVel0;
1873 TArray<float> WheelPos1, WheelOrient1, WheelLinVel1, WheelAngVel1;
1874 TArray<float> WheelPos2, WheelOrient2, WheelLinVel2, WheelAngVel2;
1875 TArray<float> WheelPos3, WheelOrient3, WheelLinVel3, WheelAngVel3;
1877 TRACE_CPUPROFILER_EVENT_SCOPE(SetUpArrays);
1878 SetUpParticleArrays(ParticlesWheel0, ParticlePos0, ParticleVel0, WheelTransform0);
1879 SetUpParticleArrays(ParticlesWheel1, ParticlePos1, ParticleVel1, WheelTransform1);
1880 SetUpParticleArrays(ParticlesWheel2, ParticlePos2, ParticleVel2, WheelTransform2);
1881 SetUpParticleArrays(ParticlesWheel3, ParticlePos3, ParticleVel3, WheelTransform3);
1883 SetUpWheelArrays(Vehicle, 0, WheelPos0, WheelOrient0, WheelLinVel0, WheelAngVel0);
1884 SetUpWheelArrays(Vehicle, 1, WheelPos1, WheelOrient1, WheelLinVel1, WheelAngVel1);
1885 SetUpWheelArrays(Vehicle, 2, WheelPos2, WheelOrient2, WheelLinVel2, WheelAngVel2);
1886 SetUpWheelArrays(Vehicle, 3, WheelPos3, WheelOrient3, WheelLinVel3, WheelAngVel3);
1890 static_cast<int>(ParticlesWheel0.size()),
1891 ParticlePos0.GetData(), ParticleVel0.GetData(),
1892 WheelPos0.GetData(), WheelOrient0.GetData(),
1893 WheelLinVel0.GetData(), WheelAngVel0.GetData()};
1895 static_cast<int>(ParticlesWheel1.size()),
1896 ParticlePos1.GetData(), ParticleVel1.GetData(),
1897 WheelPos1.GetData(), WheelOrient1.GetData(),
1898 WheelLinVel1.GetData(), WheelAngVel1.GetData()};
1900 static_cast<int>(ParticlesWheel2.size()),
1901 ParticlePos2.GetData(), ParticleVel2.GetData(),
1902 WheelPos2.GetData(), WheelOrient2.GetData(),
1903 WheelLinVel2.GetData(), WheelAngVel2.GetData()};
1905 static_cast<int>(ParticlesWheel3.size()),
1906 ParticlePos3.GetData(), ParticleVel3.GetData(),
1907 WheelPos3.GetData(), WheelOrient3.GetData(),
1908 WheelLinVel3.GetData(), WheelAngVel3.GetData()};
1911 ASoilTypeManager* SoilTypeManagerActor = Cast<ASoilTypeManager>(UGameplayStatics::GetActorOfClass(GetWorld(), ASoilTypeManager::StaticClass()));
1912 if(SoilTypeManagerActor)
1931 SoilType, NNVerbose};
1934 NNInput.terrain_type = -1;
1938 NNInput.throttle *= -1;
1940 TerramechanicsModel.SetInputs(NNInput);
1942 TRACE_CPUPROFILER_EVENT_SCOPE(RunModel);
1945 TerramechanicsModel.ForwardCUDATensors();
1947 else if(bUseDynamicModel)
1949 TerramechanicsModel.ForwardDynamic();
1953 TerramechanicsModel.Forward();
1958 if(bUpdateParticles)
1961 TRACE_CPUPROFILER_EVENT_SCOPE(UpdateParticles);
1962 FScopeLock ScopeLock(&SparseMap.Lock_Particles);
1963 auto UpdateFutureParticles =
1964 [&] (std::vector<FParticle*>& Particles, std::vector<float>& Forces,
float DeltaTime,
1965 const FTransform& WheelTransform)
1967 UpdateParticles( Particles, Forces, DeltaTime, WheelTransform );
1969 UpdateFutureParticles(
1971 UpdateFutureParticles(
1973 UpdateFutureParticles(
1975 UpdateFutureParticles(
1980 FLinearColor
Color(1.0,0.0,1.0,1.0);
1981 DrawParticles(GetWorld(), ParticlesWheel0, Color);
1982 DrawParticles(GetWorld(), ParticlesWheel1, Color);
1983 DrawParticles(GetWorld(), ParticlesWheel2, Color);
1984 DrawParticles(GetWorld(), ParticlesWheel3, Color);
1988 if(bUseMeanAcceleration)
1990 ApplyMeanAccelerationToVehicle(Vehicle,
2010 ApplyForcesToVehicle(Vehicle,
2047 void UCustomTerrainPhysicsComponent::UpdateParticles(
2048 std::vector<FParticle*> Particles, std::vector<float> Forces,
2049 float DeltaTime,
const FTransform& WheelTransform)
2051 TRACE_CPUPROFILER_EVENT_SCOPE(UpdateParticles);
2055 for (
size_t i = 0; i < Particles.size(); i++)
2057 FVector Force = FVector(Forces[3*i + 0], Forces[3*i + 1], Forces[3*i + 2]) * ParticleForceMulFactor;
2058 FVector LocalAcceleration = Force;
2059 FVector UELocalAcceleration =
SIToUEFrame(LocalAcceleration);
2060 FVector UEGlobalAcceleration = WheelTransform.TransformVector(UELocalAcceleration);
2061 FVector Acceleration =
UEFrameToSI(UEGlobalAcceleration);
2069 for (
size_t i = 0; i < Particles.size(); i++)
2071 FVector Force = FVector(Forces[3*i + 0], Forces[3*i + 1], Forces[3*i + 2]) * ParticleForceMulFactor;
2073 FVector Acceleration = Force;
2080 void UCustomTerrainPhysicsComponent::UpdateParticlesDebug( std::vector<FParticle*> Particles)
2082 TRACE_CPUPROFILER_EVENT_SCOPE(UpdateParticles);
2083 float DeltaTime = GetWorld()->GetDeltaSeconds();
2084 for (
size_t i = 0; i < Particles.size(); i++)
2086 FVector Force = FVector( 0, 0, FMath::RandRange(-1.0f, 1.0f));
2088 FVector Acceleration = Force;
2094 void UCustomTerrainPhysicsComponent::OnLevelAddedToWorld(ULevel* InLevel, UWorld* InWorld)
2096 if( bRemoveLandscapeColliders )
2098 for(
auto CurrentActor : InLevel->Actors)
2100 if( ALandscape* CurrentLandscape = Cast<ALandscape>( CurrentActor ) )
2102 CurrentLandscape->BodyInstance.ReplaceResponseToChannels( ECollisionResponse::ECR_Block, ECollisionResponse::ECR_Ignore );
2103 CurrentLandscape->BodyInstance.ReplaceResponseToChannels( ECollisionResponse::ECR_Overlap, ECollisionResponse::ECR_Ignore );
2104 CurrentLandscape->BodyInstance.SetCollisionEnabled( ECollisionEnabled::Type::NoCollision,
true);
2106 for(
auto CurrentCollision : CurrentLandscape->CollisionComponents){
2107 CurrentCollision->SetCollisionResponseToAllChannels( ECollisionResponse::ECR_Ignore );
2108 CurrentCollision->SetCollisionEnabled( ECollisionEnabled::Type::NoCollision );
2112 for(
auto CurrentComponent : CurrentLandscape->LandscapeComponents){
2113 CurrentComponent->SetCollisionResponseToAllChannels( ECollisionResponse::ECR_Ignore );
2114 CurrentComponent->SetCollisionEnabled( ECollisionEnabled::Type::NoCollision );
2122 void UCustomTerrainPhysicsComponent::UpdateTilesHeightMaps(
2123 const std::vector<FParticle*>& Particles)
2125 TRACE_CPUPROFILER_EVENT_SCOPE(UpdateTilesHeightMaps);
2127 uint32_t PartialHeightMapSize =
2128 SparseMap.GetTileSize() * TextureToUpdate->GetSizeX() / (2*TextureRadius);
2129 float InverseTileSize = 1.f/SparseMap.GetTileSize();
2130 float Transformation = InverseTileSize * PartialHeightMapSize;
2131 float ParticlesInARowInHeightMap = TextureToUpdate->GetSizeX() / (TextureRadius * 2);
2132 for (
size_t i = 0; i < Particles.size(); i++)
2135 uint64_t TileId = SparseMap.GetTileId(P->
Position);
2136 FDenseTile& CurrentTile = SparseMap.GetTile(TileId);
2139 FIntVector HeightMapCoords = FIntVector(
2140 ParticleLocalPosition.
X * Transformation,
2141 ParticleLocalPosition.
Y * Transformation, 0);
2143 HeightMapCoords.X =
std::min( std::max( HeightMapCoords.X, 0) , static_cast<int>(PartialHeightMapSize-1));
2144 HeightMapCoords.Y =
std::min( std::max( HeightMapCoords.Y, 0) , static_cast<int>(PartialHeightMapSize-1));
2145 uint32_t Index = HeightMapCoords.Y * PartialHeightMapSize + HeightMapCoords.X;
2152 void UCustomTerrainPhysicsComponent::RemoveParticlesFromOrderedContainer(
2153 const std::vector<FParticle*>& Particles)
2155 TRACE_CPUPROFILER_EVENT_SCOPE(RemoveParticlesFromOrderedContainer);
2157 uint32_t PartialHeightMapSize =
2158 SparseMap.GetTileSize() * TextureToUpdate->GetSizeX() / (2*TextureRadius);
2159 float InverseTileSize = 1.f/SparseMap.GetTileSize();
2160 float Transformation = InverseTileSize * PartialHeightMapSize;
2161 float ParticlesInARowInHeightMap = TextureToUpdate->GetSizeX() / (TextureRadius * 2);
2162 for (
size_t i = 0; i < Particles.size(); i++)
2165 uint64_t TileId = SparseMap.GetTileId(P->
Position);
2166 FDenseTile& CurrentTile = SparseMap.GetTile(TileId);
2170 FIntVector HeightMapCoords = FIntVector(
2171 ParticleLocalPosition.
X * Transformation,
2172 ParticleLocalPosition.
Y * Transformation, 0);
2174 HeightMapCoords.X =
std::min( std::max( HeightMapCoords.X, 0) , static_cast<int>(PartialHeightMapSize-1));
2175 HeightMapCoords.Y =
std::min( std::max( HeightMapCoords.Y, 0) , static_cast<int>(PartialHeightMapSize-1));
2177 uint32_t Index = HeightMapCoords.Y * PartialHeightMapSize + HeightMapCoords.X;
2195 UE_LOG(LogCarla, Error, TEXT(
"Cannot Remove more from %d, currentsize %d Tile : %s"), Index,CurrentTile.
ParticlesZOrdered[Index].size(), *(TilePosition.
ToString()) );
2200 UE_LOG(LogCarla, Error, TEXT(
"RemoveParticlesFromOrderedContainer Invalid Index %d ZOrderedSize %d Tile: %s"), Index,CurrentTile.
ParticlesZOrdered.size(), *(TilePosition.
ToString()) );
2205 void UCustomTerrainPhysicsComponent::AddParticlesToOrderedContainer(
2206 const std::vector<FParticle*>& Particles)
2208 TRACE_CPUPROFILER_EVENT_SCOPE(AddParticlesToOrderedContainer);
2210 uint32_t PartialHeightMapSize =
2211 SparseMap.GetTileSize() * TextureToUpdate->GetSizeX() / (2*TextureRadius);
2212 float InverseTileSize = 1.f/SparseMap.GetTileSize();
2213 float Transformation = InverseTileSize * PartialHeightMapSize;
2214 float ParticlesInARowInHeightMap = TextureToUpdate->GetSizeX() / (TextureRadius * 2);
2215 for (
size_t i = 0; i < Particles.size(); i++)
2218 uint64_t TileId = SparseMap.GetTileId(P->
Position);
2219 FDenseTile& CurrentTile = SparseMap.GetTile(TileId);
2223 FIntVector HeightMapCoords = FIntVector(
2224 std::floor(ParticleLocalPosition.
X * Transformation),
2225 std::floor(ParticleLocalPosition.
Y * Transformation), 0);
2228 uint32_t Index = HeightMapCoords.Y * PartialHeightMapSize + HeightMapCoords.X;
2237 UE_LOG(LogCarla, Error, TEXT(
"RemoveParticlesFromOrderedContainer Invalid Index %d ZOrderedSize %d Tile: %s"), Index,CurrentTile.
ParticlesZOrdered.size(), *(TilePosition.
ToString()) );
2243 void UCustomTerrainPhysicsComponent::FlagTilesToRedoOrderedContainer(
2244 const std::vector<FParticle*>& Particles)
2246 TRACE_CPUPROFILER_EVENT_SCOPE(AddParticlesToOrderedContainer);
2248 uint32_t PartialHeightMapSize =
2249 SparseMap.GetTileSize() * TextureToUpdate->GetSizeX() / (2*TextureRadius);
2250 float InverseTileSize = 1.f/SparseMap.GetTileSize();
2251 float Transformation = InverseTileSize * PartialHeightMapSize;
2252 float ParticlesInARowInHeightMap = TextureToUpdate->GetSizeX() / (TextureRadius * 2);
2253 for (
size_t i = 0; i < Particles.size(); i++)
2256 uint64_t TileId = SparseMap.GetTileId(P->
Position);
2257 FDenseTile& CurrentTile = SparseMap.GetTile(TileId);
2264 void UCustomTerrainPhysicsComponent::UpdateTilesHeightMapsInRadius(
FDVector Position, uint32 Rad )
2266 TRACE_CPUPROFILER_EVENT_SCOPE(UpdateTilesHeightMapsInRadius);
2269 uint32_t Tile_X = (uint32_t)(TileId >> 32);
2270 uint32_t Tile_Y = (uint32_t)(TileId & (uint32_t)(~0));
2271 uint32_t RadiusInTiles = (Rad/TileSize);
2274 uint32_t MinX = Tile_X - RadiusInTiles;
2275 uint32_t MinY = Tile_Y - RadiusInTiles;
2276 uint32_t MaxX = Tile_X + RadiusInTiles;
2277 uint32_t MaxY = Tile_Y + RadiusInTiles;
2279 for( uint32_t X = MinX; X <= MaxX; ++X )
2281 for( uint32_t Y = MinY; Y <= MaxY; ++Y )
2283 uint64_t CurrentTileId = SparseMap.GetTileId(X,Y);
2284 if( SparseMap.Map.count(CurrentTileId) )
2286 SparseMap.GetTile(X, Y).UpdateLocalHeightmap();
2292 void UCustomTerrainPhysicsComponent::AddForceToSingleWheel( USkeletalMeshComponent* SkeletalMeshComponent, FVector WheelPosition, FVector WheelNormalForce )
2294 FVector WheelBottomLocation = WheelPosition - FVector(0,0, 0.337);
2295 float OriginalHeight = SparseMap.GetHeight(WheelPosition);
2296 float NewFloorHeight = OriginalHeight -
UEFrameToSI(TerrainDepth);
2298 if( WheelNormalForce.Size() == 0 ){
2299 WheelNormalForce = FVector::UpVector;
2302 float ForceFactor = ( WheelBottomLocation.Z - OriginalHeight ) / ( NewFloorHeight - OriginalHeight );
2303 if( ForceFactor < 0){
2307 SkeletalMeshComponent->AddForceAtLocationLocal(WheelPosition,
SIToUEFrame(WheelNormalForce) * ( ForceFactor * NormalForceIntensity) );
2310 void UCustomTerrainPhysicsComponent::ApplyForcesToVehicle(
2312 FVector ForceWheel0, FVector ForceWheel1, FVector ForceWheel2, FVector ForceWheel3,
2313 FVector TorqueWheel0, FVector TorqueWheel1, FVector TorqueWheel2, FVector TorqueWheel3)
2315 TRACE_CPUPROFILER_EVENT_SCOPE(UCustomTerrainPhysicsComponent::ApplyForcesToVehicle);
2317 FTransform VehicleTransform = Vehicle->GetTransform();
2318 FVector WheelPosition0 = VehicleTransform.TransformPosition(FVector(140, -70, 40));
2319 FVector WheelPosition1 = VehicleTransform.TransformPosition(FVector(140, 70, 40));
2320 FVector WheelPosition2 = VehicleTransform.TransformPosition(FVector(-140, -70, 40));
2321 FVector WheelPosition3 = VehicleTransform.TransformPosition(FVector(-140, 70, 40));
2323 Cast<UPrimitiveComponent>(Vehicle->GetRootComponent());
2324 if(!PrimitiveComponent)
2326 UE_LOG(LogCarla, Error, TEXT(
"ApplyForcesToVehicle Vehicle does not contain UPrimitiveComponent"));
2329 if(bDisableVehicleGravity && PrimitiveComponent->IsGravityEnabled())
2331 PrimitiveComponent->SetEnableGravity(
false);
2335 ForceWheel0 = VehicleTransform.TransformVector(ForceWheel0);
2336 ForceWheel1 = VehicleTransform.TransformVector(ForceWheel1);
2337 ForceWheel2 = VehicleTransform.TransformVector(ForceWheel2);
2338 ForceWheel3 = VehicleTransform.TransformVector(ForceWheel3);
2340 ForceWheel0 = ForceWheel0.GetClampedToMaxSize(MaxForceMagnitude);
2341 ForceWheel1 = ForceWheel1.GetClampedToMaxSize(MaxForceMagnitude);
2342 ForceWheel2 = ForceWheel2.GetClampedToMaxSize(MaxForceMagnitude);
2343 ForceWheel3 = ForceWheel3.GetClampedToMaxSize(MaxForceMagnitude);
2347 PrimitiveComponent->AddImpulseAtLocation(ForceWheel0, WheelPosition0);
2348 PrimitiveComponent->AddImpulseAtLocation(ForceWheel1, WheelPosition1);
2349 PrimitiveComponent->AddImpulseAtLocation(ForceWheel2, WheelPosition2);
2350 PrimitiveComponent->AddImpulseAtLocation(ForceWheel3, WheelPosition3);
2354 PrimitiveComponent->AddForceAtLocationLocal(ForceWheel0, FVector(140, -70, 40));
2355 PrimitiveComponent->AddForceAtLocationLocal(ForceWheel1, FVector(140, 70, 40));
2356 PrimitiveComponent->AddForceAtLocationLocal(ForceWheel2, FVector(-140, -70, 40));
2357 PrimitiveComponent->AddForceAtLocationLocal(ForceWheel3, FVector(-140, 70, 40));
2360 PrimitiveComponent->AddTorqueInRadians(TorqueWheel0);
2361 PrimitiveComponent->AddTorqueInRadians(TorqueWheel1);
2362 PrimitiveComponent->AddTorqueInRadians(TorqueWheel2);
2363 PrimitiveComponent->AddTorqueInRadians(TorqueWheel3);
2364 if (DrawDebugInfo && bShowForces)
2366 float LifeTime = 0.3f;
2367 bool bPersistentLines =
false;
2368 bool bDepthIsForeground = (0 == SDPG_Foreground);
2369 UWorld * World = GetWorld();
2370 ULineBatchComponent* LineBatcher =
2371 (World ? (bDepthIsForeground ? World->ForegroundLineBatcher :
2372 (( bPersistentLines || (LifeTime > 0.f) ) ? World->PersistentLineBatcher : World->LineBatcher)) :
nullptr);
2375 UE_LOG(LogCarla, Error, TEXT(
"Missing linebatcher"));
2377 LineBatcher->DrawLine(WheelPosition0 + FVector(0,0,50),
2378 WheelPosition0 + FVector(0,0,50)+ ForceWheel0.GetSafeNormal()*(5 + ForceMulFactor*10*ForceWheel0.Size()),
2379 FLinearColor(0.0,1.0,0.0), 0, 3.0, 0.3);
2380 LineBatcher->DrawLine(WheelPosition1 + FVector(0,0,50),
2381 WheelPosition1 + FVector(0,0,50)+ ForceWheel1.GetSafeNormal()*(5 + ForceMulFactor*10*ForceWheel1.Size()),
2382 FLinearColor(0.0,1.0,0.0), 0, 3.0, 0.3);
2383 LineBatcher->DrawLine(WheelPosition2 + FVector(0,0,50),
2384 WheelPosition2 + FVector(0,0,50)+ ForceWheel2.GetSafeNormal()*(5 + ForceMulFactor*10*ForceWheel2.Size()),
2385 FLinearColor(0.0,1.0,0.0), 0, 3.0, 0.3);
2386 LineBatcher->DrawLine(WheelPosition3 + FVector(0,0,50),
2387 WheelPosition3 + FVector(0,0,50)+ ForceWheel3.GetSafeNormal()*(5 + ForceMulFactor*10*ForceWheel3.Size()),
2388 FLinearColor(0.0,1.0,0.0), 0, 3.0, 0.3);
2392 void UCustomTerrainPhysicsComponent::ApplyMeanAccelerationToVehicle(
2394 FVector ForceWheel0, FVector ForceWheel1, FVector ForceWheel2, FVector ForceWheel3)
2396 TRACE_CPUPROFILER_EVENT_SCOPE(UCustomTerrainPhysicsComponent::ApplyForcesToVehicle);
2397 FVector MeanAcceleration = (ForceWheel0 + ForceWheel1 + ForceWheel2 + ForceWheel3)/4.f;
2399 Cast<UPrimitiveComponent>(Vehicle->GetRootComponent());
2400 if (!PrimitiveComponent)
2402 UE_LOG(LogCarla, Error, TEXT(
"ApplyMeanAccelerationToVehicle Vehicle does not contain UPrimitiveComponent"));
2405 if(bDisableVehicleGravity && PrimitiveComponent->IsGravityEnabled())
2407 PrimitiveComponent->SetEnableGravity(
false);
2411 FTransform VehicleTransform = Vehicle->GetTransform();
2412 MeanAcceleration = VehicleTransform.TransformVector(MeanAcceleration);
2414 PrimitiveComponent->AddForce(MeanAcceleration, FName(
""),
true);
2416 if (DrawDebugInfo && bShowForces)
2418 float LifeTime = 0.3f;
2419 bool bPersistentLines =
false;
2420 bool bDepthIsForeground = (0 == SDPG_Foreground);
2421 UWorld * World = GetWorld();
2422 ULineBatchComponent* LineBatcher =
2423 (World ? (bDepthIsForeground ? World->ForegroundLineBatcher :
2424 (( bPersistentLines || (LifeTime > 0.f) ) ? World->PersistentLineBatcher : World->LineBatcher)) :
nullptr);
2427 UE_LOG(LogCarla, Error, TEXT(
"Missing linebatcher"));
2429 LineBatcher->DrawLine(PrimitiveComponent->GetComponentLocation() + FVector(0,0,200),
2430 PrimitiveComponent->GetComponentLocation() + FVector(0,0,200)+ MeanAcceleration.GetSafeNormal()*(1 + MeanAcceleration.Size()),
2431 FLinearColor(0.0,1.0,0.0), 0, 3.0, 0.3);
2435 TArray<FVector> UCustomTerrainPhysicsComponent::GetParticlesInRadius(FVector Position,
float InRadius)
2437 std::vector<FParticle*> Particles = SparseMap.GetParticlesInRadius(
UEFrameToSI(Position), InRadius*
CMToM);
2438 TArray<FVector> ParticlePositions;
2441 ParticlePositions.Add(
SIToUEFrame(Particle->Position.ToFVector()));
2443 return ParticlePositions;
2446 TArray<FVector> UCustomTerrainPhysicsComponent::GetParticlesInTileRadius(FVector Position,
float InRadius)
2448 std::vector<FParticle*> Particles = SparseMap.GetParticlesInTileRadius(
UEFrameToSI(Position), InRadius*
CMToM);
2449 TArray<FVector> ParticlePositions;
2452 ParticlePositions.Add(
SIToUEFrame(Particle->Position.ToFVector()));
2454 return ParticlePositions;
2458 FVector UCustomTerrainPhysicsComponent::GetTileCenter(FVector Position)
2461 SparseMap.GetTilePosition(
2462 SparseMap.GetTileId(
2466 void UCustomTerrainPhysicsComponent::SetUpParticleArrays(std::vector<FParticle*>& ParticlesIn,
2467 TArray<float>& ParticlePosOut,
2468 TArray<float>& ParticleVelOut,
2469 const FTransform &WheelTransform)
2471 ParticlePosOut.Empty();
2472 ParticleVelOut.Empty();
2473 ParticlePosOut.Reserve(ParticlesIn.size()*3);
2474 ParticleVelOut.Reserve(ParticlesIn.size()*3);
2477 const FTransform InverseTransform = WheelTransform.Inverse();
2480 FVector UEPosition =
SIToUEFrame(Particle->Position.ToFVector());
2481 FVector UELocalPosition = InverseTransform.TransformPosition(UEPosition);
2483 ParticlePosOut.Add(static_cast<float>(Position.X));
2484 ParticlePosOut.Add(static_cast<float>(Position.Y));
2485 ParticlePosOut.Add(static_cast<float>(Position.Z));
2486 ParticleVelOut.Add(Particle->Velocity.X);
2487 ParticleVelOut.Add(Particle->Velocity.Y);
2488 ParticleVelOut.Add(Particle->Velocity.Z);
2490 if(ParticlesIn.size() < MaxParticlesPerWheel)
2492 for (
int i = 0; i < (MaxParticlesPerWheel - ParticlesIn.size()); ++i)
2494 ParticlePosOut.Add(0.f);
2495 ParticlePosOut.Add(0.f);
2496 ParticlePosOut.Add(0.f);
2497 ParticleVelOut.Add(0.f);
2498 ParticleVelOut.Add(0.f);
2499 ParticleVelOut.Add(0.f);
2507 ParticlePosOut.Add(static_cast<float>(Particle->Position.X));
2508 ParticlePosOut.Add(static_cast<float>(Particle->Position.Y));
2509 ParticlePosOut.Add(static_cast<float>(Particle->Position.Z));
2510 ParticleVelOut.Add(Particle->Velocity.X);
2511 ParticleVelOut.Add(Particle->Velocity.Y);
2512 ParticleVelOut.Add(Particle->Velocity.Z);
2514 if(ParticlesIn.size() < MaxParticlesPerWheel)
2516 FVector WheelPosition =
UEFrameToSI(WheelTransform.GetLocation());
2517 for (
int i = 0; i < (MaxParticlesPerWheel - ParticlesIn.size()); ++i)
2519 ParticlePosOut.Add(WheelPosition.X);
2520 ParticlePosOut.Add(WheelPosition.Y);
2521 ParticlePosOut.Add(WheelPosition.Z);
2522 ParticleVelOut.Add(0.f);
2523 ParticleVelOut.Add(0.f);
2524 ParticleVelOut.Add(0.f);
2530 void UCustomTerrainPhysicsComponent::SetUpWheelArrays(
ACarlaWheeledVehicle *Vehicle,
int WheelIdx,
2531 TArray<float>& WheelPos,
2532 TArray<float>& WheelOrientation,
2533 TArray<float>& WheelLinearVelocity,
2534 TArray<float>& WheelAngularVelocity)
2536 FTransform VehicleTransform = Vehicle->GetTransform();
2542 Position = FVector(140, -70, 40);
2545 Position = FVector(140, 70, 40);
2548 Position = FVector(-140, -70, 40);
2552 Position = FVector(-140, 70, 40);
2555 FVector PhysAngularVelocity = Vehicle->GetMesh()->GetPhysicsAngularVelocityInRadians();
2559 FTransform InverseTransform = VehicleTransform.Inverse();
2560 Position = FVector(0,0,0);
2562 InverseTransform.TransformVector(Vehicle->
GetVelocity()));
2563 WheelPos = {Position.X, Position.Y, Position.Z};
2565 WheelOrientation = {1.f, 0.f, 0.f, 0.f};
2566 WheelLinearVelocity = {Velocity.X, Velocity.Y, Velocity.Z};
2567 FVector LocalAngularVelocity = InverseTransform.TransformVector(PhysAngularVelocity);
2569 float ForwardSpeed = Velocity.X;
2570 float AngularSpeed = (ForwardSpeed/(
CMToM*TireRadius));
2571 WheelAngularVelocity = {
2572 LocalAngularVelocity.X,
2573 AngularSpeed + LocalAngularVelocity.Y,
2574 -LocalAngularVelocity.Z};
2578 Position = VehicleTransform.TransformPosition(Position);
2581 Position = LargeMapManager->LocalToGlobalLocation(Position);
2584 float ForwardSpeed = FVector::DotProduct(
2585 Vehicle->
GetVelocity(),VehicleTransform.GetRotation().GetForwardVector());
2587 WheelPos = {Position.X, Position.Y, Position.Z};
2588 FQuat Quat = VehicleTransform.GetRotation();
2591 WheelOrientation = {Quat.W,Quat.X,-Quat.Y,Quat.Z};
2592 WheelLinearVelocity = {Velocity.X, Velocity.Y, Velocity.Z};
2593 float AngularSpeed = (ForwardSpeed)/(TireRadius);
2594 FVector GlobalAngulaSpeed = VehicleTransform.TransformVector(FVector(0, AngularSpeed, 0));
2595 PhysAngularVelocity = PhysAngularVelocity + GlobalAngulaSpeed;
2596 WheelAngularVelocity = {
2597 PhysAngularVelocity.X,
2598 PhysAngularVelocity.Y,
2599 -PhysAngularVelocity.Z};
2604 void UCustomTerrainPhysicsComponent::AddForces(
2605 const TArray<FForceAtLocation> &Forces)
2609 ForcesToApply.Add(Force);
2613 void UCustomTerrainPhysicsComponent::ApplyForces()
2617 RootComponent->AddForceAtLocationLocal(Force.Force, Force.Location);
2619 ForcesToApply.Empty();
2622 void UCustomTerrainPhysicsComponent::UpdateMaps(
2623 FVector Position,
float RadiusX,
float RadiusY,
float CacheRadiusX,
float CacheRadiusY)
2631 CustomTerrainComp = TerrainComp;
2632 Position = NewPosition;
2633 RadiusX = NewRadiusX;
2634 RadiusY = NewRadiusY;
2639 CustomTerrainComp =
nullptr;
2645 FDateTime CacheCurrentTime = FDateTime::Now();
2646 FDateTime LoadTilesCurrentTime = FDateTime::Now();
2647 FDateTime UnloadTilesCurrentTime = FDateTime::Now();
2649 while(bShouldContinue){
2650 FVector LastPosition = CustomTerrainComp->LastUpdatedPosition;
2651 if(Position != LastPosition)
2653 Position = LastPosition;
2654 CustomTerrainComp->UpdateMaps(CustomTerrainComp->LastUpdatedPosition,
2655 CustomTerrainComp->TileRadius.X, CustomTerrainComp->TileRadius.Y,
2656 CustomTerrainComp->CacheRadius.X, CustomTerrainComp->CacheRadius.Y);
2658 if(!bShouldContinue)
void GetParticlesInBox(const FOrientedBox &OBox, std::vector< FParticle *> &ParticlesInRadius)
virtual uint32 Run() override
bool bParticlesZOrderedInitialized
FCarlaActor * FindCarlaActor(FCarlaActor::IdType ActorId)
Find a Carla actor by id.
void InitializeMap(UHeightMapDataAsset *DataAsset, FDVector Origin, FDVector MapSize, float Size, float ScaleZ)
std::vector< FParticle * > GetParticlesInRadius(FDVector Position, float Radius)
void Update(FVector Position, float RadiusX, float RadiusY)
void UpdateLocalHeightmap()
float GetHeight(FDVector Position) const
sensor::data::Color Color
std::vector< float > _particle_forces
virtual FVector GetVelocity() const override
void GetAllParticles(std::vector< FParticle *> &ParticlesInRadius)
void InitializeHeightmap(UHeightMapDataAsset *DataAsset, FDVector Size, FDVector Origin, FDVector Tile0, float ScaleZ)
FDVector GetTilePosition(uint64_t TileId)
FSoilTerramechanicsProperties GetTerrainPropertiesAtGlobalLocation(FVector VehicleLocation)
FVector UEFrameToSI(const FVector &In)
static bool ActorAttributeToBool(const FActorAttribute &ActorAttribute, bool Default)
============================================================================ – Helpers to retrieve a...
void InitializeTile(uint32_t TextureSize, float AffectedRadius, float ParticleSize, float Depth, FDVector TileOrigin, FDVector TileEnd, const FString &SavePath, const FHeightMapData &HeightMap)
std::vector< uint64_t > GetLoadedTilesInRange(FDVector Position, float Radius)
void ReadFVector(std::istream &InFile, FVector &OutObj)
std::vector< std::multiset< float, std::greater< float > > > ParticlesZOrdered
std::vector< FParticle * > GetParticlesInRadius(FDVector Position, float Radius)
std::vector< cg::Location > Path
FIntVector GetVectorTileId(FDVector Position)
FTilesWorker(class UCustomTerrainPhysicsComponent *TerrainComp, FVector NewPosition, float NewRadiusX, float NewRadiusY)
std::string _filesBaseFolder
FDenseTile & InitializeRegionInCache(uint64_t TileId)
static T Get(carla::rpc::Response< T > &response)
TEnumAsByte< ESoilTerramechanicsType > TerrainType
TArray< float > HeightValues
FVector ToFVector() const
TMap< FString, FActorAttribute > Variations
User selected variations of the actor.
void UpdateHeightMap(UHeightMapDataAsset *DataAsset, FDVector Origin, FDVector MapSize, float Size, float ScaleZ)
const int CacheExtraRadius
double min(double v1, double v2)
std::vector< float > ParticlesHeightMap
FDenseTile & InitializeRegion(uint32_t Tile_X, uint32_t Tile_Y)
virtual ~FTilesWorker() override
FVector UEFrameToSIDirection(const FVector &In)
const FVehicleControl & GetVehicleControl() const
Vehicle control currently applied to this vehicle.
void UpdateMaps(FDVector Position, float RadiusX, float RadiusY, float CacheRadiusX, float CacheRadiusY)
FDenseTile & operator=(FDenseTile &&Origin)
A description of a Carla Actor with all its variation.
FActorDescription Description
bool bHeightmapNeedToUpdate
void WriteFVector(std::ostream &OutFile, const FVector &InObj)
FDenseTile & GetTile(uint32_t Tile_X, uint32_t Tile_Y)
FVector SIToUEFrameDirection(const FVector &In)
uint64_t GetTileId(uint32_t Tile_X, uint32_t Tile_Y)
static UCarlaEpisode * GetCurrentEpisode(const UObject *WorldContextObject)
static ALargeMapManager * GetLargeMapManager(const UObject *WorldContextObject)
std::vector< FParticle > Particles
A view over an actor and its properties.
void InitializeDataStructure()
std::vector< FParticle * > GetParticlesInTileRadius(FDVector Position, float Radius)
std::vector< float > Pixels
std::vector< uint64_t > GetIntersectingTiles(const FOrientedBox &OBox)
Base class for CARLA wheeled vehicles.
std::vector< FParticle * > GetParticlesInBox(const FOrientedBox &OBox)
An actor attribute, may be an intrinsic (non-modifiable) attribute of the actor or an user-defined ac...
void sort(I begin, I end, const Pred &pred)
FVector SIToUEFrame(const FVector &In)
A view over an actor and its properties.