Add camera capture and register with game mode mechanisms
This commit is contained in:
parent
734f0f0534
commit
cfa7da7cf1
|
@ -102,12 +102,17 @@ APlayerStart *CarlaGameController::ChoosePlayerStart(
|
|||
return AvailableStartSpots[0u];
|
||||
}
|
||||
|
||||
void CarlaGameController::RegisterPlayer(AController *NewPlayer)
|
||||
void CarlaGameController::RegisterPlayer(AController &NewPlayer)
|
||||
{
|
||||
Player = Cast<ACarlaVehicleController>(NewPlayer);
|
||||
Player = Cast<ACarlaVehicleController>(&NewPlayer);
|
||||
check(Player != nullptr);
|
||||
}
|
||||
|
||||
void CarlaGameController::RegisterCaptureCamera(const ASceneCaptureCamera &CaptureCamera)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void CarlaGameController::Tick(float DeltaSeconds)
|
||||
{
|
||||
check(Player != nullptr);
|
||||
|
|
|
@ -16,7 +16,9 @@ public:
|
|||
|
||||
virtual APlayerStart *ChoosePlayerStart(const TArray<APlayerStart *> &AvailableStartSpots) override;
|
||||
|
||||
virtual void RegisterPlayer(AController *NewPlayer) override;
|
||||
virtual void RegisterPlayer(AController &NewPlayer) override;
|
||||
|
||||
virtual void RegisterCaptureCamera(const ASceneCaptureCamera &CaptureCamera) override;
|
||||
|
||||
virtual void Tick(float DeltaSeconds) override;
|
||||
|
||||
|
|
|
@ -4,8 +4,9 @@
|
|||
|
||||
#include "Array.h"
|
||||
|
||||
class APlayerStart;
|
||||
class AController;
|
||||
class APlayerStart;
|
||||
class ASceneCaptureCamera;
|
||||
|
||||
/// Base class for a CARLA game controller.
|
||||
class CARLA_API CarlaGameControllerBase
|
||||
|
@ -16,7 +17,9 @@ public:
|
|||
|
||||
virtual APlayerStart *ChoosePlayerStart(const TArray<APlayerStart *> &AvailableStartSpots) = 0;
|
||||
|
||||
virtual void RegisterPlayer(AController *NewPlayer) = 0;
|
||||
virtual void RegisterPlayer(AController &NewPlayer) = 0;
|
||||
|
||||
virtual void Tick(float DeltaSeconds) {}
|
||||
virtual void RegisterCaptureCamera(const ASceneCaptureCamera &CaptureCamera) = 0;
|
||||
|
||||
virtual void Tick(float DeltaSeconds) = 0;
|
||||
};
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
#include "EngineUtils.h"
|
||||
#include "GameFramework/PlayerStart.h"
|
||||
|
||||
#include "SceneCaptureCamera.h"
|
||||
|
||||
#include "CarlaGameInstance.h"
|
||||
#include "CarlaGameState.h"
|
||||
#include "CarlaPlayerState.h"
|
||||
|
@ -16,12 +18,12 @@ ACarlaGameMode::ACarlaGameMode() :
|
|||
Super(),
|
||||
GameController(nullptr)
|
||||
{
|
||||
PrimaryActorTick.bCanEverTick = true;
|
||||
PrimaryActorTick.TickGroup = TG_PrePhysics;
|
||||
|
||||
PlayerControllerClass = ACarlaVehicleController::StaticClass();
|
||||
GameStateClass = ACarlaGameState::StaticClass();
|
||||
PlayerStateClass = ACarlaPlayerState::StaticClass();
|
||||
|
||||
PrimaryActorTick.bCanEverTick = true;
|
||||
PrimaryActorTick.TickGroup = TG_PrePhysics;
|
||||
}
|
||||
|
||||
void ACarlaGameMode::InitGame(
|
||||
|
@ -41,17 +43,18 @@ void ACarlaGameMode::InitGame(
|
|||
|
||||
void ACarlaGameMode::RestartPlayer(AController* NewPlayer)
|
||||
{
|
||||
check(NewPlayer != nullptr);
|
||||
TArray<APlayerStart *> UnOccupiedStartPoints;
|
||||
APlayerStart *PlayFromHere = FindUnOccupiedStartPoints(NewPlayer, UnOccupiedStartPoints);
|
||||
if (PlayFromHere != nullptr) {
|
||||
RestartPlayerAtPlayerStart(NewPlayer, PlayFromHere);
|
||||
GameController->RegisterPlayer(NewPlayer);
|
||||
RegisterPlayer(*NewPlayer);
|
||||
return;
|
||||
} else if (UnOccupiedStartPoints.Num() > 0u) {
|
||||
APlayerStart *StartSpot = GameController->ChoosePlayerStart(UnOccupiedStartPoints);
|
||||
if (StartSpot != nullptr) {
|
||||
RestartPlayerAtPlayerStart(NewPlayer, UnOccupiedStartPoints[0u]);
|
||||
GameController->RegisterPlayer(NewPlayer);
|
||||
RegisterPlayer(*NewPlayer);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -64,6 +67,20 @@ void ACarlaGameMode::Tick(float DeltaSeconds)
|
|||
GameController->Tick(DeltaSeconds);
|
||||
}
|
||||
|
||||
void ACarlaGameMode::RegisterCaptureCamera(ASceneCaptureCamera &CaptureCamera)
|
||||
{
|
||||
check(GameController != nullptr);
|
||||
AddTickPrerequisiteActor(&CaptureCamera);
|
||||
GameController->RegisterCaptureCamera(CaptureCamera);
|
||||
}
|
||||
|
||||
void ACarlaGameMode::RegisterPlayer(AController &NewPlayer)
|
||||
{
|
||||
check(GameController != nullptr);
|
||||
AddTickPrerequisiteActor(&NewPlayer);
|
||||
GameController->RegisterPlayer(NewPlayer);
|
||||
}
|
||||
|
||||
APlayerStart *ACarlaGameMode::FindUnOccupiedStartPoints(
|
||||
AController *Player,
|
||||
TArray<APlayerStart *> &UnOccupiedStartPoints)
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "CarlaGameMode.generated.h"
|
||||
|
||||
class APlayerStart;
|
||||
class ASceneCaptureCamera;
|
||||
|
||||
/**
|
||||
*
|
||||
|
@ -30,8 +31,12 @@ public:
|
|||
|
||||
virtual void Tick(float DeltaSeconds) override;
|
||||
|
||||
void RegisterCaptureCamera(ASceneCaptureCamera &CaptureCamera);
|
||||
|
||||
private:
|
||||
|
||||
void RegisterPlayer(AController &NewPlayer);
|
||||
|
||||
/// Iterate all the APlayerStart present in the world and add the ones with
|
||||
/// unoccupied locations to @a UnOccupiedStartPoints.
|
||||
///
|
||||
|
|
|
@ -9,9 +9,9 @@ APlayerStart *MockGameController::ChoosePlayerStart(
|
|||
return AvailableStartSpots[0u];
|
||||
}
|
||||
|
||||
void MockGameController::RegisterPlayer(AController *NewPlayer)
|
||||
void MockGameController::RegisterPlayer(AController &NewPlayer)
|
||||
{
|
||||
ACarlaVehicleController *VehicleController = Cast<ACarlaVehicleController>(NewPlayer);
|
||||
ACarlaVehicleController *VehicleController = Cast<ACarlaVehicleController>(&NewPlayer);
|
||||
if (VehicleController != nullptr) {
|
||||
if (!VehicleController->IsInManualMode())
|
||||
VehicleController->SetManualMode(true);
|
||||
|
@ -19,3 +19,13 @@ void MockGameController::RegisterPlayer(AController *NewPlayer)
|
|||
UE_LOG(LogCarla, Warning, TEXT("Player is not a ACarlaVehicleController"));
|
||||
}
|
||||
}
|
||||
|
||||
void MockGameController::RegisterCaptureCamera(const ASceneCaptureCamera &CaptureCamera)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void MockGameController::Tick(float DeltaSeconds)
|
||||
{
|
||||
|
||||
}
|
||||
|
|
|
@ -11,5 +11,9 @@ public:
|
|||
|
||||
virtual APlayerStart *ChoosePlayerStart(const TArray<APlayerStart *> &AvailableStartSpots) override;
|
||||
|
||||
virtual void RegisterPlayer(AController *NewPlayer) override;
|
||||
virtual void RegisterPlayer(AController &NewPlayer) override;
|
||||
|
||||
virtual void RegisterCaptureCamera(const ASceneCaptureCamera &CaptureCamera) override;
|
||||
|
||||
virtual void Tick(float DeltaSeconds) override;
|
||||
};
|
||||
|
|
|
@ -8,43 +8,19 @@
|
|||
#include "Components/StaticMeshComponent.h"
|
||||
#include "Engine/CollisionProfile.h"
|
||||
#include "Engine/TextureRenderTarget2D.h"
|
||||
#include "Game/CarlaGameMode.h"
|
||||
#include "HighResScreenshot.h"
|
||||
#include "Paths.h"
|
||||
#include "StaticMeshResources.h"
|
||||
#include "TextureResource.h"
|
||||
|
||||
// -- Static methods -----------------------------------------------------------
|
||||
|
||||
static void SaveRenderTargetToDisk(UTextureRenderTarget2D* InRenderTarget, FString Filename)
|
||||
{
|
||||
FTextureRenderTargetResource* RTResource = InRenderTarget->GameThread_GetRenderTargetResource();
|
||||
|
||||
FReadSurfaceDataFlags ReadPixelFlags(RCM_UNorm);
|
||||
ReadPixelFlags.SetLinearToGamma(true);
|
||||
|
||||
TArray<FColor> OutBMP;
|
||||
RTResource->ReadPixels(OutBMP, ReadPixelFlags);
|
||||
for (FColor& color : OutBMP)
|
||||
{
|
||||
color.A = 255;
|
||||
}
|
||||
FIntPoint DestSize(InRenderTarget->GetSurfaceWidth(), InRenderTarget->GetSurfaceHeight());
|
||||
FString ResultPath;
|
||||
FHighResScreenshotConfig& HighResScreenshotConfig = GetHighResScreenshotConfig();
|
||||
HighResScreenshotConfig.SaveImage(Filename, OutBMP, DestSize, &ResultPath);
|
||||
}
|
||||
|
||||
// -- ASceneCaptureCamera ------------------------------------------------------
|
||||
|
||||
ASceneCaptureCamera::ASceneCaptureCamera(const FObjectInitializer& ObjectInitializer) :
|
||||
Super(ObjectInitializer),
|
||||
SaveToFolder(FPlatformProcess::UserDir()),
|
||||
FileName("capture_%05d.png"),
|
||||
CapturesPerSecond(15.0f),
|
||||
SizeX(200u),
|
||||
SizeY(200u)
|
||||
{
|
||||
PrimaryActorTick.bCanEverTick = true;
|
||||
PrimaryActorTick.TickGroup = TG_PrePhysics;
|
||||
|
||||
MeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("CamMesh0"));
|
||||
|
||||
|
@ -57,34 +33,12 @@ ASceneCaptureCamera::ASceneCaptureCamera(const FObjectInitializer& ObjectInitial
|
|||
|
||||
DrawFrustum = CreateDefaultSubobject<UDrawFrustumComponent>(TEXT("DrawFrust0"));
|
||||
DrawFrustum->bIsEditorOnly = true;
|
||||
DrawFrustum->SetupAttachment(GetMeshComp());
|
||||
DrawFrustum->SetupAttachment(MeshComp);
|
||||
|
||||
CaptureRenderTarget = CreateDefaultSubobject<UTextureRenderTarget2D>(TEXT("CaptureRenderTarget0"));
|
||||
|
||||
CaptureComponent2D = CreateDefaultSubobject<USceneCaptureComponent2D>(TEXT("SceneCaptureComponent2D"));
|
||||
CaptureComponent2D->SetupAttachment(GetMeshComp());
|
||||
}
|
||||
|
||||
ASceneCaptureCamera::~ASceneCaptureCamera() {}
|
||||
|
||||
void ASceneCaptureCamera::OnInterpToggle(bool bEnable)
|
||||
{
|
||||
CaptureComponent2D->SetVisibility(bEnable);
|
||||
}
|
||||
|
||||
void ASceneCaptureCamera::UpdateDrawFrustum()
|
||||
{
|
||||
if(DrawFrustum && CaptureComponent2D)
|
||||
{
|
||||
DrawFrustum->FrustumStartDist = GNearClippingPlane;
|
||||
|
||||
// 1000 is the default frustum distance, ideally this would be infinite but that might cause rendering issues
|
||||
DrawFrustum->FrustumEndDist = (CaptureComponent2D->MaxViewDistanceOverride > DrawFrustum->FrustumStartDist)
|
||||
? CaptureComponent2D->MaxViewDistanceOverride : 1000.0f;
|
||||
|
||||
DrawFrustum->FrustumAngle = CaptureComponent2D->FOVAngle;
|
||||
//DrawFrustum->FrustumAspectRatio = CaptureComponent2D->AspectRatio;
|
||||
}
|
||||
CaptureComponent2D->SetupAttachment(MeshComp);
|
||||
}
|
||||
|
||||
void ASceneCaptureCamera::PostActorCreated()
|
||||
|
@ -93,14 +47,14 @@ void ASceneCaptureCamera::PostActorCreated()
|
|||
|
||||
// no need load the editor mesh when there is no editor
|
||||
#if WITH_EDITOR
|
||||
if(GetMeshComp())
|
||||
if(MeshComp)
|
||||
{
|
||||
if (!IsRunningCommandlet())
|
||||
{
|
||||
if( !GetMeshComp()->GetStaticMesh())
|
||||
if( !MeshComp->GetStaticMesh())
|
||||
{
|
||||
UStaticMesh* CamMesh = LoadObject<UStaticMesh>(NULL, TEXT("/Engine/EditorMeshes/MatineeCam_SM.MatineeCam_SM"), NULL, LOAD_None, NULL);
|
||||
GetMeshComp()->SetStaticMesh(CamMesh);
|
||||
MeshComp->SetStaticMesh(CamMesh);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -121,49 +75,34 @@ void ASceneCaptureCamera::BeginPlay()
|
|||
CaptureComponent2D->TextureTarget = CaptureRenderTarget;
|
||||
CaptureComponent2D->UpdateContent();
|
||||
CaptureComponent2D->Activate();
|
||||
|
||||
// Register this camera with the game mode.
|
||||
ACarlaGameMode *GameMode = Cast<ACarlaGameMode>(GetWorld()->GetAuthGameMode());
|
||||
if (GameMode != nullptr)
|
||||
GameMode->RegisterCaptureCamera(*this);
|
||||
}
|
||||
|
||||
void ASceneCaptureCamera::Tick(float Delta)
|
||||
{
|
||||
Super::Tick(Delta);
|
||||
|
||||
const float CaptureUpdateTime = 1.0f / CapturesPerSecond;
|
||||
ElapsedTimeSinceLastCapture += Delta;
|
||||
|
||||
if (bCaptureScene && (ElapsedTimeSinceLastCapture >= CaptureUpdateTime))
|
||||
{
|
||||
if (CaptureComponent2D == nullptr)
|
||||
{
|
||||
UE_LOG(LogCarla, Error, TEXT("Missing capture component"));
|
||||
}
|
||||
|
||||
if (CaptureRenderTarget)
|
||||
{
|
||||
// Capture scene.
|
||||
FString FilePath = FPaths::Combine(SaveToFolder, FString::Printf(*FileName, CaptureFileNameCount));
|
||||
//UE_LOG(LogCarla, Log, TEXT("Delta %fs: Capture %s"), ElapsedTimeSinceLastCapture, *FilePath);
|
||||
SaveRenderTargetToDisk(CaptureRenderTarget, FilePath);
|
||||
++CaptureFileNameCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
UE_LOG(LogCarla, Error, TEXT("Missing render target"));
|
||||
}
|
||||
ElapsedTimeSinceLastCapture = 0.0f;
|
||||
}
|
||||
// Update the image bitmap.
|
||||
FTextureRenderTargetResource* RTResource = CaptureRenderTarget->GameThread_GetRenderTargetResource();
|
||||
FReadSurfaceDataFlags ReadPixelFlags(RCM_UNorm);
|
||||
ReadPixelFlags.SetLinearToGamma(true);
|
||||
RTResource->ReadPixels(ImageBitMap, ReadPixelFlags);
|
||||
}
|
||||
|
||||
UStaticMeshComponent* ASceneCaptureCamera::GetMeshComp() const
|
||||
void ASceneCaptureCamera::UpdateDrawFrustum()
|
||||
{
|
||||
return MeshComp;
|
||||
}
|
||||
if(DrawFrustum && CaptureComponent2D)
|
||||
{
|
||||
DrawFrustum->FrustumStartDist = GNearClippingPlane;
|
||||
|
||||
USceneCaptureComponent2D* ASceneCaptureCamera::GetCaptureComponent2D() const
|
||||
{
|
||||
return CaptureComponent2D;
|
||||
}
|
||||
// 1000 is the default frustum distance, ideally this would be infinite but that might cause rendering issues
|
||||
DrawFrustum->FrustumEndDist = (CaptureComponent2D->MaxViewDistanceOverride > DrawFrustum->FrustumStartDist)
|
||||
? CaptureComponent2D->MaxViewDistanceOverride : 1000.0f;
|
||||
|
||||
UDrawFrustumComponent* ASceneCaptureCamera::GetDrawFrustum() const
|
||||
{
|
||||
return DrawFrustum;
|
||||
DrawFrustum->FrustumAngle = CaptureComponent2D->FOVAngle;
|
||||
//DrawFrustum->FrustumAspectRatio = CaptureComponent2D->AspectRatio;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,30 +20,37 @@ class CARLA_API ASceneCaptureCamera : public AActor
|
|||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
float ElapsedTimeSinceLastCapture = 0.0f;
|
||||
public:
|
||||
|
||||
size_t CaptureFileNameCount = 0u;
|
||||
ASceneCaptureCamera(const FObjectInitializer& ObjectInitializer);
|
||||
|
||||
protected:
|
||||
|
||||
virtual void PostActorCreated() override;
|
||||
|
||||
public:
|
||||
UPROPERTY(Category = SceneCapture, EditAnywhere)
|
||||
bool bCaptureScene = true;
|
||||
|
||||
UPROPERTY(Category = SceneCapture, EditAnywhere, meta = (EditCondition = bCaptureScene))
|
||||
FString SaveToFolder;
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
UPROPERTY(Category = SceneCapture, EditAnywhere, meta = (EditCondition = bCaptureScene))
|
||||
FString FileName;
|
||||
virtual void Tick(float Delta) override;
|
||||
|
||||
UPROPERTY(Category = SceneCapture, EditAnywhere, meta = (EditCondition = bCaptureScene))
|
||||
float CapturesPerSecond;
|
||||
|
||||
UPROPERTY(Category = SceneCapture, EditAnywhere, meta = (EditCondition = bCaptureScene))
|
||||
uint32 SizeX;
|
||||
|
||||
UPROPERTY(Category = SceneCapture, EditAnywhere, meta = (EditCondition = bCaptureScene))
|
||||
uint32 SizeY;
|
||||
const TArray<FColor> &GetImage() const
|
||||
{
|
||||
return ImageBitMap;
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
/// Used to synchronize the DrawFrustumComponent with the
|
||||
/// SceneCaptureComponent2D settings.
|
||||
void UpdateDrawFrustum();
|
||||
|
||||
UPROPERTY(Category = SceneCapture, EditAnywhere)
|
||||
uint32 SizeX;
|
||||
|
||||
UPROPERTY(Category = SceneCapture, EditAnywhere)
|
||||
uint32 SizeY;
|
||||
|
||||
/** To display the 3d camera in the editor. */
|
||||
UPROPERTY()
|
||||
class UStaticMeshComponent* MeshComp;
|
||||
|
@ -60,30 +67,6 @@ private:
|
|||
UPROPERTY(Transient)
|
||||
class USceneCaptureComponent2D* CaptureComponent2D;
|
||||
|
||||
public:
|
||||
|
||||
ASceneCaptureCamera(const FObjectInitializer& ObjectInitializer);
|
||||
|
||||
~ASceneCaptureCamera();
|
||||
|
||||
virtual void PostActorCreated() override;
|
||||
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
virtual void Tick(float Delta) override;
|
||||
|
||||
/** Used to synchronize the DrawFrustumComponent with the SceneCaptureComponent2D settings. */
|
||||
void UpdateDrawFrustum();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Rendering")
|
||||
void OnInterpToggle(bool bEnable);
|
||||
|
||||
/** Returns CaptureComponent2D subobject **/
|
||||
USceneCaptureComponent2D* GetCaptureComponent2D() const;
|
||||
|
||||
/** Returns DrawFrustum subobject **/
|
||||
UDrawFrustumComponent* GetDrawFrustum() const;
|
||||
|
||||
/** Returns MeshComp subobject **/
|
||||
UStaticMeshComponent* GetMeshComp() const;
|
||||
UPROPERTY()
|
||||
TArray<FColor> ImageBitMap;
|
||||
};
|
||||
|
|
|
@ -0,0 +1,169 @@
|
|||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
#include "Carla.h"
|
||||
#include "SceneCaptureToDiskCamera.h"
|
||||
|
||||
#include "Components/DrawFrustumComponent.h"
|
||||
#include "Components/SceneCaptureComponent2D.h"
|
||||
#include "Components/StaticMeshComponent.h"
|
||||
#include "Engine/CollisionProfile.h"
|
||||
#include "Engine/TextureRenderTarget2D.h"
|
||||
#include "HighResScreenshot.h"
|
||||
#include "Paths.h"
|
||||
#include "StaticMeshResources.h"
|
||||
#include "TextureResource.h"
|
||||
|
||||
// -- Static methods -----------------------------------------------------------
|
||||
|
||||
static void SaveRenderTargetToDisk(UTextureRenderTarget2D* InRenderTarget, FString Filename)
|
||||
{
|
||||
FTextureRenderTargetResource* RTResource = InRenderTarget->GameThread_GetRenderTargetResource();
|
||||
|
||||
FReadSurfaceDataFlags ReadPixelFlags(RCM_UNorm);
|
||||
ReadPixelFlags.SetLinearToGamma(true);
|
||||
|
||||
TArray<FColor> OutBMP;
|
||||
RTResource->ReadPixels(OutBMP, ReadPixelFlags);
|
||||
for (FColor& color : OutBMP)
|
||||
{
|
||||
color.A = 255;
|
||||
}
|
||||
FIntPoint DestSize(InRenderTarget->GetSurfaceWidth(), InRenderTarget->GetSurfaceHeight());
|
||||
FString ResultPath;
|
||||
FHighResScreenshotConfig& HighResScreenshotConfig = GetHighResScreenshotConfig();
|
||||
HighResScreenshotConfig.SaveImage(Filename, OutBMP, DestSize, &ResultPath);
|
||||
}
|
||||
|
||||
// -- ASceneCaptureToDiskCamera ------------------------------------------------------
|
||||
|
||||
ASceneCaptureToDiskCamera::ASceneCaptureToDiskCamera(const FObjectInitializer& ObjectInitializer) :
|
||||
Super(ObjectInitializer),
|
||||
SaveToFolder(FPlatformProcess::UserDir()),
|
||||
FileName("capture_%05d.png"),
|
||||
CapturesPerSecond(15.0f),
|
||||
SizeX(200u),
|
||||
SizeY(200u)
|
||||
{
|
||||
PrimaryActorTick.bCanEverTick = true;
|
||||
|
||||
MeshComp = CreateDefaultSubobject<UStaticMeshComponent>(TEXT("CamMesh0"));
|
||||
|
||||
MeshComp->SetCollisionProfileName(UCollisionProfile::NoCollision_ProfileName);
|
||||
|
||||
MeshComp->bHiddenInGame = true;
|
||||
MeshComp->CastShadow = false;
|
||||
MeshComp->PostPhysicsComponentTick.bCanEverTick = false;
|
||||
RootComponent = MeshComp;
|
||||
|
||||
DrawFrustum = CreateDefaultSubobject<UDrawFrustumComponent>(TEXT("DrawFrust0"));
|
||||
DrawFrustum->bIsEditorOnly = true;
|
||||
DrawFrustum->SetupAttachment(GetMeshComp());
|
||||
|
||||
CaptureRenderTarget = CreateDefaultSubobject<UTextureRenderTarget2D>(TEXT("CaptureRenderTarget0"));
|
||||
|
||||
CaptureComponent2D = CreateDefaultSubobject<USceneCaptureComponent2D>(TEXT("SceneCaptureComponent2D"));
|
||||
CaptureComponent2D->SetupAttachment(GetMeshComp());
|
||||
}
|
||||
|
||||
ASceneCaptureToDiskCamera::~ASceneCaptureToDiskCamera() {}
|
||||
|
||||
void ASceneCaptureToDiskCamera::OnInterpToggle(bool bEnable)
|
||||
{
|
||||
CaptureComponent2D->SetVisibility(bEnable);
|
||||
}
|
||||
|
||||
void ASceneCaptureToDiskCamera::UpdateDrawFrustum()
|
||||
{
|
||||
if(DrawFrustum && CaptureComponent2D)
|
||||
{
|
||||
DrawFrustum->FrustumStartDist = GNearClippingPlane;
|
||||
|
||||
// 1000 is the default frustum distance, ideally this would be infinite but that might cause rendering issues
|
||||
DrawFrustum->FrustumEndDist = (CaptureComponent2D->MaxViewDistanceOverride > DrawFrustum->FrustumStartDist)
|
||||
? CaptureComponent2D->MaxViewDistanceOverride : 1000.0f;
|
||||
|
||||
DrawFrustum->FrustumAngle = CaptureComponent2D->FOVAngle;
|
||||
//DrawFrustum->FrustumAspectRatio = CaptureComponent2D->AspectRatio;
|
||||
}
|
||||
}
|
||||
|
||||
void ASceneCaptureToDiskCamera::PostActorCreated()
|
||||
{
|
||||
Super::PostActorCreated();
|
||||
|
||||
// no need load the editor mesh when there is no editor
|
||||
#if WITH_EDITOR
|
||||
if(GetMeshComp())
|
||||
{
|
||||
if (!IsRunningCommandlet())
|
||||
{
|
||||
if( !GetMeshComp()->GetStaticMesh())
|
||||
{
|
||||
UStaticMesh* CamMesh = LoadObject<UStaticMesh>(NULL, TEXT("/Engine/EditorMeshes/MatineeCam_SM.MatineeCam_SM"), NULL, LOAD_None, NULL);
|
||||
GetMeshComp()->SetStaticMesh(CamMesh);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
// Sync component with CameraActor frustum settings.
|
||||
UpdateDrawFrustum();
|
||||
}
|
||||
|
||||
void ASceneCaptureToDiskCamera::BeginPlay()
|
||||
{
|
||||
Super::BeginPlay();
|
||||
|
||||
CaptureRenderTarget->InitCustomFormat(SizeX, SizeY, PF_B8G8R8A8, false);
|
||||
CaptureRenderTarget->UpdateResource();
|
||||
|
||||
CaptureComponent2D->Deactivate();
|
||||
CaptureComponent2D->TextureTarget = CaptureRenderTarget;
|
||||
CaptureComponent2D->UpdateContent();
|
||||
CaptureComponent2D->Activate();
|
||||
}
|
||||
|
||||
void ASceneCaptureToDiskCamera::Tick(float Delta)
|
||||
{
|
||||
Super::Tick(Delta);
|
||||
|
||||
const float CaptureUpdateTime = 1.0f / CapturesPerSecond;
|
||||
ElapsedTimeSinceLastCapture += Delta;
|
||||
|
||||
if (bCaptureScene && (ElapsedTimeSinceLastCapture >= CaptureUpdateTime))
|
||||
{
|
||||
if (CaptureComponent2D == nullptr)
|
||||
{
|
||||
UE_LOG(LogCarla, Error, TEXT("Missing capture component"));
|
||||
}
|
||||
|
||||
if (CaptureRenderTarget)
|
||||
{
|
||||
// Capture scene.
|
||||
FString FilePath = FPaths::Combine(SaveToFolder, FString::Printf(*FileName, CaptureFileNameCount));
|
||||
//UE_LOG(LogCarla, Log, TEXT("Delta %fs: Capture %s"), ElapsedTimeSinceLastCapture, *FilePath);
|
||||
SaveRenderTargetToDisk(CaptureRenderTarget, FilePath);
|
||||
++CaptureFileNameCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
UE_LOG(LogCarla, Error, TEXT("Missing render target"));
|
||||
}
|
||||
ElapsedTimeSinceLastCapture = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
UStaticMeshComponent* ASceneCaptureToDiskCamera::GetMeshComp() const
|
||||
{
|
||||
return MeshComp;
|
||||
}
|
||||
|
||||
USceneCaptureComponent2D* ASceneCaptureToDiskCamera::GetCaptureComponent2D() const
|
||||
{
|
||||
return CaptureComponent2D;
|
||||
}
|
||||
|
||||
UDrawFrustumComponent* ASceneCaptureToDiskCamera::GetDrawFrustum() const
|
||||
{
|
||||
return DrawFrustum;
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
// Fill out your copyright notice in the Description page of Project Settings.
|
||||
|
||||
/**
|
||||
* Own SceneCapture, re-implementing some of the methods since ASceneCapture
|
||||
* cannot be subclassed.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "GameFramework/Actor.h"
|
||||
#include "StaticMeshResources.h"
|
||||
#include "SceneCaptureToDiskCamera.generated.h"
|
||||
|
||||
class UDrawFrustumComponent;
|
||||
class USceneCaptureComponent2D;
|
||||
class UStaticMeshComponent;
|
||||
|
||||
UCLASS(hidecategories=(Collision, Material, Attachment, Actor))
|
||||
class CARLA_API ASceneCaptureToDiskCamera : public AActor
|
||||
{
|
||||
GENERATED_BODY()
|
||||
|
||||
float ElapsedTimeSinceLastCapture = 0.0f;
|
||||
|
||||
size_t CaptureFileNameCount = 0u;
|
||||
|
||||
public:
|
||||
|
||||
UPROPERTY(Category = SceneCapture, EditAnywhere)
|
||||
bool bCaptureScene = true;
|
||||
|
||||
UPROPERTY(Category = SceneCapture, EditAnywhere, meta = (EditCondition = bCaptureScene))
|
||||
FString SaveToFolder;
|
||||
|
||||
UPROPERTY(Category = SceneCapture, EditAnywhere, meta = (EditCondition = bCaptureScene))
|
||||
FString FileName;
|
||||
|
||||
UPROPERTY(Category = SceneCapture, EditAnywhere, meta = (EditCondition = bCaptureScene))
|
||||
float CapturesPerSecond;
|
||||
|
||||
UPROPERTY(Category = SceneCapture, EditAnywhere, meta = (EditCondition = bCaptureScene))
|
||||
uint32 SizeX;
|
||||
|
||||
UPROPERTY(Category = SceneCapture, EditAnywhere, meta = (EditCondition = bCaptureScene))
|
||||
uint32 SizeY;
|
||||
|
||||
private:
|
||||
/** To display the 3d camera in the editor. */
|
||||
UPROPERTY()
|
||||
class UStaticMeshComponent* MeshComp;
|
||||
|
||||
/** To allow drawing the camera frustum in the editor. */
|
||||
UPROPERTY()
|
||||
class UDrawFrustumComponent* DrawFrustum;
|
||||
|
||||
/** Render target necessary for scene capture */
|
||||
UPROPERTY(Transient)
|
||||
class UTextureRenderTarget2D* CaptureRenderTarget;
|
||||
|
||||
/** Scene capture component. */
|
||||
UPROPERTY(Transient)
|
||||
class USceneCaptureComponent2D* CaptureComponent2D;
|
||||
|
||||
public:
|
||||
|
||||
ASceneCaptureToDiskCamera(const FObjectInitializer& ObjectInitializer);
|
||||
|
||||
~ASceneCaptureToDiskCamera();
|
||||
|
||||
virtual void PostActorCreated() override;
|
||||
|
||||
virtual void BeginPlay() override;
|
||||
|
||||
virtual void Tick(float Delta) override;
|
||||
|
||||
/** Used to synchronize the DrawFrustumComponent with the SceneCaptureComponent2D settings. */
|
||||
void UpdateDrawFrustum();
|
||||
|
||||
UFUNCTION(BlueprintCallable, Category="Rendering")
|
||||
void OnInterpToggle(bool bEnable);
|
||||
|
||||
/** Returns CaptureComponent2D subobject **/
|
||||
USceneCaptureComponent2D* GetCaptureComponent2D() const;
|
||||
|
||||
/** Returns DrawFrustum subobject **/
|
||||
UDrawFrustumComponent* GetDrawFrustum() const;
|
||||
|
||||
/** Returns MeshComp subobject **/
|
||||
UStaticMeshComponent* GetMeshComp() const;
|
||||
};
|
Loading…
Reference in New Issue