Android build settings + metaxr

This commit is contained in:
2025-05-14 14:00:02 +03:00
parent 6a2bb7475e
commit d5aa21f55c
594 changed files with 200530 additions and 2 deletions

View File

@@ -0,0 +1,49 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#include "OculusXRAnchorsRules.h"
#include "CoreMinimal.h"
#include "OculusXRHMDRuntimeSettings.h"
#include "OculusXRAnchorComponents.h"
#include "OculusXRPSTUtils.h"
#include "OculusXRSceneActor.h"
namespace OculusXRAnchorsRules
{
bool FEnableAnchorSupportRule::IsApplied() const
{
const UOculusXRHMDRuntimeSettings* Settings = GetMutableDefault<UOculusXRHMDRuntimeSettings>();
return Settings->bAnchorSupportEnabled;
}
void FEnableAnchorSupportRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OCULUSXR_UPDATE_SETTINGS(UOculusXRHMDRuntimeSettings, bAnchorSupportEnabled, true);
OutShouldRestartEditor = false;
}
bool FEnableAnchorSupportRule::IsValid()
{
return OculusXRPSTUtils::IsComponentOfTypeInWorld<UOculusXRBaseAnchorComponent>() || OculusXRPSTUtils::IsComponentOfTypeInWorld<AOculusXRSceneActor>();
}
bool FEnableSceneSupportRule::IsApplied() const
{
const UOculusXRHMDRuntimeSettings* Settings = GetMutableDefault<UOculusXRHMDRuntimeSettings>();
return Settings->bSceneSupportEnabled;
}
void FEnableSceneSupportRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OCULUSXR_UPDATE_SETTINGS(UOculusXRHMDRuntimeSettings, bSceneSupportEnabled, true);
OutShouldRestartEditor = false;
}
bool FEnableSceneSupportRule::IsValid()
{
return OculusXRPSTUtils::IsComponentOfTypeInWorld<AOculusXRSceneActor>();
}
} // namespace OculusXRAnchorsRules
#undef LOCTEXT_NAMESPACE

View File

@@ -0,0 +1,49 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#pragma once
#include "OculusXRSetupRule.h"
/*
* Collection of rules related to anchors. Can be extended as needed
*/
namespace OculusXRAnchorsRules
{
class FEnableAnchorSupportRule final : public ISetupRule
{
public:
FEnableAnchorSupportRule()
: ISetupRule(
"Feature_EnableAnchorSupport",
NSLOCTEXT("OculusXRAnchorsRules", "EnableAnchorSupport_DisplayName", "Enable Anchor Support"),
NSLOCTEXT("OculusXRAnchorsRules", "EnableAnchorSupport_Description", "Anchor support must be enabled when using anchor features"),
ESetupRuleCategory::Features,
ESetupRuleSeverity::Critical) {}
virtual bool IsApplied() const override;
virtual bool IsValid() override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
class FEnableSceneSupportRule final : public ISetupRule
{
public:
FEnableSceneSupportRule()
: ISetupRule(
"Feature_EnableSceneSupport",
NSLOCTEXT("OculusXRAnchorsRules", "EnableSceneSupport_DisplayName", "Enable Scene Support"),
NSLOCTEXT("OculusXRAnchorsRules", "EnableSceneSupport_Description", "Scene support must be enabled when using scene features"),
ESetupRuleCategory::Features,
ESetupRuleSeverity::Critical) {}
virtual bool IsApplied() const override;
virtual bool IsValid() override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
inline TArray<SetupRulePtr> AnchorRules_Table{
MakeShared<FEnableAnchorSupportRule>(),
MakeShared<FEnableSceneSupportRule>()
};
} // namespace OculusXRAnchorsRules

View File

@@ -0,0 +1,367 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#include "OculusXRCompatibilityRules.h"
#include "CoreMinimal.h"
#include "AndroidRuntimeSettings.h"
#include "AndroidSDKSettings.h"
#include "GeneralProjectSettings.h"
#include "ISettingsModule.h"
#include "ISettingsCategory.h"
#include "ISettingsContainer.h"
#include "ISettingsSection.h"
#include "OculusXRRuleProcessorSubsystem.h"
#include "GameFramework/InputSettings.h"
#include "OculusXRHMDRuntimeSettings.h"
#include "OculusXRPSTUtils.h"
#include "Misc/EngineVersionComparison.h"
#define LOCTEXT_NAMESPACE "OculusXRCompatibilityRules"
namespace
{
constexpr int32 MinimumAndroidAPILevel = 32; // With Quest 1 support ending in Jan 2025, API level 29 is no longer supported.
constexpr int32 TargetAndroidAPILevel = 32; // Target API 32 or higher is required to submit to the Meta Quest Store. See https://developer.oculus.com/blog/meta-quest-apps-android-12l-june-30/
constexpr char AndroidNDKVersionNumber[] = "25.1.8937393";
// SDK Max API level is determined by reviewing SetupAndroid.bat for each UE version.
// SDK Min API Level is determined by Quest Store requirements as noted above.
#if UE_VERSION_OLDER_THAN(5, 4, 0)
constexpr char AndroidSDKAPIMinLevel[] = "android-32";
constexpr char AndroidSDKAPIMaxLevel[] = "android-32";
constexpr int32 AndroidSDKAPIMinLevelInt = 32;
constexpr int32 AndroidSDKAPIMaxLevelInt = 32;
constexpr char AndroidNDKAPIMinLevel[] = "android-32";
constexpr char AndroidNDKAPIMaxLevel[] = "android-32";
constexpr int32 AndroidNDKAPIMinLevelInt = 32;
constexpr int32 AndroidNDKAPIMaxLevelInt = 32;
#elif UE_VERSION_OLDER_THAN(5, 5, 0)
constexpr char AndroidSDKAPIMinLevel[] = "android-32";
constexpr char AndroidSDKAPIMaxLevel[] = "android-33";
constexpr int32 AndroidSDKAPIMinLevelInt = 32;
constexpr int32 AndroidSDKAPIMaxLevelInt = 33;
constexpr char AndroidNDKAPIMinLevel[] = "android-32";
constexpr char AndroidNDKAPIMaxLevel[] = "android-33";
constexpr int32 AndroidNDKAPIMinLevelInt = 32;
constexpr int32 AndroidNDKAPIMaxLevelInt = 33;
#else // 5.5 and newer
constexpr char AndroidSDKAPIMinLevel[] = "android-32";
constexpr char AndroidSDKAPIMaxLevel[] = "android-34";
constexpr int32 AndroidSDKAPIMinLevelInt = 32;
constexpr int32 AndroidSDKAPIMaxLevelInt = 34;
constexpr char AndroidNDKAPIMinLevel[] = "android-32";
constexpr char AndroidNDKAPIMaxLevel[] = "android-33"; // API level 34 is not supported by NDK 25.1.8937393
constexpr int32 AndroidNDKAPIMinLevelInt = 32;
constexpr int32 AndroidNDKAPIMaxLevelInt = 33;
#endif
} // namespace
namespace OculusXRCompatibilityRules
{
FUseAndroidSDKMinimumRule::FUseAndroidSDKMinimumRule()
: ISetupRule(
"Compatibility_UseAndroidSDKMinimum",
LOCTEXT("UseAndroidSDKMinimum_DisplayName", "Use Android SDK Minimum Version"),
FText::Format(
LOCTEXT("UseAndroidSDKMinimum_Description", "Minimum Android API level must be at least {0}."),
MinimumAndroidAPILevel),
ESetupRuleCategory::Compatibility,
ESetupRuleSeverity::Critical,
MetaQuest_All) {}
bool FUseAndroidSDKMinimumRule::IsApplied() const
{
const UAndroidRuntimeSettings* Settings = GetMutableDefault<UAndroidRuntimeSettings>();
return Settings->MinSDKVersion >= MinimumAndroidAPILevel;
}
void FUseAndroidSDKMinimumRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OCULUSXR_UPDATE_SETTINGS(UAndroidRuntimeSettings, MinSDKVersion, MinimumAndroidAPILevel);
OutShouldRestartEditor = false;
}
FUseAndroidSDKTargetRule::FUseAndroidSDKTargetRule()
: ISetupRule(
"Compatibility_UseAndroidSDKTarget",
LOCTEXT("UseAndroidSDKTarget_DisplayName", "Use Android SDK Target Version"),
FText::Format(
LOCTEXT("UseAndroidSDKTarget_Description", "Target Android API level must be at least {0}."),
TargetAndroidAPILevel),
ESetupRuleCategory::Compatibility,
ESetupRuleSeverity::Critical,
MetaQuest_All) {}
bool FUseAndroidSDKTargetRule::IsApplied() const
{
const UAndroidRuntimeSettings* Settings = GetMutableDefault<UAndroidRuntimeSettings>();
return Settings->TargetSDKVersion >= TargetAndroidAPILevel;
}
void FUseAndroidSDKTargetRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OCULUSXR_UPDATE_SETTINGS(UAndroidRuntimeSettings, TargetSDKVersion, TargetAndroidAPILevel);
OutShouldRestartEditor = false;
}
FUseAndroidSDKLevelRule::FUseAndroidSDKLevelRule()
: ISetupRule(
"Compatibility_UseAndroidSDKLevel",
LOCTEXT("UseAndroidSDKLevel_DisplayName", "Use Android SDK Level"),
FText::Format(
LOCTEXT("UseAndroidSDKLevel_Description", "Android SDK level should be set between {0} and {1} prior to packaging apks."),
FText::AsCultureInvariant(AndroidSDKAPIMinLevel), FText::AsCultureInvariant(AndroidSDKAPIMaxLevel)),
TEXT("https://developer.oculus.com/blog/meta-quest-apps-android-12l-june-30/"),
ESetupRuleCategory::Compatibility,
ESetupRuleSeverity::Critical,
MetaQuest_All,
true) {}
bool FUseAndroidSDKLevelRule::IsApplied() const
{
const UAndroidSDKSettings* Settings = GetMutableDefault<UAndroidSDKSettings>();
FString SDKAPILevel = Settings->SDKAPILevel;
if (SDKAPILevel.IsEmpty())
{
return false;
}
if (SDKAPILevel.Equals(TEXT("latest")) || SDKAPILevel.Equals(TEXT("matchndk")))
{
return true;
}
if (!SDKAPILevel.Left(8).Equals(TEXT("android-")))
{
return false;
}
if (FCString::Atoi(*SDKAPILevel.Right(2)) < AndroidSDKAPIMinLevelInt)
{
return false;
}
if (FCString::Atoi(*SDKAPILevel.Right(2)) > AndroidSDKAPIMaxLevelInt)
{
return false;
}
return true;
}
void SaveSDKSettings()
{
ISettingsModule* SettingsModule = FModuleManager::GetModulePtr<ISettingsModule>("Settings");
if (!SettingsModule)
{
return;
}
ISettingsContainerPtr SettingsContainer = SettingsModule->GetContainer("Project");
if (!SettingsContainer.IsValid())
{
return;
}
ISettingsCategoryPtr SettingsCategory = SettingsContainer->GetCategory("Platforms");
if (!SettingsCategory.IsValid())
{
return;
}
ISettingsSectionPtr SettingsSection = SettingsCategory->GetSection("AndroidSDK");
if (!SettingsSection.IsValid())
{
return;
}
TWeakObjectPtr<UObject> SettingsObject = SettingsSection->GetSettingsObject();
if (!SettingsObject.IsValid())
{
return;
}
SettingsObject->UpdateGlobalUserConfigFile();
}
void FUseAndroidSDKLevelRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OutShouldRestartEditor = false;
OCULUSXR_UPDATE_SETTINGS(UAndroidSDKSettings, SDKAPILevel, FText::AsCultureInvariant(AndroidSDKAPIMinLevel).ToString());
SaveSDKSettings();
}
FUseAndroidNDKLevelRule::FUseAndroidNDKLevelRule()
: ISetupRule(
"Compatibility_UseAndroidNDKLevel",
LOCTEXT("UseAndroidNDKLevel_DisplayName", "Use Android NDK Level"),
FText::Format(
LOCTEXT("UseAndroidNDKLevel_Description", "Android NDK level should be set between {0} and {1} prior to packaging apks."),
FText::AsCultureInvariant(AndroidNDKAPIMinLevel), FText::AsCultureInvariant(AndroidNDKAPIMaxLevel)),
TEXT("https://developer.oculus.com/blog/meta-quest-apps-must-target-android-10-starting-september-29/"),
ESetupRuleCategory::Compatibility,
ESetupRuleSeverity::Critical,
MetaQuest_All,
true) {}
bool FUseAndroidNDKLevelRule::IsApplied() const
{
const UAndroidSDKSettings* Settings = GetMutableDefault<UAndroidSDKSettings>();
FString NDKAPILevel = Settings->NDKAPILevel;
if (NDKAPILevel.IsEmpty())
{
return false;
}
if (NDKAPILevel.Equals(TEXT("latest")))
{
return true;
}
if (!NDKAPILevel.Left(8).Equals(TEXT("android-")))
{
return false;
}
if (FCString::Atoi(*NDKAPILevel.Right(2)) < AndroidNDKAPIMinLevelInt)
{
return false;
}
if (FCString::Atoi(*NDKAPILevel.Right(2)) > AndroidNDKAPIMaxLevelInt)
{
return false;
}
return true;
}
void FUseAndroidNDKLevelRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OutShouldRestartEditor = false;
OCULUSXR_UPDATE_SETTINGS(UAndroidSDKSettings, NDKAPILevel, FText::AsCultureInvariant(AndroidNDKAPIMinLevel).ToString());
SaveSDKSettings();
}
bool FUseArm64CPURule::IsApplied() const
{
const UAndroidRuntimeSettings* Settings = GetMutableDefault<UAndroidRuntimeSettings>();
return Settings->bBuildForArm64 && !Settings->bBuildForX8664;
}
void FUseArm64CPURule::ApplyImpl(bool& OutShouldRestartEditor)
{
OCULUSXR_UPDATE_SETTINGS(UAndroidRuntimeSettings, bBuildForArm64, true);
OCULUSXR_UPDATE_SETTINGS(UAndroidRuntimeSettings, bBuildForX8664, false);
OutShouldRestartEditor = false;
}
bool FEnablePackageForMetaQuestRule::IsApplied() const
{
const UAndroidRuntimeSettings* Settings = GetMutableDefault<UAndroidRuntimeSettings>();
return Settings->bPackageForMetaQuest && !Settings->bSupportsVulkanSM5 && !Settings->bBuildForES31 && Settings->ExtraApplicationSettings.Find("com.oculus.supportedDevices") != INDEX_NONE;
}
void FEnablePackageForMetaQuestRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OCULUSXR_UPDATE_SETTINGS(UAndroidRuntimeSettings, bPackageForMetaQuest, true);
OCULUSXR_UPDATE_SETTINGS(UAndroidRuntimeSettings, bSupportsVulkanSM5, false);
OCULUSXR_UPDATE_SETTINGS(UAndroidRuntimeSettings, bBuildForES31, false);
UAndroidRuntimeSettings* Settings = GetMutableDefault<UAndroidRuntimeSettings>();
if (Settings->ExtraApplicationSettings.Find("com.oculus.supportedDevices") == INDEX_NONE)
{
const FString SupportedDevicesValue("quest|quest2|questpro");
Settings->ExtraApplicationSettings.Append("<meta-data android:name=\"com.oculus.supportedDevices\" android:value=\"" + SupportedDevicesValue + "\" />");
Settings->UpdateSinglePropertyInConfigFile(Settings->GetClass()->FindPropertyByName(GET_MEMBER_NAME_CHECKED(UAndroidRuntimeSettings, ExtraApplicationSettings)), Settings->GetDefaultConfigFilename());
}
OutShouldRestartEditor = false;
}
bool FQuest2SupportedDeviceRule::IsApplied() const
{
const UOculusXRHMDRuntimeSettings* Settings = GetMutableDefault<UOculusXRHMDRuntimeSettings>();
return Settings->SupportedDevices.Contains(EOculusXRSupportedDevices::Quest2);
}
void FQuest2SupportedDeviceRule::ApplyImpl(bool& OutShouldRestartEditor)
{
UOculusXRHMDRuntimeSettings* Settings = GetMutableDefault<UOculusXRHMDRuntimeSettings>();
Settings->SupportedDevices.Add(EOculusXRSupportedDevices::Quest2);
// UpdateSinglePropertyInConfigFile does not support arrays
Settings->TryUpdateDefaultConfigFile();
OutShouldRestartEditor = false;
}
bool FQuestProSupportedDeviceRule::IsApplied() const
{
const UOculusXRHMDRuntimeSettings* Settings = GetMutableDefault<UOculusXRHMDRuntimeSettings>();
return Settings->SupportedDevices.Contains(EOculusXRSupportedDevices::QuestPro);
}
void FQuestProSupportedDeviceRule::ApplyImpl(bool& OutShouldRestartEditor)
{
UOculusXRHMDRuntimeSettings* Settings = GetMutableDefault<UOculusXRHMDRuntimeSettings>();
Settings->SupportedDevices.Add(EOculusXRSupportedDevices::QuestPro);
// UpdateSinglePropertyInConfigFile does not support arrays
Settings->TryUpdateDefaultConfigFile();
OutShouldRestartEditor = false;
}
bool FQuest3SupportedDeviceRule::IsApplied() const
{
const UOculusXRHMDRuntimeSettings* Settings = GetMutableDefault<UOculusXRHMDRuntimeSettings>();
return Settings->SupportedDevices.Contains(EOculusXRSupportedDevices::Quest3);
}
void FQuest3SupportedDeviceRule::ApplyImpl(bool& OutShouldRestartEditor)
{
UOculusXRHMDRuntimeSettings* Settings = GetMutableDefault<UOculusXRHMDRuntimeSettings>();
Settings->SupportedDevices.Add(EOculusXRSupportedDevices::Quest3);
// UpdateSinglePropertyInConfigFile does not support arrays
Settings->TryUpdateDefaultConfigFile();
OutShouldRestartEditor = false;
}
bool FEnableFullscreenRule::IsApplied() const
{
const UAndroidRuntimeSettings* Settings = GetMutableDefault<UAndroidRuntimeSettings>();
return Settings->bFullScreen;
}
void FEnableFullscreenRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OCULUSXR_UPDATE_SETTINGS(UAndroidRuntimeSettings, bFullScreen, true);
OutShouldRestartEditor = false;
}
bool FEnableStartInVRRule::IsApplied() const
{
const UGeneralProjectSettings* Settings = GetDefault<UGeneralProjectSettings>();
return Settings->bStartInVR != 0;
}
void FEnableStartInVRRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OCULUSXR_UPDATE_SETTINGS(UGeneralProjectSettings, bStartInVR, true);
OutShouldRestartEditor = false;
}
bool FDisableTouchInterfaceRule::IsApplied() const
{
const UInputSettings* Settings = GetDefault<UInputSettings>();
return Settings->DefaultTouchInterface.IsNull();
}
void FDisableTouchInterfaceRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OCULUSXR_UPDATE_SETTINGS(UInputSettings, DefaultTouchInterface, nullptr);
OutShouldRestartEditor = false;
}
} // namespace OculusXRCompatibilityRules
#undef LOCTEXT_NAMESPACE

View File

@@ -0,0 +1,199 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#pragma once
#include "OculusXRSetupRule.h"
// Collection of rules related to compatibility. Can be extended as needed
namespace OculusXRCompatibilityRules
{
class FUseAndroidSDKMinimumRule final : public ISetupRule
{
public:
FUseAndroidSDKMinimumRule();
virtual bool IsApplied() const override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
class FUseAndroidSDKTargetRule final : public ISetupRule
{
public:
FUseAndroidSDKTargetRule();
virtual bool IsApplied() const override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
void SaveSDKSettings();
class FUseAndroidSDKLevelRule final : public ISetupRule
{
public:
FUseAndroidSDKLevelRule();
virtual bool IsApplied() const override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
class FUseAndroidNDKLevelRule final : public ISetupRule
{
public:
FUseAndroidNDKLevelRule();
virtual bool IsApplied() const override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
class FUseArm64CPURule final : public ISetupRule
{
public:
FUseArm64CPURule()
: ISetupRule(
"Compatibility_UseArm64CPU",
NSLOCTEXT("OculusXRCompatibilityRules", "UseArm64CPU_DisplayName", "Use Arm64 CPU Architecture"),
NSLOCTEXT("OculusXRCompatibilityRules", "UseArm64CPU_Description", "Meta Quest store requires 64-bit applications"),
ESetupRuleCategory::Compatibility,
ESetupRuleSeverity::Critical,
MetaQuest_All) {}
virtual bool IsApplied() const override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
class FEnablePackageForMetaQuestRule final : public ISetupRule
{
public:
FEnablePackageForMetaQuestRule()
: ISetupRule(
"Compatibility_UsePackageForMetaQuest",
NSLOCTEXT("OculusXRCompatibilityRules", "UsePackageForQuest_DisplayName", "Enable Package for Meta Quest devices"),
NSLOCTEXT("OculusXRCompatibilityRules", "UsePackageForQuest_Description", "\"Package for Meta Quest devices\" must be enabled."),
ESetupRuleCategory::Compatibility,
ESetupRuleSeverity::Critical,
MetaQuest_All) {}
virtual bool IsApplied() const override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
class FQuest2SupportedDeviceRule final : public ISetupRule
{
public:
FQuest2SupportedDeviceRule()
: ISetupRule(
"Compatibility_UsePackageForQuest2",
NSLOCTEXT("OculusXRCompatibilityRules", "UsePackageForQuest_DisplayName", "Use Package for Quest2"),
NSLOCTEXT("OculusXRCompatibilityRules", "UsePackageForQuest_Description", "Meta Quest2 must be added to \"Supported Meta Quest Devices\"."),
ESetupRuleCategory::Compatibility,
ESetupRuleSeverity::Critical,
ESetupRulePlatform::MetaQuest_2) {}
virtual bool IsApplied() const override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
class FQuestProSupportedDeviceRule final : public ISetupRule
{
public:
FQuestProSupportedDeviceRule()
: ISetupRule(
"Compatibility_UsePackageForQuestPro",
NSLOCTEXT("OculusXRCompatibilityRules", "UsePackageForQuest_DisplayName", "Use Package for QuestPro"),
NSLOCTEXT("OculusXRCompatibilityRules", "UsePackageForQuest_Description", "Meta QuestPro must be added to \"Supported Meta Quest Devices\"."),
ESetupRuleCategory::Compatibility,
ESetupRuleSeverity::Critical,
ESetupRulePlatform::MetaQuest_Pro) {}
virtual bool IsApplied() const override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
class FQuest3SupportedDeviceRule final : public ISetupRule
{
public:
FQuest3SupportedDeviceRule()
: ISetupRule(
"Compatibility_UsePackageForQuest3",
NSLOCTEXT("OculusXRCompatibilityRules", "UsePackageForQuest_DisplayName", "Use Package for Quest3"),
NSLOCTEXT("OculusXRCompatibilityRules", "UsePackageForQuest_Description", "Meta Quest3 must be added to \"Supported Meta Quest Devices\"."),
ESetupRuleCategory::Compatibility,
ESetupRuleSeverity::Critical,
ESetupRulePlatform::MetaQuest_3) {}
virtual bool IsApplied() const override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
class FEnableFullscreenRule final : public ISetupRule
{
public:
FEnableFullscreenRule()
: ISetupRule(
"Compatibility_EnableFullscreen",
NSLOCTEXT("OculusXRCompatibilityRules", "EnableFullscreen_DisplayName", "Enable Fullscreen"),
NSLOCTEXT("OculusXRCompatibilityRules", "EnableFullscreen_Description", "Android fullscreen must be enabled for VR"),
ESetupRuleCategory::Compatibility,
ESetupRuleSeverity::Warning,
MetaQuest_All) {}
virtual bool IsApplied() const override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
class FEnableStartInVRRule final : public ISetupRule
{
public:
FEnableStartInVRRule()
: ISetupRule(
"Compatibility_EnableStartInVR",
NSLOCTEXT("OculusXRCompatibilityRules", "EnableStartInVR_DisplayName", "Enable Start in VR"),
NSLOCTEXT("OculusXRCompatibilityRules", "EnableStartInVR_Description", "Enable the \"Start in VR\" setting to ensure your app starts in VR. (You can also ignore this and pass -vr at the command line"),
ESetupRuleCategory::Compatibility,
ESetupRuleSeverity::Warning) {}
virtual bool IsApplied() const override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
class FDisableTouchInterfaceRule final : public ISetupRule
{
public:
FDisableTouchInterfaceRule()
: ISetupRule(
"Compatibility_DisableTouchInterface",
NSLOCTEXT("OculusXRCompatibilityRules", "DisableTouchInterface_DisplayName", "Disable Touch Interface"),
NSLOCTEXT("OculusXRCompatibilityRules", "DisableTouchInterface_Description", "Touch interface will interfere with correct VR input behavior"),
ESetupRuleCategory::Compatibility,
ESetupRuleSeverity::Critical) {}
virtual bool IsApplied() const override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
inline TArray<SetupRulePtr> CompatibilityRules_Table{
MakeShared<FUseAndroidSDKMinimumRule>(),
MakeShared<FUseAndroidSDKTargetRule>(),
MakeShared<FUseAndroidSDKLevelRule>(),
MakeShared<FUseAndroidNDKLevelRule>(),
MakeShared<FUseArm64CPURule>(),
MakeShared<FEnablePackageForMetaQuestRule>(),
MakeShared<FQuest2SupportedDeviceRule>(),
MakeShared<FQuestProSupportedDeviceRule>(),
MakeShared<FQuest3SupportedDeviceRule>(),
MakeShared<FEnableFullscreenRule>(),
MakeShared<FEnableStartInVRRule>(),
MakeShared<FDisableTouchInterfaceRule>()
};
} // namespace OculusXRCompatibilityRules

View File

@@ -0,0 +1,69 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#include "OculusXRMovementRules.h"
#include "CoreMinimal.h"
#include "OculusXRHMDRuntimeSettings.h"
#include "OculusXRPSTUtils.h"
#include "OculusXRBodyTrackingComponent.h"
#include "OculusXREyeTrackingComponent.h"
#include "OculusXRFaceTrackingComponent.h"
#include "OculusXRProjectSetupToolModule.h"
#include "OculusXRRuleProcessorSubsystem.h"
namespace OculusXRMovementRules
{
bool FEnableBodyTrackingRule::IsApplied() const
{
const UOculusXRHMDRuntimeSettings* Settings = GetMutableDefault<UOculusXRHMDRuntimeSettings>();
return Settings->bBodyTrackingEnabled;
}
void FEnableBodyTrackingRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OCULUSXR_UPDATE_SETTINGS(UOculusXRHMDRuntimeSettings, bBodyTrackingEnabled, true);
OutShouldRestartEditor = false;
}
bool FEnableBodyTrackingRule::IsValid()
{
return OculusXRPSTUtils::IsComponentOfTypeInWorld<UOculusXRBodyTrackingComponent>();
}
bool FEnableFaceTrackingRule::IsApplied() const
{
const UOculusXRHMDRuntimeSettings* Settings = GetMutableDefault<UOculusXRHMDRuntimeSettings>();
return Settings->bFaceTrackingEnabled;
}
void FEnableFaceTrackingRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OCULUSXR_UPDATE_SETTINGS(UOculusXRHMDRuntimeSettings, bFaceTrackingEnabled, true);
OutShouldRestartEditor = false;
}
bool FEnableFaceTrackingRule::IsValid()
{
return OculusXRPSTUtils::IsComponentOfTypeInWorld<UOculusXRFaceTrackingComponent>();
}
bool FEnableEyeTrackingRule::IsApplied() const
{
const UOculusXRHMDRuntimeSettings* Settings = GetMutableDefault<UOculusXRHMDRuntimeSettings>();
return Settings->bEyeTrackingEnabled;
}
void FEnableEyeTrackingRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OCULUSXR_UPDATE_SETTINGS(UOculusXRHMDRuntimeSettings, bEyeTrackingEnabled, true);
OutShouldRestartEditor = false;
}
bool FEnableEyeTrackingRule::IsValid()
{
return OculusXRPSTUtils::IsComponentOfTypeInWorld<UOculusXREyeTrackingComponent>();
}
} // namespace OculusXRMovementRules
#undef LOCTEXT_NAMESPACE

View File

@@ -0,0 +1,67 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#pragma once
#include "OculusXRSetupRule.h"
/*
* Collection of rules related to movement SDK. Can be extended as needed
*/
namespace OculusXRMovementRules
{
class FEnableBodyTrackingRule final : public ISetupRule
{
public:
FEnableBodyTrackingRule()
: ISetupRule(
"Feature_EnableBodyTracking",
NSLOCTEXT("OculusXRMovementRules", "EnableBodyTracking_DisplayName", "Enable Body Tracking"),
NSLOCTEXT("OculusXRMovementRules", "EnableBodyTracking_Description", "Body tracking must be enabled when using body tracking features"),
ESetupRuleCategory::Features,
ESetupRuleSeverity::Critical) {}
virtual bool IsApplied() const override;
virtual bool IsValid() override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
class FEnableFaceTrackingRule final : public ISetupRule
{
public:
FEnableFaceTrackingRule()
: ISetupRule(
"Feature_EnableFaceTracking",
NSLOCTEXT("OculusXRMovementRules", "EnableFaceTracking_DisplayName", "Enable Face Tracking"),
NSLOCTEXT("OculusXRMovementRules", "EnableFaceTracking_Description", "Face tracking must be enabled when using face tracking features"),
ESetupRuleCategory::Features,
ESetupRuleSeverity::Critical) {}
virtual bool IsApplied() const override;
virtual bool IsValid() override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
class FEnableEyeTrackingRule final : public ISetupRule
{
public:
FEnableEyeTrackingRule()
: ISetupRule(
"Feature_EnableEyeTracking",
NSLOCTEXT("OculusXRMovementRules", "EnableEyeTracking_DisplayName", "Enable Eye Tracking"),
NSLOCTEXT("OculusXRMovementRules", "EnableEyeTracking_Description", "Eye tracking must be enabled when using eye tracking features"),
ESetupRuleCategory::Features,
ESetupRuleSeverity::Critical) {}
virtual bool IsApplied() const override;
virtual bool IsValid() override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
inline TArray<SetupRulePtr> MovementRules_Table{
MakeShared<FEnableBodyTrackingRule>(),
MakeShared<FEnableFaceTrackingRule>(),
MakeShared<FEnableEyeTrackingRule>()
};
} // namespace OculusXRMovementRules

View File

@@ -0,0 +1,72 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#include "OculusXRPassthroughRules.h"
#include "CoreMinimal.h"
#include "OculusXRHMDRuntimeSettings.h"
#include "OculusXRPSTUtils.h"
#include "OculusXRPassthroughLayerComponent.h"
#include "BPNode_InitializePersistentPassthrough.h"
#include "OculusXRProjectSetupToolModule.h"
#include "OculusXRRuleProcessorSubsystem.h"
#include "Engine/RendererSettings.h"
#include "EdGraph/EdGraphPin.h"
#include "K2Node.h"
namespace OculusXRPassthroughRules
{
bool FEnablePassthroughRule::IsApplied() const
{
const UOculusXRHMDRuntimeSettings* Settings = GetMutableDefault<UOculusXRHMDRuntimeSettings>();
return Settings->bInsightPassthroughEnabled;
}
void FEnablePassthroughRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OCULUSXR_UPDATE_SETTINGS(UOculusXRHMDRuntimeSettings, bInsightPassthroughEnabled, true);
OutShouldRestartEditor = false;
}
bool FEnablePassthroughRule::IsValid()
{
if (OculusXRPSTUtils::IsComponentOfTypeInWorld<UOculusXRPassthroughLayerComponent>()
|| OculusXRPSTUtils::IsComponentOfTypeInWorld<UBPNode_InitializePersistentPassthrough>(
[](UBPNode_InitializePersistentPassthrough* n) {
return n && n->GetExecPin() && n->GetExecPin()->LinkedTo.Num() > 0;
}))
{
return true;
}
return false;
}
bool FAllowAlphaToneMapperPassthroughRule::IsApplied() const
{
URendererSettings* Settings = GetMutableDefault<URendererSettings>();
#if UE_VERSION_OLDER_THAN(5, 5, 0)
return Settings->bEnableAlphaChannelInPostProcessing == EAlphaChannelMode::AllowThroughTonemapper;
#else
return Settings->bEnableAlphaChannelInPostProcessing;
#endif
}
bool FAllowAlphaToneMapperPassthroughRule::IsValid()
{
const UOculusXRHMDRuntimeSettings* Settings = GetMutableDefault<UOculusXRHMDRuntimeSettings>();
return Settings->bInsightPassthroughEnabled || Settings->SystemSplashBackground == ESystemSplashBackgroundType::Contextual;
}
void FAllowAlphaToneMapperPassthroughRule::ApplyImpl(bool& OutShouldRestartEditor)
{
#if UE_VERSION_OLDER_THAN(5, 5, 0)
OCULUSXR_UPDATE_SETTINGS(URendererSettings, bEnableAlphaChannelInPostProcessing, EAlphaChannelMode::AllowThroughTonemapper);
#else
OCULUSXR_UPDATE_SETTINGS(URendererSettings, bEnableAlphaChannelInPostProcessing, true);
#endif
OutShouldRestartEditor = true;
}
} // namespace OculusXRPassthroughRules
#undef LOCTEXT_NAMESPACE

View File

@@ -0,0 +1,49 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#pragma once
#include "OculusXRSetupRule.h"
/*
* Collection of rules related to passthrough. Can be extended as needed
*/
namespace OculusXRPassthroughRules
{
class FEnablePassthroughRule final : public ISetupRule
{
public:
FEnablePassthroughRule()
: ISetupRule(
"Feature_EnablePassthrough",
NSLOCTEXT("OculusXRPassthroughRules", "EnablePassthrough_DisplayName", "Enable Passthrough"),
NSLOCTEXT("OculusXRPassthroughRules", "EnablePassthrough_Description", "Passthrough must be enabled when using passthrough features"),
ESetupRuleCategory::Features,
ESetupRuleSeverity::Critical) {}
virtual bool IsApplied() const override;
virtual bool IsValid() override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
class FAllowAlphaToneMapperPassthroughRule final : public ISetupRule
{
public:
FAllowAlphaToneMapperPassthroughRule()
: ISetupRule(
"Feature_AllowAlphaToneMapperPassthrough",
NSLOCTEXT("OculusXRPassthroughRules", "AllowAlphaToneMapperPassthrough_DisplayName", "Enable passing alpha channel through tonemapper"),
NSLOCTEXT("OculusXRPassthroughRules", "AllowAlphaToneMapperPassthrough_Description", "For passthrough to work over Link alpha channel must be passed through tonemapper."),
ESetupRuleCategory::Features,
ESetupRuleSeverity::Warning) {}
virtual bool IsApplied() const override;
virtual bool IsValid() override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
inline TArray<SetupRulePtr> PassthroughRules_Table{
MakeShared<FEnablePassthroughRule>(),
MakeShared<FAllowAlphaToneMapperPassthroughRule>()
};
} // namespace OculusXRPassthroughRules

View File

@@ -0,0 +1,81 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#include "OculusXRPluginRules.h"
#include "CoreMinimal.h"
#include "OculusXRHMDRuntimeSettings.h"
#include "OculusXRPSTUtils.h"
#include "Editor/GameProjectGeneration/Public/GameProjectGenerationModule.h"
#include "Interfaces/IPluginManager.h"
#include "Interfaces/IProjectManager.h"
#include "Misc/MessageDialog.h"
namespace OculusXRPluginRules
{
namespace
{
bool IsPluginEnabled(const FString& PluginName)
{
const auto Plugin = IPluginManager::Get().FindPlugin(PluginName);
if (!Plugin)
{
return false;
}
return Plugin->IsEnabled();
}
bool DisablePlugin(const FString& PluginName)
{
FText FailMessage;
bool bSuccess = IProjectManager::Get().SetPluginEnabled(
PluginName, false, FailMessage);
const bool bIsProjectDirty = IProjectManager::Get().IsCurrentProjectDirty();
if (bSuccess && bIsProjectDirty)
{
FGameProjectGenerationModule::Get().TryMakeProjectFileWriteable(FPaths::GetProjectFilePath());
bSuccess = IProjectManager::Get().SaveCurrentProjectToDisk(FailMessage);
}
if (!bSuccess)
{
FMessageDialog::Open(EAppMsgType::Ok, FailMessage);
}
return bSuccess && !bIsProjectDirty;
}
} // namespace
bool FUseRecommendedXRAPIRule::IsApplied() const
{
const UOculusXRHMDRuntimeSettings* Settings = GetMutableDefault<UOculusXRHMDRuntimeSettings>();
return Settings->XrApi == EOculusXRXrApi::OVRPluginOpenXR;
}
void FUseRecommendedXRAPIRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OCULUSXR_UPDATE_SETTINGS(UOculusXRHMDRuntimeSettings, XrApi, EOculusXRXrApi::OVRPluginOpenXR);
OutShouldRestartEditor = false;
}
bool FDisableOculusVRRule::IsApplied() const
{
return bApplied || !IsPluginEnabled(PluginName);
}
void FDisableOculusVRRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OutShouldRestartEditor = DisablePlugin(PluginName);
bApplied = OutShouldRestartEditor;
}
bool FDisableSteamVRRule::IsApplied() const
{
return bApplied || !IsPluginEnabled(PluginName);
}
void FDisableSteamVRRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OutShouldRestartEditor = DisablePlugin(PluginName);
bApplied = OutShouldRestartEditor;
}
} // namespace OculusXRPluginRules
#undef LOCTEXT_NAMESPACE

View File

@@ -0,0 +1,71 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#pragma once
#include "OculusXRSetupRule.h"
// Collection of rules related to plugins. Can be extended as needed
namespace OculusXRPluginRules
{
class FUseRecommendedXRAPIRule final : public ISetupRule
{
public:
FUseRecommendedXRAPIRule()
: ISetupRule("Plugin_UseRecommendedXRAPI",
NSLOCTEXT("OculusXRPluginRules", "UseRecommendedXRAPI_DisplayName", "Use Recommended XR API"),
NSLOCTEXT("OculusXRPluginRules", "UseRecommendedXRAPI_Description", "It is currently recommended to use OVRPlugin + OpenXR for the XR API"),
ESetupRuleCategory::Plugins,
ESetupRuleSeverity::Warning) {}
virtual bool IsApplied() const override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
class FDisableOculusVRRule final : public ISetupRule
{
public:
FDisableOculusVRRule()
: ISetupRule("Plugin_DisableOculusVR",
NSLOCTEXT("OculusXRPluginRules", "DisableOculusVR_DisplayName", "Disable OculusVR Plugin"),
NSLOCTEXT("OculusXRPluginRules", "DisableOculusVR_Description", "The OculusVR plugin is deprecated and should be disabled"),
ESetupRuleCategory::Plugins,
ESetupRuleSeverity::Warning) {}
virtual bool IsApplied() const override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
private:
FString PluginName = "OculusVR";
bool bApplied = false;
};
class FDisableSteamVRRule final : public ISetupRule
{
public:
FDisableSteamVRRule()
: ISetupRule("Plugin_DisableSteamVR",
NSLOCTEXT("OculusXRPluginRules", "DisableSteamVR_DisplayName", "Disable SteamVR Plugin"),
NSLOCTEXT("OculusXRPluginRules", "DisableSteamVR_Description", "The SteamVR plugin is deprecated and should be disabled"),
ESetupRuleCategory::Plugins,
ESetupRuleSeverity::Warning) {}
virtual bool IsApplied() const override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
private:
FString PluginName = "SteamVR";
bool bApplied = false;
};
// All defined plugin rules. Add new rules to this table for them to be auto-registered
inline TArray<SetupRulePtr> PluginRules_Table{
MakeShared<FUseRecommendedXRAPIRule>(),
MakeShared<FDisableOculusVRRule>(),
MakeShared<FDisableSteamVRRule>()
};
} // namespace OculusXRPluginRules

View File

@@ -0,0 +1,406 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#include "OculusXRRenderingRules.h"
#include "CoreMinimal.h"
#include "AndroidRuntimeSettings.h"
#include "DataDrivenShaderPlatformInfo.h"
#include "EngineUtils.h"
#include "OculusXRHMDRuntimeSettings.h"
#include "OculusXRPSTUtils.h"
#include "OculusXRRuleProcessorSubsystem.h"
#include "Engine/PostProcessVolume.h"
#include "Engine/RendererSettings.h"
#include "Misc/EngineVersionComparison.h"
#include "Editor.h"
#include "Kismet/KismetSystemLibrary.h"
namespace OculusXRRenderingRules
{
namespace
{
FPreviewPlatformInfo GetAndroidPreviewPlatformInfo()
{
const FName AndroidPlatformName(TEXT("AndroidVulkan_Preview"));
const EShaderPlatform ShaderPlatform = FDataDrivenShaderPlatformInfo::GetShaderPlatformFromName(AndroidPlatformName);
const ERHIFeatureLevel::Type FeatureLevel = GetMaxSupportedFeatureLevel(ShaderPlatform);
const auto& AllPreviewPlatforms = FDataDrivenPlatformInfoRegistry::GetAllPreviewPlatformMenuItems();
for (const auto& Platform : AllPreviewPlatforms)
{
if (Platform.PreviewShaderPlatformName == AndroidPlatformName)
{
return FPreviewPlatformInfo(FeatureLevel, ShaderPlatform, Platform.PlatformName, Platform.ShaderFormat, Platform.DeviceProfileName,
true, Platform.PreviewShaderPlatformName);
}
}
return {};
}
} // namespace
bool FUseVulkanRule::IsApplied() const
{
const UAndroidRuntimeSettings* Settings = GetMutableDefault<UAndroidRuntimeSettings>();
return Settings->bSupportsVulkan && !Settings->bBuildForES31;
}
void FUseVulkanRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OCULUSXR_UPDATE_SETTINGS(UAndroidRuntimeSettings, bSupportsVulkan, true);
OCULUSXR_UPDATE_SETTINGS(UAndroidRuntimeSettings, bBuildForES31, false);
OutShouldRestartEditor = false;
}
bool FUseHalfPrecisionFloatRule::IsApplied() const
{
const URendererSettings* Settings = GetMutableDefault<URendererSettings>();
return Settings->MobileFloatPrecisionMode == EMobileFloatPrecisionMode::Half;
}
void FUseHalfPrecisionFloatRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OCULUSXR_UPDATE_SETTINGS(URendererSettings, MobileFloatPrecisionMode, EMobileFloatPrecisionMode::Half);
OutShouldRestartEditor = true;
}
bool FEnableInstancedStereoRule::IsApplied() const
{
const URendererSettings* Settings = GetMutableDefault<URendererSettings>();
return Settings->bMultiView != 0;
}
void FEnableInstancedStereoRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OCULUSXR_UPDATE_SETTINGS(URendererSettings, bMultiView, 1);
OutShouldRestartEditor = true;
}
bool FEnableForwardShadingRule::IsApplied() const
{
const URendererSettings* Settings = GetMutableDefault<URendererSettings>();
return Settings->MobileShadingPath == EMobileShadingPath::Forward;
}
void FEnableForwardShadingRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OCULUSXR_UPDATE_SETTINGS(URendererSettings, MobileShadingPath, EMobileShadingPath::Forward);
OutShouldRestartEditor = true;
}
bool FEnablePCForwardShadingRule::IsApplied() const
{
const URendererSettings* Settings = GetMutableDefault<URendererSettings>();
return Settings->bForwardShading;
}
void FEnablePCForwardShadingRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OCULUSXR_UPDATE_SETTINGS(URendererSettings, bForwardShading, true);
OutShouldRestartEditor = true;
}
bool FEnableMSAARule::IsApplied() const
{
const URendererSettings* Settings = GetMutableDefault<URendererSettings>();
return Settings->MobileAntiAliasing == EMobileAntiAliasingMethod::MSAA
&& Settings->MSAASampleCount == ECompositingSampleCount::Four;
}
void FEnableMSAARule::ApplyImpl(bool& OutShouldRestartEditor)
{
OCULUSXR_UPDATE_SETTINGS(URendererSettings, MobileAntiAliasing, EMobileAntiAliasingMethod::MSAA);
OCULUSXR_UPDATE_SETTINGS(URendererSettings, MSAASampleCount, ECompositingSampleCount::Four);
OutShouldRestartEditor = false;
}
bool FEnableOcclusionCullingRule::IsApplied() const
{
const URendererSettings* Settings = GetMutableDefault<URendererSettings>();
return Settings->bOcclusionCulling;
}
void FEnableOcclusionCullingRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OCULUSXR_UPDATE_SETTINGS(URendererSettings, bOcclusionCulling, 1);
OutShouldRestartEditor = false;
}
bool FEnableDynamicFoveationRule::IsApplied() const
{
const UOculusXRHMDRuntimeSettings* Settings = GetMutableDefault<UOculusXRHMDRuntimeSettings>();
return Settings->bDynamicFoveatedRendering;
}
void FEnableDynamicFoveationRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OCULUSXR_UPDATE_SETTINGS(UOculusXRHMDRuntimeSettings, bDynamicFoveatedRendering, true);
OutShouldRestartEditor = false;
}
#ifdef WITH_OCULUS_BRANCH
bool FEnableDynamicResolutionRule::IsApplied() const
{
const UOculusXRHMDRuntimeSettings* Settings = GetMutableDefault<UOculusXRHMDRuntimeSettings>();
return Settings->bDynamicResolution;
}
void FEnableDynamicResolutionRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OCULUSXR_UPDATE_SETTINGS(UOculusXRHMDRuntimeSettings, bDynamicResolution, true);
OutShouldRestartEditor = false;
}
bool FEnableMobileUniformLocalLightsRule::IsApplied() const
{
return GetMutableDefault<URendererSettings>()->bMobileUniformLocalLights;
}
void FEnableMobileUniformLocalLightsRule::ApplyImpl(bool& OutShouldRestartEditor)
{
if (GetMutableDefault<URendererSettings>()->bMobileSupportGPUScene)
{
UE_LOG(LogTemp, Error, TEXT("Failed to enable MobileUniformLocalLights because MobileUniformLocalLights is incompatible with GPUScene."));
return;
}
OCULUSXR_UPDATE_SETTINGS(URendererSettings, bMobileUniformLocalLights, true);
OutShouldRestartEditor = true;
}
bool FEnableEmulatedUniformBuffersRule::IsApplied() const
{
const URendererSettings* Settings = GetMutableDefault<URendererSettings>();
return Settings->bVulkanUseEmulatedUBs;
}
void FEnableEmulatedUniformBuffersRule::ApplyImpl(bool& OutShouldRestartEditor)
{
if (GetMutableDefault<URendererSettings>()->bMobileSupportGPUScene)
{
UE_LOG(LogTemp, Error, TEXT("Failed to enable EmulatedUniformBuffers because EmulatedUniformBuffers is incompatible with GPUScene."));
return;
}
OCULUSXR_UPDATE_SETTINGS(URendererSettings, bVulkanUseEmulatedUBs, true);
OutShouldRestartEditor = true;
}
#endif
bool FDisableLensFlareRule::IsApplied() const
{
const URendererSettings* Settings = GetMutableDefault<URendererSettings>();
if (!Settings->bMobilePostProcessing)
{
return true;
}
for (TActorIterator<APostProcessVolume> ActorItr(GEditor->GetEditorWorldContext().World()); ActorItr; ++ActorItr)
{
if (ActorItr->Settings.bOverride_LensFlareIntensity && ActorItr->Settings.LensFlareIntensity > 0.0f)
{
return false;
}
}
return Settings->bDefaultFeatureLensFlare == 0;
}
void FDisableLensFlareRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OCULUSXR_UPDATE_SETTINGS(URendererSettings, bDefaultFeatureLensFlare, false);
UKismetSystemLibrary::BeginTransaction("ProjectSetupTool", NSLOCTEXT("OculusXRRenderingRules", "DisableLensFlare", "Disable Lens Flare"), nullptr);
for (TActorIterator<APostProcessVolume> ActorItr(GEditor->GetEditorWorldContext().World()); ActorItr; ++ActorItr)
{
if (ActorItr->Settings.bOverride_LensFlareIntensity)
{
UKismetSystemLibrary::TransactObject(*ActorItr);
ActorItr->Settings.bOverride_LensFlareIntensity = false;
}
}
UKismetSystemLibrary::EndTransaction();
OutShouldRestartEditor = false;
}
bool FDisablePostProcessingRule::IsApplied() const
{
const URendererSettings* Settings = GetMutableDefault<URendererSettings>();
return Settings->bMobilePostProcessing == 0;
}
void FDisablePostProcessingRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OCULUSXR_UPDATE_SETTINGS(URendererSettings, bMobilePostProcessing, 0);
OutShouldRestartEditor = true;
}
bool FDisableAmbientOcclusionRule::IsApplied() const
{
const URendererSettings* Settings = GetMutableDefault<URendererSettings>();
return Settings->bMobileAmbientOcclusion == 0;
}
void FDisableAmbientOcclusionRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OCULUSXR_UPDATE_SETTINGS(URendererSettings, bMobileAmbientOcclusion, 0);
OutShouldRestartEditor = true;
}
bool FEnableMultiViewRule::IsApplied() const
{
return GetMutableDefault<URendererSettings>()->bMobileMultiView != 0;
}
void FEnableMultiViewRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OCULUSXR_UPDATE_SETTINGS(URendererSettings, bMobileMultiView, 1);
OutShouldRestartEditor = true;
}
bool FEnableStaticLightingRule::IsApplied() const
{
return GetMutableDefault<URendererSettings>()->bAllowStaticLighting;
}
void FEnableStaticLightingRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OCULUSXR_UPDATE_SETTINGS(URendererSettings, bAllowStaticLighting, true);
OutShouldRestartEditor = true;
}
bool FDisableMobileShaderStaticAndCSMShadowReceiversRule::IsApplied() const
{
return !GetMutableDefault<URendererSettings>()->bMobileEnableStaticAndCSMShadowReceivers;
}
void FDisableMobileShaderStaticAndCSMShadowReceiversRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OCULUSXR_UPDATE_SETTINGS(URendererSettings, bMobileEnableStaticAndCSMShadowReceivers, false);
OutShouldRestartEditor = false;
}
bool FDisableMobileShaderStaticAndCSMShadowReceiversRule::IsValid()
{
const UOculusXRRuleProcessorSubsystem* RuleProcessorSubsystem = GEngine->GetEngineSubsystem<UOculusXRRuleProcessorSubsystem>();
return !RuleProcessorSubsystem->DynamicLightsExistInProject();
}
bool FDisableMobileShaderAllowDistanceFieldShadowsRule::IsApplied() const
{
return !GetMutableDefault<URendererSettings>()->bMobileAllowDistanceFieldShadows;
}
void FDisableMobileShaderAllowDistanceFieldShadowsRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OCULUSXR_UPDATE_SETTINGS(URendererSettings, bMobileAllowDistanceFieldShadows, false);
OutShouldRestartEditor = true;
}
bool FDisableMobileShaderAllowDistanceFieldShadowsRule::IsValid()
{
const UOculusXRRuleProcessorSubsystem* RuleProcessorSubsystem = GEngine->GetEngineSubsystem<UOculusXRRuleProcessorSubsystem>();
return !RuleProcessorSubsystem->DynamicLightsExistInProject();
}
#if UE_VERSION_OLDER_THAN(5, 5, 0)
bool FDisableMobileShaderAllowMovableDirectionalLightsRule::IsApplied() const
{
return !GetMutableDefault<URendererSettings>()->bMobileAllowMovableDirectionalLights;
}
void FDisableMobileShaderAllowMovableDirectionalLightsRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OCULUSXR_UPDATE_SETTINGS(URendererSettings, bMobileAllowMovableDirectionalLights, false);
OutShouldRestartEditor = true;
}
bool FDisableMobileShaderAllowMovableDirectionalLightsRule::IsValid()
{
const UOculusXRRuleProcessorSubsystem* RuleProcessorSubsystem = GEngine->GetEngineSubsystem<UOculusXRRuleProcessorSubsystem>();
return !RuleProcessorSubsystem->DynamicLightsExistInProject();
}
#endif
#ifdef WITH_OCULUS_BRANCH
bool FDisableMobileGPUSceneRule::IsApplied() const
{
const URendererSettings* RenderSettings = GetMutableDefault<URendererSettings>();
// check if GPUScene conflicts with any existing features: EUB or ULL
return !((RenderSettings->bMobileSupportGPUScene && RenderSettings->bVulkanUseEmulatedUBs) || (RenderSettings->bMobileSupportGPUScene && RenderSettings->bMobileUniformLocalLights));
}
void FDisableMobileGPUSceneRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OCULUSXR_UPDATE_SETTINGS(URendererSettings, bMobileSupportGPUScene, false);
OutShouldRestartEditor = true;
}
bool FDisableMobileGPUSceneRule::IsValid()
{
return true;
}
#endif
FUseAndroidVulkanPreviewPlatform::FUseAndroidVulkanPreviewPlatform()
: ISetupRule("Rendering_UseAndroidVulkanPreviewPlatform",
NSLOCTEXT("OculusXRRenderingRules", "UseAndroidVulkanPreviewPlatform_DisplayName", "Use Android Vulkan Preview Platform"),
NSLOCTEXT("OculusXRRenderingRules", "UseAndroidVulkanPreviewPlatform_Description", "Android Vulkan Mobile Preview Platform is necessery for correct behaviour of passthrough over Link."),
ESetupRuleCategory::Rendering,
ESetupRuleSeverity::Warning,
ESetupRulePlatform::MetaLink)
{
AndroidVulkanPreview = GetAndroidPreviewPlatformInfo();
}
bool FUseAndroidVulkanPreviewPlatform::IsApplied() const
{
FName CurrentPlatformName;
if (!GEditor->GetPreviewPlatformName(CurrentPlatformName))
{
return false;
}
return CurrentPlatformName == AndroidVulkanPreview.PreviewPlatformName;
}
bool FUseAndroidVulkanPreviewPlatform::IsValid()
{
const UOculusXRHMDRuntimeSettings* Settings = GetMutableDefault<UOculusXRHMDRuntimeSettings>();
return Settings->bInsightPassthroughEnabled;
}
void FUseAndroidVulkanPreviewPlatform::ApplyImpl(bool& OutShouldRestartEditor)
{
GEditor->SetPreviewPlatform(AndroidVulkanPreview, true);
OutShouldRestartEditor = false;
}
FDisableMobileMoveableSpotlightShadowsRule::FDisableMobileMoveableSpotlightShadowsRule()
: ISetupRule("Rendering_MobileMoveableSpotlightShadows",
NSLOCTEXT("OculusXRRenderingRules", "MobileMoveableSpotlightShadows_DisplayName", "Mobile Moveable Spotlight Shadows"),
NSLOCTEXT("OculusXRRenderingRules", "MobileMoveableSpotlightShadows_Description", "Mobile Movable Spotlights Shadows are not supported with Mobile Multi-View enabled."),
ESetupRuleCategory::Rendering,
ESetupRuleSeverity::Critical,
MetaQuest_All)
{
}
bool FDisableMobileMoveableSpotlightShadowsRule::IsApplied() const
{
const URendererSettings* RenderSettings = GetMutableDefault<URendererSettings>();
return RenderSettings->bMobileMultiView ? !RenderSettings->bMobileAllowMovableSpotlightShadows : true;
}
void FDisableMobileMoveableSpotlightShadowsRule::ApplyImpl(bool& OutShouldRestartEditor)
{
OCULUSXR_UPDATE_SETTINGS(URendererSettings, bMobileAllowMovableSpotlightShadows, false);
OutShouldRestartEditor = true;
}
} // namespace OculusXRRenderingRules

View File

@@ -0,0 +1,403 @@
// Copyright (c) Meta Platforms, Inc. and affiliates.
#pragma once
#include "OculusXRSetupRule.h"
#include "Editor/EditorEngine.h"
#include "Misc/EngineVersionComparison.h"
// Collection of rules related to rendering. Can be extended as needed
namespace OculusXRRenderingRules
{
class FUseVulkanRule final : public ISetupRule
{
public:
FUseVulkanRule()
: ISetupRule("Rendering_UseVulkan",
NSLOCTEXT("OculusXRRenderingRules", "UseVulkan_DisplayName", "Use Vulkan Rendering Backend"),
NSLOCTEXT("OculusXRRenderingRules", "UseVulkan_Description", "Oculus recommends using Vulkan as the rendering backend for all mobile apps."),
ESetupRuleCategory::Rendering,
ESetupRuleSeverity::Performance,
MetaQuest_All) {}
virtual bool IsApplied() const override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
class FUseHalfPrecisionFloatRule final : public ISetupRule
{
public:
FUseHalfPrecisionFloatRule()
: ISetupRule("Rendering_UseHalfPrecisionFloat",
NSLOCTEXT("OculusXRRenderingRules", "UseHalfPrecisionFloat_DisplayName", "Use Half Precision Float"),
NSLOCTEXT("OculusXRRenderingRules", "UseHalfPrecisionFloat_Description", "Half precision float provides increased shader performance."),
ESetupRuleCategory::Rendering,
ESetupRuleSeverity::Performance,
MetaQuest_All) {}
virtual bool IsApplied() const override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
class FEnableInstancedStereoRule final : public ISetupRule
{
public:
FEnableInstancedStereoRule()
: ISetupRule("Rendering_EnableInstancedStereo",
NSLOCTEXT("OculusXRRenderingRules", "EnableInstancedStereo_DisplayName", "Enable Instanced Stereo"),
NSLOCTEXT("OculusXRRenderingRules", "EnableInstancedStereo_Description", "Instanced stereo substantially reduces draw calls, and improves rendering performance."),
ESetupRuleCategory::Rendering,
ESetupRuleSeverity::Performance,
ESetupRulePlatform::MetaLink) {}
virtual bool IsApplied() const override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
class FEnableForwardShadingRule final : public ISetupRule
{
public:
FEnableForwardShadingRule()
: ISetupRule("Rendering_EnableForwardShading",
NSLOCTEXT("OculusXRRenderingRules", "EnableForwardShading_DisplayName", "Enable Forward Shading"),
NSLOCTEXT("OculusXRRenderingRules", "EnableForwardShading_Description", "Forward shading is often better suited for VR rendering."),
ESetupRuleCategory::Rendering,
ESetupRuleSeverity::Performance,
ESetupRulePlatform::MetaQuest_2) {}
virtual bool IsApplied() const override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
class FEnablePCForwardShadingRule final : public ISetupRule
{
public:
FEnablePCForwardShadingRule()
: ISetupRule("Rendering_EnablePCForwardShading",
NSLOCTEXT("OculusXRRenderingRules", "EnablePCForwardShading_DisplayName", "Enable PC Forward Shading"),
NSLOCTEXT("OculusXRRenderingRules", "EnablePCForwardShading_Description", "Forward shading is often better suited for VR rendering."),
ESetupRuleCategory::Rendering,
ESetupRuleSeverity::Performance,
ESetupRulePlatform::MetaLink) {}
virtual bool IsApplied() const override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
class FEnableMSAARule final : public ISetupRule
{
public:
FEnableMSAARule()
: ISetupRule("Rendering_EnableMSAA",
NSLOCTEXT("OculusXRRenderingRules", "EnableMSAA_DisplayName", "Enable MSAA"),
NSLOCTEXT("OculusXRRenderingRules", "EnableMSAA_Description", "MSAA provides higher quality antialiasing at a reasonable cost."),
ESetupRuleCategory::Rendering,
ESetupRuleSeverity::Performance,
MetaQuest_All) {}
virtual bool IsApplied() const override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
class FEnableOcclusionCullingRule final : public ISetupRule
{
public:
FEnableOcclusionCullingRule()
: ISetupRule("Rendering_EnableOcclusionCulling",
NSLOCTEXT("OculusXRRenderingRules", "EnableOcclusionCulling_DisplayName", "Enable Occlusion Culling"),
NSLOCTEXT("OculusXRRenderingRules", "EnableOcclusionCulling_Description", "Occlusion culling can provide significant performance gains."),
TEXT("https://developers.meta.com/horizon/documentation/unreal/po-fork-engine-perf"),
ESetupRuleCategory::Rendering,
ESetupRuleSeverity::Performance) {}
virtual bool IsApplied() const override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
class FEnableDynamicFoveationRule final : public ISetupRule
{
public:
FEnableDynamicFoveationRule()
: ISetupRule("Rendering_EnableDynamicFoveation",
NSLOCTEXT("OculusXRRenderingRules", "EnableDynamicFoveation_DisplayName", "Enable Dynamic Foveation"),
NSLOCTEXT("OculusXRRenderingRules", "EnableDynamicFoveation_Description", "Dynamic foveated rendering significantly reduces rendering cost."),
ESetupRuleCategory::Rendering,
ESetupRuleSeverity::Performance,
MetaQuest_All) {}
virtual bool IsApplied() const override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
#ifdef WITH_OCULUS_BRANCH
class FEnableDynamicResolutionRule final : public ISetupRule
{
public:
FEnableDynamicResolutionRule()
: ISetupRule("Rendering_EnableDynamicResolution",
NSLOCTEXT("OculusXRRenderingRules", "EnableDynamicResolution_DisplayName", "Enable Dynamic Resolution"),
NSLOCTEXT("OculusXRRenderingRules", "EnableDynamicResolution_Description", "Dynamic resolution rendering significantly reduces rendering cost."),
TEXT("https://developers.meta.com/horizon/documentation/unreal/dynamic-resolution-unreal"),
ESetupRuleCategory::Rendering,
ESetupRuleSeverity::Performance,
MetaQuest_All) {}
virtual bool IsApplied() const override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
class FEnableMobileUniformLocalLightsRule final : public ISetupRule
{
public:
FEnableMobileUniformLocalLightsRule()
: ISetupRule("Rendering_MobileUniformLocalLights",
NSLOCTEXT("OculusXRRenderingRules", "MobileUniformLocalLights_DisplayName", "Enable OR Ignore MobileUniformLocalLights"),
NSLOCTEXT("OculusXRRenderingRules",
"MobileUniformLocalLights_Description",
"MobileUniformLocalLights might perform better than default LightGrid shading in small number of dynamic local lights cases.\nEither Enable MobileUniformLocalLights in ProjectSettings or Ignore this rule here.\nNOTE: MobileUniformLocalLights is incompatible with GPUScene."),
TEXT("https://developers.meta.com/horizon/documentation/unreal/po-fork-engine-perf"),
ESetupRuleCategory::Rendering,
ESetupRuleSeverity::Performance,
MetaQuest_All,
false) {}
virtual bool IsApplied() const override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
class FEnableEmulatedUniformBuffersRule final : public ISetupRule
{
public:
FEnableEmulatedUniformBuffersRule()
: ISetupRule("Rendering_EnableEmulatedUniformBuffers",
NSLOCTEXT("OculusXRRenderingRules", "EnableEmulatedUniformBuffers_DisplayName", "Enable Emulated Uniform Buffers"),
NSLOCTEXT("OculusXRRenderingRules", "EnableEmulatedUniformBuffers_Description", "Optimizes performance by consolidating constant buffers into a single global uniform buffer for improved shader compiler optimization.\nNOTE: EmulatedUniformBuffers is incompatible with GPUScene."),
TEXT("https://developers.meta.com/horizon/documentation/unreal/po-fork-engine-perf"),
ESetupRuleCategory::Rendering,
ESetupRuleSeverity::Performance,
MetaQuest_All) {}
virtual bool IsApplied() const override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
#endif
class FDisableLensFlareRule final : public ISetupRule
{
public:
FDisableLensFlareRule()
: ISetupRule("Rendering_DisableLensFlare",
NSLOCTEXT("OculusXRRenderingRules", "DisableLensFlare_DisplayName", "Disable Lens Flare"),
NSLOCTEXT("OculusXRRenderingRules", "DisableLensFlare_Description", "Lens flare can be expensive and exhibit visible artifacts in VR."),
ESetupRuleCategory::Rendering,
ESetupRuleSeverity::Performance) {}
virtual bool IsApplied() const override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
class FDisablePostProcessingRule final : public ISetupRule
{
public:
FDisablePostProcessingRule()
: ISetupRule("Rendering_DisablePostProcessing",
NSLOCTEXT("OculusXRRenderingRules", "DisablePostProcessing_DisplayName", "Disable Post Processing"),
NSLOCTEXT("OculusXRRenderingRules", "DisablePostProcessing_Description", "Mobile HDR has performance and stability issues in VR. We strongly recommend disabling it."),
ESetupRuleCategory::Rendering,
ESetupRuleSeverity::Performance,
MetaQuest_All) {}
virtual bool IsApplied() const override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
class FDisableAmbientOcclusionRule final : public ISetupRule
{
public:
FDisableAmbientOcclusionRule()
: ISetupRule("Rendering_DisableAmbientOcclusion",
NSLOCTEXT("OculusXRRenderingRules", "DisableAmbientOcclusion_DisplayName", "Disable Ambient Occlusion"),
NSLOCTEXT("OculusXRRenderingRules", "DisableAmbientOcclusion_Description", "Ambient occlusion has performance issues. We recommend disabling it."),
ESetupRuleCategory::Rendering,
ESetupRuleSeverity::Performance,
MetaQuest_All) {}
virtual bool IsApplied() const override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
class FEnableMultiViewRule final : public ISetupRule
{
public:
FEnableMultiViewRule()
: ISetupRule("Rendering_EnableMultiView",
NSLOCTEXT("OculusXRRenderingRules", "EnableMultiView_DisplayName", "Enable Mobile Multiveiw"),
NSLOCTEXT("OculusXRRenderingRules", "EnableMultiView_Description", "Enable mobile multi-view and direct mobile multi-view to significantly reduce CPU overhead."),
ESetupRuleCategory::Rendering,
ESetupRuleSeverity::Performance,
MetaQuest_All) {}
virtual bool IsApplied() const override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
class FEnableStaticLightingRule final : public ISetupRule
{
public:
FEnableStaticLightingRule()
: ISetupRule("Rendering_EnableStaticLighting",
NSLOCTEXT("OculusXRRenderingRules", "EnableStaticLighting_DisplayName", "Enable Static Lighting"),
NSLOCTEXT("OculusXRRenderingRules", "EnableStaticLighting_Description", "Static lighting should be disallowed only if project is intended to be 100% dynamically lit."),
ESetupRuleCategory::Rendering,
ESetupRuleSeverity::Performance,
All_Platforms) {}
virtual bool IsApplied() const override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
class FDisableMobileShaderStaticAndCSMShadowReceiversRule final : public ISetupRule
{
public:
FDisableMobileShaderStaticAndCSMShadowReceiversRule()
: ISetupRule(
"Rendering_MobileShaderStaticAndCSMShadowReceivers",
NSLOCTEXT("OculusXRRenderingRules", "MobileShaderStaticAndCSMShadowReceivers_DisplayName", "Disable Support Combined Static and CSM Shadowing"),
NSLOCTEXT("OculusXRRenderingRules", "MobileShaderStaticAndCSMShadowReceivers_Description", "The project does not contain any stationary lights. Support Combined Static and CSM Shadowing can be disabled to reduce shader permutations."),
ESetupRuleCategory::Rendering,
ESetupRuleSeverity::Performance) {}
virtual bool IsApplied() const override;
virtual bool IsValid() override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
class FDisableMobileShaderAllowDistanceFieldShadowsRule final : public ISetupRule
{
public:
FDisableMobileShaderAllowDistanceFieldShadowsRule()
: ISetupRule("Rendering_MobileShaderAllowDistanceFieldShadows",
NSLOCTEXT("OculusXRRenderingRules", "MobileShaderAllowDistanceFieldShadows_DisplayName", "Disable Support Support Distance Field Shadows"),
NSLOCTEXT("OculusXRRenderingRules", "MobileShaderAllowDistanceFieldShadows_Description", "The project does not contain any stationary lights. Support Support Distance Field Shadows can be disabled to reduce shader permutations."),
ESetupRuleCategory::Rendering,
ESetupRuleSeverity::Performance,
MetaQuest_All) {}
virtual bool IsApplied() const override;
virtual bool IsValid() override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
#if UE_VERSION_OLDER_THAN(5, 5, 0)
class FDisableMobileShaderAllowMovableDirectionalLightsRule final : public ISetupRule
{
public:
FDisableMobileShaderAllowMovableDirectionalLightsRule()
: ISetupRule("Rendering_MobileShaderAllowMovableDirectionalLights",
NSLOCTEXT("OculusXRRenderingRules", "MobileShaderAllowMovableDirectionalLights_DisplayName", "Disable Support Movable Directional Lights"),
NSLOCTEXT("OculusXRRenderingRules", "MobileShaderAllowMovableDirectionalLights_Description", "The project does not contain any movable lights. Support Movable Directional Lights can be disabled to reduce shader permutations."),
ESetupRuleCategory::Rendering,
ESetupRuleSeverity::Performance,
MetaQuest_All) {}
virtual bool IsApplied() const override;
virtual bool IsValid() override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
#endif
#ifdef WITH_OCULUS_BRANCH
class FDisableMobileGPUSceneRule final : public ISetupRule
{
public:
FDisableMobileGPUSceneRule()
: ISetupRule("Rendering_MobileGPUScene",
NSLOCTEXT("OculusXRRenderingRules", "MobileGPUSceneLights_DisplayName", "Disable Support GPUScene"),
NSLOCTEXT("OculusXRRenderingRules", "MobileGPUSceneLights_Description", "GPUScene is not compatible with MobileUniformLocalLights and EmulatedUniformBuffers."),
ESetupRuleCategory::Rendering,
ESetupRuleSeverity::Performance,
MetaQuest_All) {}
virtual bool IsApplied() const override;
virtual bool IsValid() override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
#endif
class FUseAndroidVulkanPreviewPlatform final : public ISetupRule
{
public:
FUseAndroidVulkanPreviewPlatform();
virtual bool IsApplied() const override;
virtual bool IsValid() override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
private:
FPreviewPlatformInfo AndroidVulkanPreview;
};
class FDisableMobileMoveableSpotlightShadowsRule final : public ISetupRule
{
public:
FDisableMobileMoveableSpotlightShadowsRule();
virtual bool IsApplied() const override;
protected:
virtual void ApplyImpl(bool& OutShouldRestartEditor) override;
};
// All defined rendering rules. Add new rules to this table for them to be auto-registered
inline TArray<SetupRulePtr> RenderingRules_Table{
MakeShared<FUseVulkanRule>(),
MakeShared<FUseHalfPrecisionFloatRule>(),
MakeShared<FEnableInstancedStereoRule>(),
MakeShared<FEnableForwardShadingRule>(),
MakeShared<FEnablePCForwardShadingRule>(),
MakeShared<FEnableMSAARule>(),
MakeShared<FEnableOcclusionCullingRule>(),
MakeShared<FEnableDynamicFoveationRule>(),
#ifdef WITH_OCULUS_BRANCH
MakeShared<FEnableDynamicResolutionRule>(),
MakeShared<FEnableMobileUniformLocalLightsRule>(),
MakeShared<FEnableEmulatedUniformBuffersRule>(),
MakeShared<FDisableMobileGPUSceneRule>(),
#endif
MakeShared<FDisableLensFlareRule>(),
MakeShared<FDisablePostProcessingRule>(),
MakeShared<FDisableAmbientOcclusionRule>(),
MakeShared<FEnableMultiViewRule>(),
MakeShared<FEnableStaticLightingRule>(),
MakeShared<FDisableMobileShaderStaticAndCSMShadowReceiversRule>(),
MakeShared<FDisableMobileShaderAllowDistanceFieldShadowsRule>(),
#if UE_VERSION_OLDER_THAN(5, 5, 0)
MakeShared<FDisableMobileShaderAllowMovableDirectionalLightsRule>(),
#endif
MakeShared<FUseAndroidVulkanPreviewPlatform>(),
MakeShared<FDisableMobileMoveableSpotlightShadowsRule>()
};
} // namespace OculusXRRenderingRules