diff --git a/AirLib/include/common/AirSimSettings.hpp b/AirLib/include/common/AirSimSettings.hpp index d108111a6a..9f8e3a0ab7 100644 --- a/AirLib/include/common/AirSimSettings.hpp +++ b/AirLib/include/common/AirSimSettings.hpp @@ -87,15 +87,39 @@ struct AirSimSettings { float target_gamma = Utils::nan(); //1.0f; //This would be reset to kSceneTargetGamma for scene as default }; + struct NoiseSetting { + int ImageType = 0; + + bool Enabled = false; + float HorzWaveStrength = 0.01f; + float RandSpeed = 10.0f; + float RandSize = 300.0f; + float RandDensity = 2.0f; + float RandContrib = 0.1f; + float HorzWaveContrib = 0.8f; + float HorzWaveVertSize = 100.0f; + float HorzWaveScreenSize = 50.0f; + float HorzNoiseLinesContrib = 1.0f; + float HorzNoiseLinesDensityY = 0.01f; + float HorzNoiseLinesDensityXY = 0.1f; + float HorzDistortionStrength = 0.01f; + float HorzDistortionContrib = 0.5f; + }; + private: //fields float settings_version_actual; float settings_version_minimum = 1; public: //fields std::string simmode_name; + std::vector subwindow_settings; - std::vector capture_settings; + + std::map capture_settings; + std::map noise_settings; + RecordingSettings recording_settings; + std::vector warning_messages; bool is_record_ui_visible; @@ -137,6 +161,7 @@ struct AirSimSettings { loadViewModeSettings(settings); loadRecordingSettings(settings); loadCaptureSettings(settings); + loadCameraNoiseSettings(settings); loadOtherSettings(settings); return static_cast(warning_messages.size()); @@ -147,7 +172,7 @@ struct AirSimSettings { warning_messages.clear(); initializeSubwindowSettings(); - initializeCaptureSettings(); + initializeImageTypeSettings(); simmode_name = ""; recording_settings = RecordingSettings(); @@ -337,10 +362,46 @@ struct AirSimSettings { } } - void createCaptureSettings(const msr::airlib::Settings& settings, CaptureSetting& capture_setting) + void loadCameraNoiseSettings(const Settings& settings) { - typedef msr::airlib::Settings Settings; + Settings json_settings_parent; + if (settings.getChild("NoiseSetting", json_settings_parent)) { + for (size_t child_index = 0; child_index < json_settings_parent.size(); ++child_index) { + Settings json_settings_child; + if (json_settings_parent.getChild(child_index, json_settings_child)) { + NoiseSetting noise_setting; + createNoiseSettings(json_settings_child, noise_setting); + if (noise_setting.ImageType >= 0 && noise_setting.ImageType < noise_settings.size()) + noise_settings[noise_setting.ImageType] = noise_setting; + else + throw std::invalid_argument("ImageType must be >= 0 and < " + std::to_string(noise_settings.size())); + } + } + } + } + + void createNoiseSettings(const msr::airlib::Settings& settings, NoiseSetting& noise_setting) + { + noise_setting.Enabled = settings.getBool("Enabled", noise_setting.Enabled); + noise_setting.ImageType = settings.getInt("ImageType", noise_setting.ImageType); + + noise_setting.HorzWaveStrength = settings.getFloat("HorzWaveStrength", noise_setting.HorzWaveStrength); + noise_setting.RandSpeed = settings.getFloat("RandSpeed", noise_setting.RandSpeed); + noise_setting.RandSize = settings.getFloat("RandSize", noise_setting.RandSize); + noise_setting.RandDensity = settings.getFloat("RandDensity", noise_setting.RandDensity); + noise_setting.RandContrib = settings.getFloat("RandContrib", noise_setting.RandContrib); + noise_setting.HorzWaveContrib = settings.getFloat("HorzWaveContrib", noise_setting.HorzWaveContrib); + noise_setting.HorzWaveVertSize = settings.getFloat("HorzWaveVertSize", noise_setting.HorzWaveVertSize); + noise_setting.HorzWaveScreenSize = settings.getFloat("HorzWaveScreenSize", noise_setting.HorzWaveScreenSize); + noise_setting.HorzNoiseLinesContrib = settings.getFloat("HorzNoiseLinesContrib", noise_setting.HorzNoiseLinesContrib); + noise_setting.HorzNoiseLinesDensityY = settings.getFloat("HorzNoiseLinesDensityY", noise_setting.HorzNoiseLinesDensityY); + noise_setting.HorzNoiseLinesDensityXY = settings.getFloat("HorzNoiseLinesDensityXY", noise_setting.HorzNoiseLinesDensityXY); + noise_setting.HorzDistortionStrength = settings.getFloat("HorzDistortionStrength", noise_setting.HorzDistortionStrength); + noise_setting.HorzDistortionContrib = settings.getFloat("HorzDistortionContrib", noise_setting.HorzDistortionContrib); + } + void createCaptureSettings(const msr::airlib::Settings& settings, CaptureSetting& capture_setting) + { capture_setting.width = settings.getInt("Width", capture_setting.width); capture_setting.height = settings.getInt("Height", capture_setting.height); capture_setting.fov_degrees = settings.getFloat("FOV_Degrees", capture_setting.fov_degrees); @@ -376,10 +437,17 @@ struct AirSimSettings { } } - void initializeCaptureSettings() + void initializeImageTypeSettings() { capture_settings.clear(); - capture_settings.assign(Utils::toNumeric(ImageType::Count), CaptureSetting()); + + int image_count = Utils::toNumeric(ImageType::Count); + + for (int i = -1; i < image_count; ++i) { + capture_settings[i] = CaptureSetting(); + noise_settings[i] = NoiseSetting(); + } + capture_settings.at(Utils::toNumeric(ImageType::Scene)).target_gamma = CaptureSetting::kSceneTargetGamma; } diff --git a/Unreal/Environments/Blocks/Source/Blocks/Blocks.Build.cs b/Unreal/Environments/Blocks/Source/Blocks/Blocks.Build.cs index a5bb60e116..be47a9adad 100644 --- a/Unreal/Environments/Blocks/Source/Blocks/Blocks.Build.cs +++ b/Unreal/Environments/Blocks/Source/Blocks/Blocks.Build.cs @@ -4,9 +4,10 @@ public class Blocks : ModuleRules { - public Blocks(ReadOnlyTargetRules Target) : base(Target) - { + public Blocks(ReadOnlyTargetRules Target) : base(Target) + { PCHUsage = PCHUsageMode.UseExplicitOrSharedPCHs; + bEnableExceptions = true; PublicDependencyModuleNames.AddRange(new string[] { "Core", "CoreUObject", "Engine", "InputCore" }); - } + } } diff --git a/Unreal/Plugins/AirSim/Content/HUDAssets/CameraSensorNoise.uasset b/Unreal/Plugins/AirSim/Content/HUDAssets/CameraSensorNoise.uasset index 2e08d9eaf2..eca00148ab 100644 Binary files a/Unreal/Plugins/AirSim/Content/HUDAssets/CameraSensorNoise.uasset and b/Unreal/Plugins/AirSim/Content/HUDAssets/CameraSensorNoise.uasset differ diff --git a/Unreal/Plugins/AirSim/Source/PIPCamera.cpp b/Unreal/Plugins/AirSim/Source/PIPCamera.cpp index c39a2786ca..50dd2834ea 100644 --- a/Unreal/Plugins/AirSim/Source/PIPCamera.cpp +++ b/Unreal/Plugins/AirSim/Source/PIPCamera.cpp @@ -7,9 +7,17 @@ #include "AirBlueprintLib.h" #include "ImageUtils.h" -unsigned int APIPCamera::imageTypeCount() + +APIPCamera::APIPCamera() { - return Utils::toNumeric(ImageType::Count); + static ConstructorHelpers::FObjectFinder mat_finder(TEXT("Material'/AirSim/HUDAssets/CameraSensorNoise.CameraSensorNoise'")); + if (mat_finder.Succeeded()) + { + noise_material_static_ = mat_finder.Object; + } + else + UAirBlueprintLib::LogMessageString("Cannot create noise material for the PIPCamera", + "", LogDebugLevel::Failure); } void APIPCamera::PostInitializeComponents() @@ -34,6 +42,7 @@ void APIPCamera::PostInitializeComponents() UAirBlueprintLib::GetActorComponent(this, TEXT("SegmentationCaptureComponent")); captures_[Utils::toNumeric(ImageType::SurfaceNormals)] = UAirBlueprintLib::GetActorComponent(this, TEXT("NormalsCaptureComponent")); + } void APIPCamera::BeginPlay() @@ -48,13 +57,38 @@ void APIPCamera::BeginPlay() captures_[image_type]->CaptureSource = ESceneCaptureSource::SCS_FinalColorLDR; render_targets_[image_type] = NewObject(); - updateCaptureComponentSetting(captures_[image_type], render_targets_[image_type], - AirSimSettings::singleton().capture_settings[image_type]); } } +void APIPCamera::setNoiseMaterial(FPostProcessSettings& obj, const NoiseSetting& settings) +{ + if (!settings.Enabled) + return; + + noise_material_ = UMaterialInstanceDynamic::Create(noise_material_static_, GetWorld()); + + noise_material_->SetScalarParameterValue("HorzWaveStrength", settings.HorzWaveStrength); + noise_material_->SetScalarParameterValue("RandSpeed", settings.RandSpeed); + noise_material_->SetScalarParameterValue("RandSize", settings.RandSize); + noise_material_->SetScalarParameterValue("RandDensity", settings.RandDensity); + noise_material_->SetScalarParameterValue("RandContrib", settings.RandContrib); + noise_material_->SetScalarParameterValue("HorzWaveContrib", settings.HorzWaveContrib); + noise_material_->SetScalarParameterValue("HorzWaveVertSize", settings.HorzWaveVertSize); + noise_material_->SetScalarParameterValue("HorzWaveScreenSize", settings.HorzWaveScreenSize); + noise_material_->SetScalarParameterValue("HorzNoiseLinesContrib", settings.HorzNoiseLinesContrib); + noise_material_->SetScalarParameterValue("HorzNoiseLinesDensityY", settings.HorzNoiseLinesDensityY); + noise_material_->SetScalarParameterValue("HorzNoiseLinesDensityXY", settings.HorzNoiseLinesDensityXY); + noise_material_->SetScalarParameterValue("HorzDistortionStrength", settings.HorzDistortionStrength); + noise_material_->SetScalarParameterValue("HorzDistortionContrib", settings.HorzDistortionContrib); + + obj.AddBlendable(noise_material_, 1.0f); +} + void APIPCamera::EndPlay(const EEndPlayReason::Type EndPlayReason) { + noise_material_static_ = nullptr; + noise_material_ = nullptr; + for (unsigned int image_type = 0; image_type < imageTypeCount(); ++image_type) { //use final color for all calculations captures_[image_type] = nullptr; @@ -62,6 +96,12 @@ void APIPCamera::EndPlay(const EEndPlayReason::Type EndPlayReason) } } + +unsigned int APIPCamera::imageTypeCount() +{ + return Utils::toNumeric(ImageType::Count); +} + void APIPCamera::showToScreen() { camera_->SetVisibility(true); @@ -86,12 +126,13 @@ void APIPCamera::setCameraTypeEnabled(ImageType type, bool enabled) enableCaptureComponent(type, enabled); } -void APIPCamera::setCaptureSetting(const APIPCamera::CaptureSetting& setting) +void APIPCamera::setImageTypeSettings(int image_type, const APIPCamera::CaptureSetting& capture_setting, + const APIPCamera::NoiseSetting& noise_setting) { - unsigned int image_type = static_cast(setting.image_type); - updateCaptureComponentSetting(captures_[image_type], render_targets_[image_type], - setting); + capture_setting); + + setNoiseMaterial(captures_[image_type]->PostProcessSettings, noise_setting); } void APIPCamera::updateCaptureComponentSetting(USceneCaptureComponent2D* capture, UTextureRenderTarget2D* render_target, const CaptureSetting& setting) diff --git a/Unreal/Plugins/AirSim/Source/PIPCamera.h b/Unreal/Plugins/AirSim/Source/PIPCamera.h index 5fc7f47df7..208d306f69 100644 --- a/Unreal/Plugins/AirSim/Source/PIPCamera.h +++ b/Unreal/Plugins/AirSim/Source/PIPCamera.h @@ -19,6 +19,10 @@ class AIRSIM_API APIPCamera : public ACameraActor typedef msr::airlib::ImageCaptureBase::ImageType ImageType; typedef msr::airlib::AirSimSettings AirSimSettings; typedef AirSimSettings::CaptureSetting CaptureSetting; + typedef AirSimSettings::NoiseSetting NoiseSetting; + + + APIPCamera(); virtual void PostInitializeComponents() override; virtual void BeginPlay() override; @@ -31,7 +35,8 @@ class AIRSIM_API APIPCamera : public ACameraActor void setCameraTypeEnabled(ImageType type, bool enabled); bool getCameraTypeEnabled(ImageType type) const; - void setCaptureSetting(const CaptureSetting& setting); + void setImageTypeSettings(int image_type, const APIPCamera::CaptureSetting& capture_setting, + const APIPCamera::NoiseSetting& noise_setting); USceneCaptureComponent2D* getCaptureComponent(const ImageType type, bool if_active); UTextureRenderTarget2D* getRenderTarget(const ImageType type, bool if_active); @@ -45,6 +50,8 @@ class AIRSIM_API APIPCamera : public ACameraActor UPROPERTY() TArray render_targets_; UPROPERTY() UCameraComponent* camera_; + UPROPERTY() UMaterialInstanceDynamic* noise_material_ = nullptr; + UPROPERTY() UMaterial* noise_material_static_ = nullptr; std::vector camera_type_enabled_; @@ -52,4 +59,5 @@ class AIRSIM_API APIPCamera : public ACameraActor static unsigned int imageTypeCount(); void enableCaptureComponent(const ImageType type, bool is_enabled); static void updateCaptureComponentSetting(USceneCaptureComponent2D* capture, UTextureRenderTarget2D* render_target, const CaptureSetting& setting); + void setNoiseMaterial(FPostProcessSettings& obj, const NoiseSetting& settings); }; diff --git a/Unreal/Plugins/AirSim/Source/VehiclePawnWrapper.cpp b/Unreal/Plugins/AirSim/Source/VehiclePawnWrapper.cpp index 718da2f505..ec9c1e04ad 100644 --- a/Unreal/Plugins/AirSim/Source/VehiclePawnWrapper.cpp +++ b/Unreal/Plugins/AirSim/Source/VehiclePawnWrapper.cpp @@ -24,11 +24,12 @@ void VehiclePawnWrapper::setupCamerasFromSettings() typedef msr::airlib::ImageCaptureBase::ImageType ImageType; typedef msr::airlib::AirSimSettings AirSimSettings; - - for (const AirSimSettings::CaptureSetting& capture_setting : AirSimSettings::singleton().capture_settings) { + int image_count = static_cast(Utils::toNumeric(ImageType::Count)); + for (int image_type = 0; image_type < image_count; ++image_type) { for (int camera_index = 0; camera_index < getCameraCount(); ++camera_index) { APIPCamera* camera = getCamera(camera_index); - camera->setCaptureSetting(capture_setting); + camera->setImageTypeSettings(image_type, AirSimSettings::singleton().capture_settings[image_type], + AirSimSettings::singleton().noise_settings[image_type]); } } }