carla/Source/Carla/SceneCaptureCamera.cpp

341 lines
13 KiB
C++

// CARLA, Copyright (C) 2017 Computer Vision Center (CVC)
#include "Carla.h"
#include "SceneCaptureCamera.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 "Materials/Material.h"
#include "Paths.h"
#include "StaticMeshResources.h"
#include "TextureResource.h"
static constexpr auto DEPTH_MAT_PATH =
#if PLATFORM_LINUX
TEXT("Material'/Carla/PostProcessingMaterials/DepthEffectMaterial_GLSL.DepthEffectMaterial_GLSL'");
#elif PLATFORM_WINDOWS
TEXT("Material'/Carla/PostProcessingMaterials/DepthEffectMaterial.DepthEffectMaterial'");
#else
# error No depth material defined for this platform
#endif
static constexpr auto SEMANTIC_SEGMENTATION_MAT_PATH =
TEXT("Material'/Carla/PostProcessingMaterials/GTMaterial.GTMaterial'");
static void RemoveShowFlags(FEngineShowFlags &ShowFlags);
ASceneCaptureCamera::ASceneCaptureCamera(const FObjectInitializer& ObjectInitializer) :
Super(ObjectInitializer),
SizeX(720u),
SizeY(512u),
PostProcessEffect(EPostProcessEffect::SceneFinal)
{
PrimaryActorTick.bCanEverTick = true; /// @todo Does it need to tick?
PrimaryActorTick.TickGroup = TG_PrePhysics;
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(MeshComp);
CaptureRenderTarget = CreateDefaultSubobject<UTextureRenderTarget2D>(TEXT("CaptureRenderTarget0"));
CaptureComponent2D = CreateDefaultSubobject<USceneCaptureComponent2D>(TEXT("SceneCaptureComponent2D"));
CaptureComponent2D->SetupAttachment(MeshComp);
// Load post-processing materials.
static ConstructorHelpers::FObjectFinder<UMaterial> DEPTH(DEPTH_MAT_PATH);
PostProcessDepth = DEPTH.Object;
static ConstructorHelpers::FObjectFinder<UMaterial> SEMANTIC_SEGMENTATION(SEMANTIC_SEGMENTATION_MAT_PATH);
PostProcessSemanticSegmentation = SEMANTIC_SEGMENTATION.Object;
}
void ASceneCaptureCamera::PostActorCreated()
{
Super::PostActorCreated();
// no need load the editor mesh when there is no editor
#if WITH_EDITOR
if(MeshComp)
{
if (!IsRunningCommandlet())
{
if( !MeshComp->GetStaticMesh())
{
UStaticMesh* CamMesh = LoadObject<UStaticMesh>(NULL, TEXT("/Engine/EditorMeshes/MatineeCam_SM.MatineeCam_SM"), NULL, LOAD_None, NULL);
MeshComp->SetStaticMesh(CamMesh);
}
}
}
#endif // WITH_EDITOR
// Sync component with CameraActor frustum settings.
UpdateDrawFrustum();
}
void ASceneCaptureCamera::BeginPlay()
{
const bool bRemovePostProcessing = (PostProcessEffect != EPostProcessEffect::SceneFinal);
// Setup render target.
const bool bInForceLinearGamma = bRemovePostProcessing;
CaptureRenderTarget->InitCustomFormat(SizeX, SizeY, PF_B8G8R8A8, bInForceLinearGamma);
CaptureComponent2D->Deactivate();
CaptureComponent2D->TextureTarget = CaptureRenderTarget;
// Setup camera post-processing.
if (PostProcessEffect != EPostProcessEffect::None) {
CaptureComponent2D->CaptureSource = ESceneCaptureSource::SCS_FinalColorLDR;
}
if (bRemovePostProcessing) {
RemoveShowFlags(CaptureComponent2D->ShowFlags);
}
if (PostProcessEffect == EPostProcessEffect::Depth) {
CaptureComponent2D->PostProcessSettings.AddBlendable(PostProcessDepth, 1.0f);
} else if (PostProcessEffect == EPostProcessEffect::SemanticSegmentation) {
CaptureComponent2D->PostProcessSettings.AddBlendable(PostProcessSemanticSegmentation, 1.0f);
}
CaptureComponent2D->UpdateContent();
CaptureComponent2D->Activate();
Super::BeginPlay();
}
void ASceneCaptureCamera::SetImageSize(uint32 otherSizeX, uint32 otherSizeY)
{
SizeX = otherSizeX;
SizeY = otherSizeY;
}
void ASceneCaptureCamera::SetPostProcessEffect(EPostProcessEffect otherPostProcessEffect)
{
PostProcessEffect = otherPostProcessEffect;
auto &PostProcessSettings = CaptureComponent2D->PostProcessSettings;
if (PostProcessEffect != EPostProcessEffect::SceneFinal) {
PostProcessSettings.bOverride_AutoExposureMethod = false;
PostProcessSettings.bOverride_AutoExposureMinBrightness = false;
PostProcessSettings.bOverride_AutoExposureMaxBrightness = false;
PostProcessSettings.bOverride_AutoExposureBias = false;
}
}
void ASceneCaptureCamera::SetFOVAngle(float FOVAngle)
{
check(CaptureComponent2D != nullptr);
CaptureComponent2D->FOVAngle = FOVAngle;
}
void ASceneCaptureCamera::Set(const FCameraDescription &CameraDescription)
{
SetImageSize(CameraDescription.ImageSizeX, CameraDescription.ImageSizeY);
SetPostProcessEffect(CameraDescription.PostProcessEffect);
SetFOVAngle(CameraDescription.FOVAngle);
}
void ASceneCaptureCamera::Set(
const FCameraDescription &CameraDescription,
const FCameraPostProcessParameters &OverridePostProcessParameters)
{
auto &PostProcessSettings = CaptureComponent2D->PostProcessSettings;
PostProcessSettings.bOverride_AutoExposureMethod = true;
PostProcessSettings.AutoExposureMethod = OverridePostProcessParameters.AutoExposureMethod;
PostProcessSettings.bOverride_AutoExposureMinBrightness = true;
PostProcessSettings.AutoExposureMinBrightness = OverridePostProcessParameters.AutoExposureMinBrightness;
PostProcessSettings.bOverride_AutoExposureMaxBrightness = true;
PostProcessSettings.AutoExposureMaxBrightness = OverridePostProcessParameters.AutoExposureMaxBrightness;
PostProcessSettings.bOverride_AutoExposureBias = true;
PostProcessSettings.AutoExposureBias = OverridePostProcessParameters.AutoExposureBias;
Set(CameraDescription);
}
bool ASceneCaptureCamera::ReadPixels(TArray<FColor> &BitMap) const
{
FTextureRenderTargetResource* RTResource = CaptureRenderTarget->GameThread_GetRenderTargetResource();
if (RTResource == nullptr) {
UE_LOG(LogCarla, Error, TEXT("SceneCaptureCamera: Missing render target"));
return false;
}
FReadSurfaceDataFlags ReadPixelFlags(RCM_UNorm);
ReadPixelFlags.SetLinearToGamma(true);
return RTResource->ReadPixels(BitMap, ReadPixelFlags);
}
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;
}
}
// Remove the show flags that might interfere with post-processing effects like
// depth and semantic segmentation.
static void RemoveShowFlags(FEngineShowFlags &ShowFlags)
{
ShowFlags.SetAmbientOcclusion(false);
ShowFlags.SetAntiAliasing(false);
ShowFlags.SetAtmosphericFog(false);
// ShowFlags.SetAudioRadius(false);
// ShowFlags.SetBillboardSprites(false);
ShowFlags.SetBloom(false);
// ShowFlags.SetBounds(false);
// ShowFlags.SetBrushes(false);
// ShowFlags.SetBSP(false);
// ShowFlags.SetBSPSplit(false);
// ShowFlags.SetBSPTriangles(false);
// ShowFlags.SetBuilderBrush(false);
// ShowFlags.SetCameraAspectRatioBars(false);
// ShowFlags.SetCameraFrustums(false);
ShowFlags.SetCameraImperfections(false);
ShowFlags.SetCameraInterpolation(false);
// ShowFlags.SetCameraSafeFrames(false);
// ShowFlags.SetCollision(false);
// ShowFlags.SetCollisionPawn(false);
// ShowFlags.SetCollisionVisibility(false);
ShowFlags.SetColorGrading(false);
// ShowFlags.SetCompositeEditorPrimitives(false);
// ShowFlags.SetConstraints(false);
// ShowFlags.SetCover(false);
// ShowFlags.SetDebugAI(false);
// ShowFlags.SetDecals(false);
// ShowFlags.SetDeferredLighting(false);
ShowFlags.SetDepthOfField(false);
ShowFlags.SetDiffuse(false);
ShowFlags.SetDirectionalLights(false);
ShowFlags.SetDirectLighting(false);
// ShowFlags.SetDistanceCulledPrimitives(false);
// ShowFlags.SetDistanceFieldAO(false);
// ShowFlags.SetDistanceFieldGI(false);
ShowFlags.SetDynamicShadows(false);
// ShowFlags.SetEditor(false);
ShowFlags.SetEyeAdaptation(false);
ShowFlags.SetFog(false);
// ShowFlags.SetGame(false);
// ShowFlags.SetGameplayDebug(false);
// ShowFlags.SetGBufferHints(false);
ShowFlags.SetGlobalIllumination(false);
ShowFlags.SetGrain(false);
// ShowFlags.SetGrid(false);
// ShowFlags.SetHighResScreenshotMask(false);
// ShowFlags.SetHitProxies(false);
ShowFlags.SetHLODColoration(false);
ShowFlags.SetHMDDistortion(false);
// ShowFlags.SetIndirectLightingCache(false);
// ShowFlags.SetInstancedFoliage(false);
// ShowFlags.SetInstancedGrass(false);
// ShowFlags.SetInstancedStaticMeshes(false);
// ShowFlags.SetLandscape(false);
// ShowFlags.SetLargeVertices(false);
ShowFlags.SetLensFlares(false);
ShowFlags.SetLevelColoration(false);
ShowFlags.SetLightComplexity(false);
ShowFlags.SetLightFunctions(false);
ShowFlags.SetLightInfluences(false);
ShowFlags.SetLighting(false);
ShowFlags.SetLightMapDensity(false);
ShowFlags.SetLightRadius(false);
ShowFlags.SetLightShafts(false);
// ShowFlags.SetLOD(false);
ShowFlags.SetLODColoration(false);
// ShowFlags.SetMaterials(false);
// ShowFlags.SetMaterialTextureScaleAccuracy(false);
// ShowFlags.SetMeshEdges(false);
// ShowFlags.SetMeshUVDensityAccuracy(false);
// ShowFlags.SetModeWidgets(false);
ShowFlags.SetMotionBlur(false);
// ShowFlags.SetNavigation(false);
ShowFlags.SetOnScreenDebug(false);
// ShowFlags.SetOutputMaterialTextureScales(false);
// ShowFlags.SetOverrideDiffuseAndSpecular(false);
// ShowFlags.SetPaper2DSprites(false);
ShowFlags.SetParticles(false);
// ShowFlags.SetPivot(false);
ShowFlags.SetPointLights(false);
// ShowFlags.SetPostProcessing(false);
// ShowFlags.SetPostProcessMaterial(false);
// ShowFlags.SetPrecomputedVisibility(false);
// ShowFlags.SetPrecomputedVisibilityCells(false);
// ShowFlags.SetPreviewShadowsIndicator(false);
// ShowFlags.SetPrimitiveDistanceAccuracy(false);
ShowFlags.SetPropertyColoration(false);
// ShowFlags.SetQuadOverdraw(false);
// ShowFlags.SetReflectionEnvironment(false);
// ShowFlags.SetReflectionOverride(false);
ShowFlags.SetRefraction(false);
// ShowFlags.SetRendering(false);
ShowFlags.SetSceneColorFringe(false);
// ShowFlags.SetScreenPercentage(false);
ShowFlags.SetScreenSpaceAO(false);
ShowFlags.SetScreenSpaceReflections(false);
// ShowFlags.SetSelection(false);
// ShowFlags.SetSelectionOutline(false);
// ShowFlags.SetSeparateTranslucency(false);
// ShowFlags.SetShaderComplexity(false);
// ShowFlags.SetShaderComplexityWithQuadOverdraw(false);
// ShowFlags.SetShadowFrustums(false);
// ShowFlags.SetSkeletalMeshes(false);
// ShowFlags.SetSkinCache(false);
ShowFlags.SetSkyLighting(false);
// ShowFlags.SetSnap(false);
// ShowFlags.SetSpecular(false);
// ShowFlags.SetSplines(false);
ShowFlags.SetSpotLights(false);
// ShowFlags.SetStaticMeshes(false);
ShowFlags.SetStationaryLightOverlap(false);
// ShowFlags.SetStereoRendering(false);
// ShowFlags.SetStreamingBounds(false);
ShowFlags.SetSubsurfaceScattering(false);
// ShowFlags.SetTemporalAA(false);
// ShowFlags.SetTessellation(false);
// ShowFlags.SetTestImage(false);
// ShowFlags.SetTextRender(false);
// ShowFlags.SetTexturedLightProfiles(false);
ShowFlags.SetTonemapper(false);
// ShowFlags.SetTranslucency(false);
// ShowFlags.SetVectorFields(false);
// ShowFlags.SetVertexColors(false);
// ShowFlags.SetVignette(false);
// ShowFlags.SetVisLog(false);
ShowFlags.SetVisualizeAdaptiveDOF(false);
ShowFlags.SetVisualizeBloom(false);
ShowFlags.SetVisualizeBuffer(false);
ShowFlags.SetVisualizeDistanceFieldAO(false);
ShowFlags.SetVisualizeDistanceFieldGI(false);
ShowFlags.SetVisualizeDOF(false);
ShowFlags.SetVisualizeHDR(false);
ShowFlags.SetVisualizeLightCulling(false);
ShowFlags.SetVisualizeLPV(false);
ShowFlags.SetVisualizeMeshDistanceFields(false);
ShowFlags.SetVisualizeMotionBlur(false);
ShowFlags.SetVisualizeOutOfBoundsPixels(false);
ShowFlags.SetVisualizeSenses(false);
ShowFlags.SetVisualizeShadingModels(false);
ShowFlags.SetVisualizeSSR(false);
ShowFlags.SetVisualizeSSS(false);
// ShowFlags.SetVolumeLightingSamples(false);
// ShowFlags.SetVolumes(false);
// ShowFlags.SetWidgetComponents(false);
// ShowFlags.SetWireframe(false);
}