Atlas Working
This commit is contained in:
parent
477ae9d2c8
commit
67b9d7d0d2
|
@ -83,13 +83,6 @@ public:
|
|||
return GenerationParameters;
|
||||
}
|
||||
|
||||
|
||||
UFUNCTION(Exec)
|
||||
void SwitchReadSurface() {
|
||||
extern bool ReadSurface;
|
||||
ReadSurface = !ReadSurface;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
UPROPERTY(Category = "CARLA Settings", EditAnywhere)
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
#include "carla/road/element/RoadInfoSignal.h"
|
||||
#include <compiler/enable-ue4-macros.h>
|
||||
|
||||
#include "Async/ParallelFor.h"
|
||||
|
||||
#include "DrawDebugHelpers.h"
|
||||
#include "Kismet/KismetSystemLibrary.h"
|
||||
|
||||
|
@ -39,6 +41,44 @@ ACarlaGameModeBase::ACarlaGameModeBase(const FObjectInitializer& ObjectInitializ
|
|||
CarlaSettingsDelegate = CreateDefaultSubobject<UCarlaSettingsDelegate>(TEXT("CarlaSettingsDelegate"));
|
||||
}
|
||||
|
||||
void ACarlaGameModeBase::AddSceneCaptureSensor(ASceneCaptureSensor* SceneCaptureSensor)
|
||||
{
|
||||
uint32 ImageWidth = SceneCaptureSensor->ImageWidth;
|
||||
uint32 ImageHeight = SceneCaptureSensor->ImageHeight;
|
||||
|
||||
if(AtlasTextureWidth < (CurrentAtlasTextureWidth + ImageWidth))
|
||||
{
|
||||
IsAtlasTextureValid = false;
|
||||
AtlasTextureWidth = CurrentAtlasTextureWidth + ImageWidth;
|
||||
}
|
||||
if(AtlasTextureHeight < ImageHeight)
|
||||
{
|
||||
IsAtlasTextureValid = false;
|
||||
AtlasTextureHeight = ImageHeight;
|
||||
}
|
||||
|
||||
SceneCaptureSensor->PositionInAtlas = FIntVector(CurrentAtlasTextureWidth, 0, 0);
|
||||
CurrentAtlasTextureWidth += ImageWidth;
|
||||
|
||||
SceneCaptureSensors.Add(SceneCaptureSensor);
|
||||
|
||||
UE_LOG(LogCarla, Warning, TEXT("ACarlaGameModeBase::AddSceneCaptureSensor %d %dx%d"), SceneCaptureSensors.Num(), AtlasTextureWidth, AtlasTextureHeight);
|
||||
}
|
||||
|
||||
void ACarlaGameModeBase::RemoveSceneCaptureSensor(ASceneCaptureSensor* SceneCaptureSensor)
|
||||
{
|
||||
// Remove camera
|
||||
SceneCaptureSensors.Remove(SceneCaptureSensor);
|
||||
|
||||
// Recalculate PositionInAtlas for each camera
|
||||
CurrentAtlasTextureWidth = 0;
|
||||
for(ASceneCaptureSensor* Camera : SceneCaptureSensors)
|
||||
{
|
||||
Camera->PositionInAtlas = FIntVector(CurrentAtlasTextureWidth, 0, 0);
|
||||
CurrentAtlasTextureWidth += Camera->ImageWidth;
|
||||
}
|
||||
}
|
||||
|
||||
void ACarlaGameModeBase::InitGame(
|
||||
const FString &MapName,
|
||||
const FString &Options,
|
||||
|
@ -151,6 +191,8 @@ void ACarlaGameModeBase::BeginPlay()
|
|||
Recorder->GetReplayer()->CheckPlayAfterMapLoaded();
|
||||
}
|
||||
|
||||
CaptureAtlasDelegate = FCoreDelegates::OnEndFrameRT.AddUObject(this, &ACarlaGameModeBase::CaptureAtlas);
|
||||
|
||||
}
|
||||
|
||||
void ACarlaGameModeBase::Tick(float DeltaSeconds)
|
||||
|
@ -162,6 +204,10 @@ void ACarlaGameModeBase::Tick(float DeltaSeconds)
|
|||
{
|
||||
Recorder->Tick(DeltaSeconds);
|
||||
}
|
||||
|
||||
if(!IsAtlasTextureValid) {
|
||||
CreateAtlasTextures();
|
||||
}
|
||||
}
|
||||
|
||||
void ACarlaGameModeBase::EndPlay(const EEndPlayReason::Type EndPlayReason)
|
||||
|
@ -175,6 +221,8 @@ void ACarlaGameModeBase::EndPlay(const EEndPlayReason::Type EndPlayReason)
|
|||
{
|
||||
CarlaSettingsDelegate->Reset();
|
||||
}
|
||||
|
||||
FCoreDelegates::OnEndFrameRT.Remove(CaptureAtlasDelegate);
|
||||
}
|
||||
|
||||
void ACarlaGameModeBase::SpawnActorFactories()
|
||||
|
@ -327,3 +375,61 @@ void ACarlaGameModeBase::DebugShowSignals(bool enable)
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
void ACarlaGameModeBase::CreateAtlasTextures()
|
||||
{
|
||||
UE_LOG(LogCarla, Warning, TEXT("ACarlaGameModeBase::CreateAtlasTextures %d %dx%d"), SceneCaptureSensors.Num(), AtlasTextureWidth, AtlasTextureHeight);
|
||||
|
||||
FRHIResourceCreateInfo CreateInfo;
|
||||
for(int i = 0; i < kMaxNumTextures; i++)
|
||||
{
|
||||
CamerasAtlasTexture[i] = RHICreateTexture2D(AtlasTextureWidth, AtlasTextureHeight, PF_B8G8R8A8, 1, 1, TexCreate_CPUReadback, CreateInfo);
|
||||
AtlasPixels[i].Init(FColor(), AtlasTextureWidth * AtlasTextureHeight);
|
||||
}
|
||||
IsAtlasTextureValid = true;
|
||||
}
|
||||
|
||||
void ACarlaGameModeBase::CaptureAtlas()
|
||||
{
|
||||
ACarlaGameModeBase* This = this;
|
||||
|
||||
if(!IsAtlasTextureValid || !SceneCaptureSensors.Num()) return;
|
||||
|
||||
#if !UE_BUILD_SHIPPING
|
||||
if (!ReadSurface) return;
|
||||
#endif
|
||||
|
||||
ENQUEUE_RENDER_COMMAND(ASceneCaptureSensor_CaptureAtlas)
|
||||
(
|
||||
[This](FRHICommandListImmediate& RHICmdList) mutable
|
||||
{
|
||||
FTexture2DRHIRef AtlasTexture = This->CamerasAtlasTexture[This->CurrentAtlas];
|
||||
TArray<FColor>& CurrentAtlasPixels = This->AtlasPixels[This->CurrentAtlas];
|
||||
|
||||
if (!AtlasTexture)
|
||||
{
|
||||
UE_LOG(LogCarla, Error, TEXT("ACarlaGameModeBase::CaptureAtlas: Missing atlas texture"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Download Atlas texture
|
||||
SCOPE_CYCLE_COUNTER(STAT_CarlaSensorReadRT);
|
||||
|
||||
FIntRect Rect = FIntRect(0, 0, This->AtlasTextureWidth, This->AtlasTextureHeight);
|
||||
#if !UE_BUILD_SHIPPING
|
||||
if(This->ReadSurface == 2) {
|
||||
Rect = FIntRect(0, 0, This->SurfaceW, This->SurfaceH);
|
||||
}
|
||||
#endif
|
||||
|
||||
RHICmdList.ReadSurfaceData(
|
||||
AtlasTexture,
|
||||
Rect,
|
||||
CurrentAtlasPixels,
|
||||
FReadSurfaceDataFlags(RCM_UNorm, CubeFace_MAX));
|
||||
|
||||
// PreviousTexture = CurrentTexture;
|
||||
// CurrentTexture = (CurrentTexture + 1) & ~MaxNumTextures;
|
||||
}
|
||||
);
|
||||
}
|
|
@ -12,6 +12,7 @@
|
|||
#include "Carla/Recorder/CarlaRecorder.h"
|
||||
#include "Carla/Game/TaggerDelegate.h"
|
||||
#include "Carla/OpenDrive/OpenDrive.h"
|
||||
#include "Carla/Sensor/SceneCaptureSensor.h"
|
||||
#include "Carla/Settings/CarlaSettingsDelegate.h"
|
||||
#include "Carla/Weather/Weather.h"
|
||||
#include "Carla/Traffic/TrafficLightManager.h"
|
||||
|
@ -51,6 +52,46 @@ public:
|
|||
UFUNCTION(BlueprintCallable, Category = "CARLA Game Mode")
|
||||
ATrafficLightManager* GetTrafficLightManager();
|
||||
|
||||
void AddSceneCaptureSensor(ASceneCaptureSensor* SceneCaptureSensor);
|
||||
|
||||
void RemoveSceneCaptureSensor(ASceneCaptureSensor* SceneCaptureSensor);
|
||||
|
||||
bool IsCameraAtlasTextureValid() const
|
||||
{
|
||||
return IsAtlasTextureValid;
|
||||
}
|
||||
|
||||
const TArray<FColor>& GetCurrentAtlasPixels() const{
|
||||
return AtlasPixels[CurrentAtlas];
|
||||
}
|
||||
|
||||
FTexture2DRHIRef GetCurrentCamerasAtlasTexture() const{
|
||||
return CamerasAtlasTexture[CurrentAtlas];
|
||||
}
|
||||
|
||||
uint32 GetAtlasTextureWidth() const {
|
||||
return AtlasTextureWidth;
|
||||
}
|
||||
|
||||
uint32 GetAtlasTextureHeight() const {
|
||||
return AtlasTextureHeight;
|
||||
}
|
||||
|
||||
UFUNCTION(Exec)
|
||||
void SwitchReadSurface(uint32 Mode) {
|
||||
#if !UE_BUILD_SHIPPING
|
||||
ReadSurface = Mode;
|
||||
#endif
|
||||
}
|
||||
|
||||
UFUNCTION(Exec)
|
||||
void SetAtlasSurface(uint32 W, uint32 H) {
|
||||
#if !UE_BUILD_SHIPPING
|
||||
SurfaceW = W;
|
||||
SurfaceH = H;
|
||||
#endif
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
void InitGame(const FString &MapName, const FString &Options, FString &ErrorMessage) override;
|
||||
|
@ -69,6 +110,10 @@ private:
|
|||
|
||||
void ParseOpenDrive(const FString &MapName);
|
||||
|
||||
void CreateAtlasTextures();
|
||||
|
||||
void CaptureAtlas();
|
||||
|
||||
UPROPERTY()
|
||||
UCarlaGameInstance *GameInstance = nullptr;
|
||||
|
||||
|
@ -101,4 +146,23 @@ private:
|
|||
|
||||
boost::optional<carla::road::Map> Map;
|
||||
|
||||
FDelegateHandle CaptureAtlasDelegate;
|
||||
|
||||
static const uint32 kMaxNumTextures = 2u; // This has to be POT
|
||||
TArray<FColor> AtlasPixels[kMaxNumTextures];
|
||||
TArray<ASceneCaptureSensor*> SceneCaptureSensors;
|
||||
FTexture2DRHIRef CamerasAtlasTexture[kMaxNumTextures];
|
||||
uint32 AtlasTextureWidth = 0u;
|
||||
uint32 AtlasTextureHeight = 0u;
|
||||
uint32 CurrentAtlasTextureWidth = 0u;
|
||||
uint32 CurrentAtlas = 0u;
|
||||
uint32 PreviousAtlas = 0u;
|
||||
bool IsAtlasTextureValid = false;
|
||||
|
||||
#if !UE_BUILD_SHIPPING
|
||||
uint32 ReadSurface = 1;
|
||||
uint32 SurfaceW = 0;
|
||||
uint32 SurfaceH = 0;
|
||||
#endif
|
||||
|
||||
};
|
||||
|
|
|
@ -28,11 +28,13 @@ ADepthCamera::ADepthCamera(const FObjectInitializer &ObjectInitializer)
|
|||
);
|
||||
|
||||
Offset = carla::sensor::SensorRegistry::get<ADepthCamera*>::type::header_offset;
|
||||
|
||||
}
|
||||
|
||||
void ADepthCamera::Tick(float DeltaTime)
|
||||
{
|
||||
Super::Tick(DeltaTime);
|
||||
SendPixelsInStream(*this);
|
||||
|
||||
ACarlaGameModeBase* GameMode = Cast<ACarlaGameModeBase>(GetWorld()->GetAuthGameMode());
|
||||
SendPixelsInStream(*this, GameMode->GetCurrentAtlasPixels(), GameMode->GetAtlasTextureWidth());
|
||||
}
|
||||
|
||||
|
|
|
@ -27,5 +27,7 @@ ASceneCaptureCamera::ASceneCaptureCamera(const FObjectInitializer &ObjectInitial
|
|||
void ASceneCaptureCamera::Tick(float DeltaTime)
|
||||
{
|
||||
Super::Tick(DeltaTime);
|
||||
SendPixelsInStream(*this);
|
||||
}
|
||||
|
||||
ACarlaGameModeBase* GameMode = Cast<ACarlaGameModeBase>(GetWorld()->GetAuthGameMode());
|
||||
SendPixelsInStream(*this, GameMode->GetCurrentAtlasPixels(), GameMode->GetAtlasTextureWidth());
|
||||
}
|
|
@ -27,4 +27,5 @@ public:
|
|||
protected:
|
||||
|
||||
void Tick(float DeltaTime) override;
|
||||
|
||||
};
|
||||
|
|
|
@ -45,24 +45,6 @@ namespace SceneCaptureSensor_local_ns {
|
|||
// -- ASceneCaptureSensor ------------------------------------------------------
|
||||
// =============================================================================
|
||||
|
||||
TArray<ASceneCaptureSensor*> ASceneCaptureSensor::CaptureSensors = {};
|
||||
int32 ASceneCaptureSensor::NumCaptureSensors = 0;
|
||||
int32 ASceneCaptureSensor::CurrentTexture = 0;
|
||||
int32 ASceneCaptureSensor::PreviousTexture = 0;
|
||||
|
||||
// ASceneCaptureSensor::MaxNumTextures
|
||||
FTexture2DRHIRef AtlasTexture[2];
|
||||
const int32_t kAtlasTextureWidth = 1280 * 2;
|
||||
const int32_t kAtlasTextureHeight = 720 * 2;
|
||||
|
||||
std::atomic<int32_t> gSensorIndex {0};
|
||||
|
||||
TArray<FColor> ASceneCaptureSensor::Pixels[MaxNumTextures];
|
||||
bool ASceneCaptureSensor::AtlasCreated = false;
|
||||
bool ASceneCaptureSensor::AtlasInitialized = false;
|
||||
bool ReadSurface = true;
|
||||
bool CaptureScheduled = false;
|
||||
|
||||
ASceneCaptureSensor::ASceneCaptureSensor(const FObjectInitializer &ObjectInitializer)
|
||||
: Super(ObjectInitializer)
|
||||
{
|
||||
|
@ -74,6 +56,7 @@ ASceneCaptureSensor::ASceneCaptureSensor(const FObjectInitializer &ObjectInitial
|
|||
CaptureRenderTarget->CompressionSettings = TextureCompressionSettings::TC_Default;
|
||||
CaptureRenderTarget->SRGB = false;
|
||||
CaptureRenderTarget->bAutoGenerateMips = false;
|
||||
CaptureRenderTarget->bGPUSharedFlag = true;
|
||||
CaptureRenderTarget->AddressX = TextureAddress::TA_Clamp;
|
||||
CaptureRenderTarget->AddressY = TextureAddress::TA_Clamp;
|
||||
|
||||
|
@ -463,22 +446,7 @@ void ASceneCaptureSensor::BeginPlay()
|
|||
{
|
||||
using namespace SceneCaptureSensor_local_ns;
|
||||
|
||||
// Setup render target.
|
||||
|
||||
if(!AtlasCreated)
|
||||
{
|
||||
FRHIResourceCreateInfo CreateInfo;
|
||||
for(int i = 0; i < MaxNumTextures; i++)
|
||||
{
|
||||
AtlasTexture[i] = RHICreateTexture2D(kAtlasTextureWidth, kAtlasTextureHeight, PF_R8G8B8A8, 1, 1, TexCreate_CPUReadback, CreateInfo);
|
||||
}
|
||||
AtlasCreated = true;
|
||||
}
|
||||
SensorIndex = gSensorIndex.fetch_add(1);
|
||||
|
||||
|
||||
// Determine the gamma of the player.
|
||||
|
||||
const bool bInForceLinearGamma = !bEnablePostProcessingEffects;
|
||||
|
||||
CaptureRenderTarget->InitCustomFormat(ImageWidth, ImageHeight, PF_B8G8R8A8, bInForceLinearGamma);
|
||||
|
@ -515,36 +483,18 @@ void ASceneCaptureSensor::BeginPlay()
|
|||
|
||||
Super::BeginPlay();
|
||||
|
||||
CaptureSensors.Add(this);
|
||||
CopyTextureDelegate = FCoreDelegates::OnEndFrameRT.AddUObject(this, &ASceneCaptureCamera::CopyTextureToAtlas);
|
||||
|
||||
if(!AtlasInitialized)
|
||||
{
|
||||
for(int32 i = 0; i < MaxNumTextures; i++)
|
||||
{
|
||||
Pixels[i].Init(FColor(), kAtlasTextureWidth * kAtlasTextureHeight);
|
||||
}
|
||||
AtlasInitialized = true;
|
||||
}
|
||||
ACarlaGameModeBase* GameMode = Cast<ACarlaGameModeBase>(GetWorld()->GetAuthGameMode());
|
||||
GameMode->AddSceneCaptureSensor(this);
|
||||
|
||||
// CaptureDelegate = FCoreDelegates::OnBeginFrame.AddUObject(this, &ASceneCaptureCamera::SetViewport);
|
||||
CaptureDelegate = FCoreDelegates::OnEndFrameRT.AddUObject(this, &ASceneCaptureCamera::CopyTexture);
|
||||
if(!CaptureScheduled)
|
||||
{
|
||||
FCoreDelegates::OnEndFrameRT.AddUObject(this, &ASceneCaptureCamera::Capture);
|
||||
CaptureScheduled = true;
|
||||
}
|
||||
|
||||
// FDelegateHandle OnBackBufferReadyToPresent;
|
||||
// OnBackBufferReadyToPresent =
|
||||
// FSlateApplication::Get().GetRenderer()->OnBackBufferReadyToPresent().AddRaw(this, &ASceneCaptureCamera::OnBackBufferReadyToPresentCallback);
|
||||
// void FFrameGrabber::OnBackBufferReadyToPresentCallback(SWindow& SlateWindow, const FTexture2DRHIRef& BackBuffer)
|
||||
|
||||
// FlushRenderingCommands();
|
||||
}
|
||||
|
||||
void ASceneCaptureSensor::Tick(float DeltaTime)
|
||||
{
|
||||
Super::Tick(DeltaTime);
|
||||
// TODO: can I remove this?
|
||||
|
||||
// Add the view information every tick. Its only used for one tick and then
|
||||
// removed by the streamer.
|
||||
IStreamingManager::Get().AddViewInformation(
|
||||
|
@ -560,106 +510,57 @@ void ASceneCaptureSensor::EndPlay(const EEndPlayReason::Type EndPlayReason)
|
|||
Super::EndPlay(EndPlayReason);
|
||||
SCENE_CAPTURE_COUNTER = 0u;
|
||||
|
||||
CaptureSensors.Remove(this);
|
||||
|
||||
FCoreDelegates::OnEndFrameRT.Remove(CaptureDelegate);
|
||||
|
||||
if(CaptureScheduled)
|
||||
{
|
||||
CaptureScheduled = false;
|
||||
}
|
||||
|
||||
FCoreDelegates::OnEndFrameRT.Remove(CopyTextureDelegate);
|
||||
ACarlaGameModeBase* GameMode = Cast<ACarlaGameModeBase>(GetWorld()->GetAuthGameMode());
|
||||
GameMode->RemoveSceneCaptureSensor(this);
|
||||
}
|
||||
|
||||
void ASceneCaptureSensor::SetViewport()
|
||||
{
|
||||
ENQUEUE_RENDER_COMMAND(ASceneCaptureSensor_SetViewport)
|
||||
(
|
||||
[](FRHICommandListImmediate& RHICmdList) mutable
|
||||
{
|
||||
RHICmdList.SetViewport(0, 0, 0.0f, 800, 600, 0.0f);
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void ASceneCaptureSensor::CopyTexture()
|
||||
void ASceneCaptureSensor::CopyTextureToAtlas()
|
||||
{
|
||||
|
||||
check(CaptureRenderTarget != nullptr);
|
||||
check(IsInRenderingThread());
|
||||
|
||||
ASceneCaptureSensor* This = this;
|
||||
ASceneCaptureSensor* This = this;
|
||||
|
||||
ENQUEUE_RENDER_COMMAND(ASceneCaptureSensor_SendPixelsInRenderThread)
|
||||
(
|
||||
[This](FRHICommandListImmediate& RHICmdList) mutable
|
||||
{
|
||||
FRHICopyTextureInfo CopyInfo;
|
||||
int32_t current_w = 0;
|
||||
int32_t current_h = 0;
|
||||
ACarlaGameModeBase* GameMode = Cast<ACarlaGameModeBase>(GetWorld()->GetAuthGameMode());
|
||||
if(!GameMode->IsCameraAtlasTextureValid()) return;
|
||||
|
||||
if (This && This-> HasActorBegunPlay() && !This->IsPendingKill())
|
||||
{
|
||||
SCOPE_CYCLE_COUNTER(STAT_CarlaSensorCopyText);
|
||||
|
||||
const FTextureRenderTarget2DResource* RenderResource =
|
||||
static_cast<const FTextureRenderTarget2DResource *>(This->CaptureRenderTarget->Resource);
|
||||
FTexture2DRHIRef Texture = RenderResource->GetRenderTargetTexture();
|
||||
if (!Texture)
|
||||
{
|
||||
UE_LOG(LogCarla, Error, TEXT("ASceneCaptureSensor::Capture: UTextureRenderTarget2D missing render target texture"));
|
||||
return;
|
||||
}
|
||||
FIntPoint Rect = RenderResource->GetSizeXY();
|
||||
// Prepare copy information
|
||||
CopyInfo.Size = FIntVector(Rect.X, Rect.Y, 1); // Size of the camera
|
||||
|
||||
// TODO: camera texture is bigger than atlas
|
||||
// TODO: camera texture doesn't have enough space on atlas
|
||||
|
||||
CopyInfo.DestPosition = FIntVector(current_w , current_h, 0); // Where to copy the texture
|
||||
|
||||
current_w += Rect.X;
|
||||
if(current_w >= kAtlasTextureWidth)
|
||||
{
|
||||
current_w = 0;
|
||||
current_h += Rect.Y;
|
||||
}
|
||||
|
||||
RHICmdList.CopyTexture(Texture, AtlasTexture[CurrentTexture], CopyInfo);
|
||||
|
||||
/*
|
||||
ASceneCaptureSensor& CameraRef = *Camera;
|
||||
FPixelReader::WritePixelsToArray(
|
||||
*(CameraRef.CaptureRenderTarget),
|
||||
CameraRef.Pixels[CameraRef.PreviousTexture],
|
||||
RHICmdList);
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
void ASceneCaptureSensor::Capture()
|
||||
{
|
||||
ENQUEUE_RENDER_COMMAND(ASceneCaptureSensor_Capture)
|
||||
ENQUEUE_RENDER_COMMAND(ASceneCaptureSensor_CopyTextureToAtlas)
|
||||
(
|
||||
[](FRHICommandListImmediate& RHICmdList) mutable
|
||||
[This, GameMode](FRHICommandListImmediate& RHICmdList) mutable
|
||||
{
|
||||
// Download Atlas texture
|
||||
if(ReadSurface)
|
||||
{
|
||||
SCOPE_CYCLE_COUNTER(STAT_CarlaSensorReadRT);
|
||||
RHICmdList.ReadSurfaceData(
|
||||
AtlasTexture[PreviousTexture],
|
||||
FIntRect(0, 0, kAtlasTextureWidth, kAtlasTextureHeight),
|
||||
Pixels[CurrentTexture],
|
||||
FReadSurfaceDataFlags(RCM_UNorm, CubeFace_MAX));
|
||||
FTexture2DRHIRef AtlasTexture = GameMode->GetCurrentCamerasAtlasTexture();
|
||||
|
||||
PreviousTexture = CurrentTexture;
|
||||
CurrentTexture = (CurrentTexture + 1) & ~MaxNumTextures;
|
||||
}
|
||||
if (AtlasTexture.IsValid() && This && This->HasActorBegunPlay() && !This->IsPendingKill())
|
||||
{
|
||||
SCOPE_CYCLE_COUNTER(STAT_CarlaSensorCopyText);
|
||||
|
||||
const FTextureRenderTarget2DResource* RenderResource =
|
||||
static_cast<const FTextureRenderTarget2DResource *>(This->CaptureRenderTarget->Resource);
|
||||
FTexture2DRHIRef Texture = RenderResource->GetRenderTargetTexture();
|
||||
if (!Texture)
|
||||
{
|
||||
UE_LOG(LogCarla, Error, TEXT("ASceneCaptureSensor::Capture: UTextureRenderTarget2D missing render target texture"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Prepare copy information
|
||||
FRHICopyTextureInfo CopyInfo;
|
||||
CopyInfo.Size = FIntVector(This->ImageWidth, This->ImageHeight, 0); // Size of the camera
|
||||
CopyInfo.DestPosition = This->PositionInAtlas; // Where to copy the texture
|
||||
|
||||
RHICmdList.CopyTexture(Texture, AtlasTexture, CopyInfo);
|
||||
|
||||
/*
|
||||
ASceneCaptureSensor& CameraRef = *Camera;
|
||||
FPixelReader::WritePixelsToArray(
|
||||
*(CameraRef.CaptureRenderTarget),
|
||||
CameraRef.Pixels[CameraRef.PreviousTexture],
|
||||
RHICmdList);
|
||||
*/
|
||||
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ class CARLA_API ASceneCaptureSensor : public ASensor
|
|||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
friend class ACarlaGameModeBase;
|
||||
friend class FPixelReader;
|
||||
|
||||
public:
|
||||
|
@ -269,67 +270,32 @@ public:
|
|||
FPixelReader::SavePixelsToDisk(*CaptureRenderTarget, FilePath);
|
||||
}
|
||||
|
||||
protected:
|
||||
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
virtual void Tick(float DeltaTime) override;
|
||||
|
||||
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
|
||||
|
||||
virtual void SetUpSceneCaptureComponent(USceneCaptureComponent2D &SceneCapture) {}
|
||||
|
||||
uint32 Offset = 0u;
|
||||
|
||||
void SetViewport();
|
||||
|
||||
void CopyTexture();
|
||||
|
||||
void Capture();
|
||||
|
||||
template <typename TSensor>
|
||||
void SendPixelsInStream(TSensor &Sensor) {
|
||||
TArray<FColor>& PixelsData = Pixels[PreviousTexture];
|
||||
if(PixelsData.Num() > 0)
|
||||
void SendPixelsInStream(TSensor &Sensor, const TArray<FColor>& AtlasPixels, uint32 AtlasTextureWidth)
|
||||
{
|
||||
if(AtlasPixels.Num() > 0)
|
||||
{
|
||||
auto Stream = GetDataStream(Sensor);
|
||||
auto Buffer = Stream.PopBufferFromPool();
|
||||
|
||||
{
|
||||
SCOPE_CYCLE_COUNTER(STAT_CarlaSensorBufferCopy);
|
||||
FColor* Source = &PixelsData[0];
|
||||
Source += Offset;
|
||||
|
||||
constexpr auto SizeOfColor = sizeof(FColor);
|
||||
Buffer.reset(Offset + ImageWidth * ImageHeight * SizeOfColor);
|
||||
// const uint8 *SrcRow = (uint8*)Source;
|
||||
// auto DstRow = Buffer.begin() + Offset;
|
||||
constexpr uint32 BytesPerPixel = sizeof(FColor);
|
||||
const uint32 ExpectedStride = ImageWidth * BytesPerPixel;
|
||||
|
||||
const FColor* Source = &AtlasPixels[0];
|
||||
uint8 *SrcRow = (uint8*)Source + PositionInAtlas.X * BytesPerPixel;
|
||||
uint32 DstOffset = Offset;
|
||||
/*
|
||||
|
||||
Buffer.reset(Offset + ImageWidth * ImageHeight * BytesPerPixel);
|
||||
|
||||
for (uint32 Row = 0u; Row < ImageHeight; Row++)
|
||||
{
|
||||
//UE_LOG(LogCarla, Warning, TEXT("SendPixelsInStream %d %d %d"), DstRow?0:1, SrcRow?0:1, ImageWidth * SizeOfColor);
|
||||
//if(SrcRow)
|
||||
//{
|
||||
// FMemory::Memcpy(DstRow, SrcRow, ImageWidth * SizeOfColor);
|
||||
// DstRow += ImageWidth * SizeOfColor;
|
||||
// SrcRow += ImageWidth * SizeOfColor;
|
||||
|
||||
Buffer.copy_from(DstOffset, (unsigned char*)Source, ImageWidth * SizeOfColor);
|
||||
DstOffset += ImageWidth * SizeOfColor;
|
||||
//}
|
||||
//else
|
||||
//{
|
||||
// UE_LOG(LogCarla, Error, TEXT("SendPixelsInStream no source"));
|
||||
//}
|
||||
Buffer.copy_from(DstOffset, SrcRow, ExpectedStride);
|
||||
DstOffset += ExpectedStride;
|
||||
SrcRow += AtlasTextureWidth * BytesPerPixel;
|
||||
}
|
||||
*/
|
||||
|
||||
// UE_LOG(LogCarla, Warning, TEXT("SendPixelsInStream %d %d %d"), ImageWidth, ImageHeight, ImageWidth * ImageHeight * sizeof(FColor));
|
||||
Buffer.copy_from(
|
||||
Offset + SensorIndex * ImageWidth * ImageHeight * sizeof(FColor),
|
||||
(unsigned char*)Source ,
|
||||
ImageWidth * ImageHeight * sizeof(FColor));
|
||||
}
|
||||
|
||||
{
|
||||
|
@ -341,32 +307,17 @@ protected:
|
|||
|
||||
protected:
|
||||
|
||||
FDelegateHandle CaptureDelegate;
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
static TArray<ASceneCaptureSensor*> CaptureSensors;
|
||||
static int32 NumCaptureSensors;
|
||||
static const int32 MaxNumTextures = 2; // This has to be POT
|
||||
virtual void Tick(float DeltaTime) override;
|
||||
|
||||
static TArray<FColor> Pixels[MaxNumTextures];
|
||||
static int32 CurrentTexture;
|
||||
static int32 PreviousTexture;
|
||||
static bool AtlasCreated;
|
||||
static bool AtlasInitialized;
|
||||
virtual void EndPlay(const EEndPlayReason::Type EndPlayReason) override;
|
||||
|
||||
/// Image width in pixels.
|
||||
UPROPERTY(EditAnywhere)
|
||||
uint32 ImageWidth = 800u;
|
||||
virtual void SetUpSceneCaptureComponent(USceneCaptureComponent2D &SceneCapture) {}
|
||||
|
||||
/// Image height in pixels.
|
||||
UPROPERTY(EditAnywhere)
|
||||
uint32 ImageHeight = 600u;
|
||||
void CopyTextureToAtlas();
|
||||
|
||||
/// Whether to render the post-processing effects present in the scene.
|
||||
UPROPERTY(EditAnywhere)
|
||||
bool bEnablePostProcessingEffects = true;
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
float TargetGamma = 2.2f;
|
||||
FDelegateHandle CopyTextureDelegate;
|
||||
|
||||
/// Render target necessary for scene capture.
|
||||
UPROPERTY(EditAnywhere)
|
||||
|
@ -376,6 +327,23 @@ protected:
|
|||
UPROPERTY(EditAnywhere)
|
||||
USceneCaptureComponent2D *CaptureComponent2D = nullptr;
|
||||
|
||||
int32_t SensorIndex = 0;
|
||||
FIntVector PositionInAtlas;
|
||||
|
||||
UPROPERTY(EditAnywhere)
|
||||
float TargetGamma = 2.2f;
|
||||
|
||||
/// Image width in pixels.
|
||||
UPROPERTY(EditAnywhere)
|
||||
uint32 ImageWidth = 800u;
|
||||
|
||||
/// Image height in pixels.
|
||||
UPROPERTY(EditAnywhere)
|
||||
uint32 ImageHeight = 600u;
|
||||
|
||||
uint32 Offset = 0u;
|
||||
|
||||
/// Whether to render the post-processing effects present in the scene.
|
||||
UPROPERTY(EditAnywhere)
|
||||
bool bEnablePostProcessingEffects = true;
|
||||
|
||||
};
|
||||
|
|
|
@ -29,5 +29,7 @@ ASemanticSegmentationCamera::ASemanticSegmentationCamera(
|
|||
void ASemanticSegmentationCamera::Tick(float DeltaTime)
|
||||
{
|
||||
Super::Tick(DeltaTime);
|
||||
SendPixelsInStream(*this);
|
||||
}
|
||||
|
||||
ACarlaGameModeBase* GameMode = Cast<ACarlaGameModeBase>(GetWorld()->GetAuthGameMode());
|
||||
SendPixelsInStream(*this, GameMode->GetCurrentAtlasPixels(), GameMode->GetAtlasTextureWidth());
|
||||
}
|
Loading…
Reference in New Issue