diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaGameModeBase.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaGameModeBase.cpp index 4314b9b4d..b0cc6b63e 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaGameModeBase.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaGameModeBase.cpp @@ -195,7 +195,7 @@ void ACarlaGameModeBase::BeginPlay() // OnBeginFrame // OnEndFrame - CaptureAtlasDelegate = FCoreDelegates::OnEndFrame.AddUObject(this, &ACarlaGameModeBase::CaptureAtlas); + CaptureAtlasDelegate = FCoreDelegates::OnBeginFrame.AddUObject(this, &ACarlaGameModeBase::CaptureAtlas); // SendAtlasDelegate = FCoreDelegates::OnEndFrame.AddUObject(this, &ACarlaGameModeBase::SendAtlas); } @@ -209,7 +209,6 @@ void ACarlaGameModeBase::Tick(float DeltaSeconds) { Recorder->Tick(DeltaSeconds); } - } void ACarlaGameModeBase::EndPlay(const EEndPlayReason::Type EndPlayReason) @@ -225,6 +224,7 @@ void ACarlaGameModeBase::EndPlay(const EEndPlayReason::Type EndPlayReason) } // TODO: improve this delete processs; not multithread friendly + /* while(!AtlasCopyRequestQueue.IsEmpty()) { delete AtlasCopyRequestQueue.Peek(); @@ -236,6 +236,7 @@ void ACarlaGameModeBase::EndPlay(const EEndPlayReason::Type EndPlayReason) delete AtlasCopyRequestsQueuePool.Peek(); AtlasCopyRequestsQueuePool.Pop(); } + */ // OnEndFrame @@ -395,7 +396,7 @@ void ACarlaGameModeBase::DebugShowSignals(bool enable) } } - +/* FAtlasCopyRequest* ACarlaGameModeBase::GetAtlasCopyRequest() { if(AtlasCopyRequestsQueuePool.IsEmpty()) { @@ -406,7 +407,7 @@ FAtlasCopyRequest* ACarlaGameModeBase::GetAtlasCopyRequest() AtlasCopyRequestsQueuePool.Dequeue(AtlasCopyRequest); return AtlasCopyRequest; } - + */ void ACarlaGameModeBase::CreateAtlasTextures() { if(AtlasTextureWidth > 0 && AtlasTextureHeight > 0) @@ -414,17 +415,19 @@ void ACarlaGameModeBase::CreateAtlasTextures() UE_LOG(LogCarla, Warning, TEXT("ACarlaGameModeBase::CreateAtlasTextures %d %dx%d"), SceneCaptureSensors.Num(), AtlasTextureWidth, AtlasTextureHeight); FRHIResourceCreateInfo CreateInfo; + CamerasAtlasTexture = RHICreateTexture2D(AtlasTextureWidth, AtlasTextureHeight, PF_B8G8R8A8, 1, 1, TexCreate_CPUReadback, CreateInfo); + for(int i = 0; i < kMaxNumTextures; i++) { - CamerasAtlasTexture[i] = RHICreateTexture2D(AtlasTextureWidth, AtlasTextureHeight, PF_B8G8R8A8, 1, 1, TexCreate_CPUReadback, CreateInfo); + AtlasImage[i].Init(FColor(), AtlasTextureWidth * AtlasTextureHeight); // Prepare some AtlasCopyRequests - AtlasCopyRequestQueue.Enqueue(new FAtlasCopyRequest()); + //AtlasCopyRequestQueue.Enqueue(new FAtlasCopyRequest()); } IsAtlasTextureValid = true; } } -extern FDynamicRHI* GDynamicRHI; +//extern FDynamicRHI* GDynamicRHI; void ACarlaGameModeBase::CaptureAtlas() { @@ -452,15 +455,15 @@ void ACarlaGameModeBase::CaptureAtlas() //} //UE_LOG(LogCarla, Warning, TEXT("ACarlaGameModeBase::CaptureAtlas: creating request")); - FAtlasCopyRequest* AtlasCopyRequest = GetAtlasCopyRequest(); - AtlasCopyRequest->ResizeBuffer(AtlasTextureWidth, AtlasTextureHeight); + //FAtlasCopyRequest* AtlasCopyRequest = GetAtlasCopyRequest(); + //AtlasCopyRequest->ResizeBuffer(AtlasTextureWidth, AtlasTextureHeight); // Download Atlas texture ENQUEUE_RENDER_COMMAND(ACarlaGameModeBase_CaptureAtlas) ( - [This, &CurrentAtlasPixels = AtlasCopyRequest->AtlasImage](FRHICommandListImmediate& RHICmdList) mutable + [This](FRHICommandListImmediate& RHICmdList) mutable { - FTexture2DRHIRef AtlasTexture = This->CamerasAtlasTexture[This->PreviousAtlas]; + FTexture2DRHIRef AtlasTexture = This->CamerasAtlasTexture; if (!AtlasTexture) { @@ -471,9 +474,7 @@ void ACarlaGameModeBase::CaptureAtlas() FIntRect Rect = FIntRect(0, 0, This->AtlasTextureWidth, This->AtlasTextureHeight); #if !UE_BUILD_SHIPPING - if(This->ReadSurfaceMode == 2) { - Rect = FIntRect(0, 0, This->SurfaceW, This->SurfaceH); - } + if(This->ReadSurfaceMode == 2) Rect = FIntRect(0, 0, This->SurfaceW, This->SurfaceH); #endif // GDynamicRHI->RHIReadSurfaceData(AtlasTexture, Rect, CurrentAtlasPixels, FReadSurfaceDataFlags(RCM_UNorm, CubeFace_MAX)); @@ -485,17 +486,17 @@ void ACarlaGameModeBase::CaptureAtlas() RHICmdList.ReadSurfaceData( AtlasTexture, Rect, - CurrentAtlasPixels, + This->AtlasImage[This->CurrentAtlas], FReadSurfaceDataFlags(RCM_UNorm, CubeFace_MAX)); - // This->PreviousAtlas = This->CurrentAtlas; - // This->CurrentAtlas = (This->CurrentAtlas + 1) & ~kMaxNumTextures; + This->PreviousAtlas = This->CurrentAtlas; + This->CurrentAtlas = (This->CurrentAtlas + 1) & ~kMaxNumTextures; } ); - AtlasCopyRequest->Start(); + //AtlasCopyRequest->Start(); // AtlasCopyRequest->Wait(); - AtlasCopyRequestQueue.Enqueue(AtlasCopyRequest); + //AtlasCopyRequestQueue.Enqueue(AtlasCopyRequest); SendAtlas(); @@ -503,21 +504,21 @@ void ACarlaGameModeBase::CaptureAtlas() void ACarlaGameModeBase::SendAtlas() { - if(!AtlasCopyRequestQueue.IsEmpty()) + //if(!AtlasCopyRequestQueue.IsEmpty()) { - FAtlasCopyRequest* AtlasCopyRequest = nullptr; - AtlasCopyRequestQueue.Peek(AtlasCopyRequest); + //FAtlasCopyRequest* AtlasCopyRequest = nullptr; + //AtlasCopyRequestQueue.Peek(AtlasCopyRequest); // Be sure that the request has finished - if( AtlasCopyRequest && AtlasCopyRequest->IsComplete() ) + //if( AtlasCopyRequest && AtlasCopyRequest->IsComplete() ) { //UE_LOG(LogCarla, Warning, TEXT("ACarlaGameModeBase::SendAtlas: DONE")); #if !UE_BUILD_SHIPPING if(!AtlasCopyToCamera) { - AtlasCopyRequestQueue.Pop(); - AtlasCopyRequestsQueuePool.Enqueue(AtlasCopyRequest); + //AtlasCopyRequestQueue.Pop(); + //AtlasCopyRequestsQueuePool.Enqueue(AtlasCopyRequest); return; } #endif @@ -531,16 +532,18 @@ void ACarlaGameModeBase::SendAtlas() for(int32 Index = 0; Index < SceneCaptureSensors.Num(); Index++) { ASceneCaptureSensor* Sensor = SceneCaptureSensors[Index]; - Sensor->CopyTextureFromAtlas(AtlasCopyRequest->AtlasImage, AtlasTextureWidth); + // TODO: merge this functions and avoid double copy + Sensor->CopyTextureFromAtlas(AtlasImage[PreviousAtlas], AtlasTextureWidth); + Sensor->SendPixels(); } //); // Remove from pending queue ... - AtlasCopyRequestQueue.Pop(); + //AtlasCopyRequestQueue.Pop(); // ... add to pool - AtlasCopyRequestsQueuePool.Enqueue(AtlasCopyRequest); + //AtlasCopyRequestsQueuePool.Enqueue(AtlasCopyRequest); } - else + //else { //UE_LOG(LogCarla, Error, TEXT("ACarlaGameModeBase::SendAtlas: request didn't finish")); } diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaGameModeBase.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaGameModeBase.h index b06e13d39..c07bf5808 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaGameModeBase.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Game/CarlaGameModeBase.h @@ -27,6 +27,7 @@ #include "CarlaGameModeBase.generated.h" +/* USTRUCT() struct FAtlasCopyRequest { @@ -63,6 +64,7 @@ struct FAtlasCopyRequest uint32 AtlasTextureWidth = 0u; uint32 AtlasTextureHeight = 0u; }; +*/ /// Base class for the CARLA Game Mode. @@ -101,7 +103,7 @@ public: } FTexture2DRHIRef GetCurrentCamerasAtlasTexture() const{ - return CamerasAtlasTexture[CurrentAtlas]; + return CamerasAtlasTexture; } uint32 GetAtlasTextureWidth() const { @@ -178,7 +180,7 @@ private: void ParseOpenDrive(const FString &MapName); - FAtlasCopyRequest* GetAtlasCopyRequest(); + //FAtlasCopyRequest* GetAtlasCopyRequest(); void CreateAtlasTextures(); @@ -221,13 +223,16 @@ private: FDelegateHandle CaptureAtlasDelegate; FDelegateHandle SendAtlasDelegate; - TQueue AtlasCopyRequestQueue; - TQueue AtlasCopyRequestsQueuePool; + //TQueue AtlasCopyRequestQueue; + //TQueue AtlasCopyRequestsQueuePool; // TODO: clean + + // TODO: remove kMaxNumTextures and current/prev index static const uint32 kMaxNumTextures = 1u; // This has to be POT TArray SceneCaptureSensors; - FTexture2DRHIRef CamerasAtlasTexture[kMaxNumTextures]; + FTexture2DRHIRef CamerasAtlasTexture; + TArray AtlasImage[kMaxNumTextures]; uint32 AtlasTextureWidth = 0u; uint32 AtlasTextureHeight = 0u; uint32 CurrentAtlasTextureHeight = 0u; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/DepthCamera.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/DepthCamera.cpp index 4e44cc3be..5c9eccc18 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/DepthCamera.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/DepthCamera.cpp @@ -30,10 +30,8 @@ ADepthCamera::ADepthCamera(const FObjectInitializer &ObjectInitializer) Offset = carla::sensor::SensorRegistry::get::type::header_offset; } -void ADepthCamera::Tick(float DeltaTime) +void ADepthCamera::SendPixels() { - Super::Tick(DeltaTime); - #if !UE_BUILD_SHIPPING ACarlaGameModeBase* GameMode = Cast(GetWorld()->GetAuthGameMode()); if(!GameMode->IsCameraStreamEnabled()) return; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/DepthCamera.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/DepthCamera.h index bb2fea1c1..60c450fc2 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/DepthCamera.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/DepthCamera.h @@ -26,5 +26,5 @@ public: protected: - void Tick(float DeltaTime) override; + void SendPixels() override; }; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureCamera.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureCamera.cpp index 26eace3b4..800054a47 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureCamera.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureCamera.cpp @@ -24,10 +24,8 @@ ASceneCaptureCamera::ASceneCaptureCamera(const FObjectInitializer &ObjectInitial Offset = carla::sensor::SensorRegistry::get::type::header_offset; } -void ASceneCaptureCamera::Tick(float DeltaTime) +void ASceneCaptureCamera::SendPixels() { - Super::Tick(DeltaTime); - #if !UE_BUILD_SHIPPING ACarlaGameModeBase* GameMode = Cast(GetWorld()->GetAuthGameMode()); if(!GameMode->IsCameraStreamEnabled()) return; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureCamera.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureCamera.h index 07b3c67c0..ee5d8a719 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureCamera.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureCamera.h @@ -26,6 +26,6 @@ public: protected: - void Tick(float DeltaTime) override; + void SendPixels() override; }; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureSensor.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureSensor.cpp index 2fdfb8e6b..4df292b6e 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureSensor.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureSensor.cpp @@ -565,7 +565,14 @@ void ASceneCaptureSensor::CopyTextureToAtlas() void ASceneCaptureSensor::CopyTextureFromAtlas(const TArray& AtlasImage, uint32 AtlasTextureWidth) { - if(AtlasImage.Num() > 0 && ImageToSend.Num() > 0) + // Check that the atlas alreay contains our texture + // and our image has been initialized + if(AtlasImage.Num() < (PositionInAtlas.Y * AtlasTextureWidth + ImageWidth * ImageHeight) || + ImageToSend.Num() <= 0) + { + return; + } + { SCOPE_CYCLE_COUNTER(STAT_CarlaSensorBufferCopy); diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureSensor.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureSensor.h index 2a87b571d..648337bea 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureSensor.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SceneCaptureSensor.h @@ -274,6 +274,8 @@ public: void CopyTextureFromAtlas(const TArray& AtlasImage, uint32 AtlasTextureWidth); + virtual void SendPixels() {} + template void SendPixelsInStream(TSensor &Sensor) { diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SemanticSegmentationCamera.cpp b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SemanticSegmentationCamera.cpp index a160ff825..fba0ddc95 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SemanticSegmentationCamera.cpp +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SemanticSegmentationCamera.cpp @@ -26,10 +26,8 @@ ASemanticSegmentationCamera::ASemanticSegmentationCamera( Offset = carla::sensor::SensorRegistry::get::type::header_offset; } -void ASemanticSegmentationCamera::Tick(float DeltaTime) +void ASemanticSegmentationCamera::SendPixels() { - Super::Tick(DeltaTime); - #if !UE_BUILD_SHIPPING ACarlaGameModeBase* GameMode = Cast(GetWorld()->GetAuthGameMode()); if(!GameMode->IsCameraStreamEnabled()) return; diff --git a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SemanticSegmentationCamera.h b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SemanticSegmentationCamera.h index ba614941d..dd5310385 100644 --- a/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SemanticSegmentationCamera.h +++ b/Unreal/CarlaUE4/Plugins/Carla/Source/Carla/Sensor/SemanticSegmentationCamera.h @@ -26,5 +26,5 @@ public: protected: - void Tick(float DeltaTime) override; + void SendPixels() override; };