Refactor settings types to use scripting API
This commit is contained in:
@@ -44,9 +44,14 @@ Array<AudioDevice> Audio::Devices;
|
||||
Action Audio::DevicesChanged;
|
||||
Action Audio::ActiveDeviceChanged;
|
||||
AudioBackend* AudioBackend::Instance = nullptr;
|
||||
float MasterVolume = 1.0f;
|
||||
float Volume = 1.0f;
|
||||
int32 ActiveDeviceIndex = -1;
|
||||
|
||||
namespace
|
||||
{
|
||||
float MasterVolume = 1.0f;
|
||||
float Volume = 1.0f;
|
||||
int32 ActiveDeviceIndex = -1;
|
||||
bool MuteOnFocusLoss = true;
|
||||
}
|
||||
|
||||
class AudioService : public EngineService
|
||||
{
|
||||
@@ -77,6 +82,11 @@ namespace
|
||||
}
|
||||
}
|
||||
|
||||
void AudioSettings::Apply()
|
||||
{
|
||||
::MuteOnFocusLoss = MuteOnFocusLoss;
|
||||
}
|
||||
|
||||
AudioDevice* Audio::GetActiveDevice()
|
||||
{
|
||||
return &Devices[ActiveDeviceIndex];
|
||||
@@ -161,7 +171,7 @@ void Audio::OnRemoveSource(AudioSource* source)
|
||||
|
||||
bool AudioService::Init()
|
||||
{
|
||||
const auto settings = AudioSettings::Instance();
|
||||
const auto settings = AudioSettings::Get();
|
||||
const bool mute = CommandLine::Options.Mute.IsTrue() || settings->DisableAudio;
|
||||
|
||||
// Pick a backend to use
|
||||
@@ -225,11 +235,9 @@ void AudioService::Update()
|
||||
{
|
||||
PROFILE_CPU();
|
||||
|
||||
const auto settings = AudioSettings::Instance();
|
||||
|
||||
// Update the master volume
|
||||
float masterVolume = MasterVolume;
|
||||
if (settings->MuteOnFocusLoss && !Engine::HasFocus)
|
||||
if (MuteOnFocusLoss && !Engine::HasFocus)
|
||||
{
|
||||
// Mute audio if app has no user focus
|
||||
masterVolume = 0.0f;
|
||||
|
||||
@@ -8,35 +8,38 @@
|
||||
/// <summary>
|
||||
/// Audio settings container.
|
||||
/// </summary>
|
||||
/// <seealso cref="SettingsBase{AudioSettings}" />
|
||||
class AudioSettings : public SettingsBase<AudioSettings>
|
||||
API_CLASS(sealed, Namespace="FlaxEditor.Content.Settings") class FLAXENGINE_API AudioSettings : public SettingsBase
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(AudioSettings);
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// If checked, audio playback will be disabled in build game. Can be used if game uses custom audio playback engine.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(0), DefaultValue(false), EditorDisplay(\"General\")")
|
||||
bool DisableAudio = false;
|
||||
|
||||
/// <summary>
|
||||
/// The doppler effect factor. Scale for source and listener velocities. Default is 1.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(100), DefaultValue(1.0f), EditorDisplay(\"General\")")
|
||||
float DopplerFactor = 1.0f;
|
||||
|
||||
/// <summary>
|
||||
/// True if mute all audio playback when game has no use focus.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(200), DefaultValue(true), EditorDisplay(\"General\", \"Mute On Focus Loss\")")
|
||||
bool MuteOnFocusLoss = true;
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instance of the settings asset (default value if missing). Object returned by this method is always loaded with valid data to use.
|
||||
/// </summary>
|
||||
static AudioSettings* Get();
|
||||
|
||||
// [SettingsBase]
|
||||
void RestoreDefault() final override
|
||||
{
|
||||
DisableAudio = false;
|
||||
DopplerFactor = 1.0f;
|
||||
MuteOnFocusLoss = true;
|
||||
}
|
||||
void Apply() override;
|
||||
|
||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) final override
|
||||
{
|
||||
|
||||
@@ -878,7 +878,7 @@ bool AudioBackendOAL::Base_Init()
|
||||
|
||||
// Init
|
||||
ALC::AL_EXT_float32 = ALC::IsExtensionSupported("AL_EXT_float32");
|
||||
SetDopplerFactor(AudioSettings::Instance()->DopplerFactor);
|
||||
SetDopplerFactor(AudioSettings::Get()->DopplerFactor);
|
||||
ALC::RebuildContexts(true);
|
||||
Audio::SetActiveDeviceIndex(activeDeviceIndex);
|
||||
|
||||
|
||||
@@ -794,7 +794,7 @@ void AudioBackendXAudio2::Base_Update()
|
||||
}
|
||||
|
||||
// Update dirty voices
|
||||
const float dopplerFactor = AudioSettings::Instance()->DopplerFactor;
|
||||
const float dopplerFactor = AudioSettings::Get()->DopplerFactor;
|
||||
X3DAUDIO_DSP_SETTINGS dsp = { 0 };
|
||||
dsp.DstChannelCount = XAudio2::Channels;
|
||||
dsp.pMatrixCoefficients = XAudio2::MatrixCoefficients;
|
||||
|
||||
@@ -214,6 +214,7 @@ Asset::LoadResult JsonAsset::loadAsset()
|
||||
if (!instance)
|
||||
return LoadResult::Failed;
|
||||
Instance = instance;
|
||||
InstanceType = typeHandle;
|
||||
_dtor = type.Class.Dtor;
|
||||
type.Class.Ctor(instance);
|
||||
|
||||
@@ -238,6 +239,7 @@ void JsonAsset::unload(bool isReloading)
|
||||
|
||||
if (Instance)
|
||||
{
|
||||
InstanceType = ScriptingTypeHandle();
|
||||
_dtor(Instance);
|
||||
Allocator::Free(Instance);
|
||||
Instance = nullptr;
|
||||
|
||||
@@ -74,7 +74,6 @@ protected:
|
||||
/// <summary>
|
||||
/// Generic type of Json-format asset. It provides the managed representation of this resource data so it can be accessed via C# API.
|
||||
/// </summary>
|
||||
/// <seealso cref="JsonAssetBase" />
|
||||
API_CLASS(NoSpawn) class JsonAsset : public JsonAssetBase
|
||||
{
|
||||
DECLARE_ASSET_HEADER(JsonAsset);
|
||||
@@ -83,6 +82,11 @@ private:
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// The scripting type of the deserialized unmanaged object instance (e.g. PhysicalMaterial).
|
||||
/// </summary>
|
||||
ScriptingTypeHandle InstanceType;
|
||||
|
||||
/// <summary>
|
||||
/// The deserialized unmanaged object instance (e.g. PhysicalMaterial).
|
||||
/// </summary>
|
||||
|
||||
@@ -10,71 +10,73 @@
|
||||
/// <summary>
|
||||
/// The game building rendering settings.
|
||||
/// </summary>
|
||||
class BuildSettings : public SettingsBase<BuildSettings>
|
||||
API_CLASS(sealed, Namespace="FlaxEditor.Content.Settings") class FLAXENGINE_API BuildSettings : public SettingsBase
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(BuildSettings);
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// The maximum amount of assets to include into a single assets package. Asset packages will split into several packages if need to.
|
||||
/// </summary>
|
||||
int32 MaxAssetsPerPackage = 1024;
|
||||
API_FIELD(Attributes="EditorOrder(10), DefaultValue(4096), Limit(1, 32, ushort.MaxValue), EditorDisplay(\"General\", \"Max assets per package\")")
|
||||
int32 MaxAssetsPerPackage = 4096;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum size of the single assets package (in megabytes). Asset packages will split into several packages if need to.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(20), DefaultValue(1024), Limit(1, 16, ushort.MaxValue), EditorDisplay(\"General\", \"Max package size (in MB)\")")
|
||||
int32 MaxPackageSizeMB = 1024;
|
||||
|
||||
/// <summary>
|
||||
/// The game content cooking keycode. Use the same value for a game and DLC packages to support loading them by the build game. Use 0 to randomize it during building.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(30), DefaultValue(0), Limit(1, 16, ushort.MaxValue), EditorDisplay(\"General\")")
|
||||
int32 ContentKey = 0;
|
||||
|
||||
/// <summary>
|
||||
/// If checked, the builds produced by the Game Cooker will be treated as for final game distribution (eg. for game store upload). Builds done this way cannot be tested on console devkits (eg. Xbox One, Xbox Scarlett).
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(40), DefaultValue(false), EditorDisplay(\"General\")")
|
||||
bool ForDistribution = false;
|
||||
|
||||
/// <summary>
|
||||
/// If checked, the output build files won't be packaged for the destination platform. Useful when debugging build from local PC.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(50), DefaultValue(false), EditorDisplay(\"General\")")
|
||||
bool SkipPackaging = false;
|
||||
|
||||
/// <summary>
|
||||
/// The list of additional assets to include into build (into root assets set).
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(1000), EditorDisplay(\"Additional Data\")")
|
||||
Array<AssetReference<Asset>> AdditionalAssets;
|
||||
|
||||
/// <summary>
|
||||
/// The list of additional folders with assets to include into build (into root assets set). Paths relative to the project directory (or absolute).
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(1010), EditorDisplay(\"Additional Data\")")
|
||||
Array<String> AdditionalAssetFolders;
|
||||
|
||||
/// <summary>
|
||||
/// Disables shaders compiler optimizations in cooked game. Can be used to debug shaders on a target platform or to speed up the shaders compilation time.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(2000), DefaultValue(false), EditorDisplay(\"Content\", \"Shaders No Optimize\")")
|
||||
bool ShadersNoOptimize = false;
|
||||
|
||||
/// <summary>
|
||||
/// Enables shader debug data generation for shaders in cooked game (depends on the target platform rendering backend).
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(2010), DefaultValue(false), EditorDisplay(\"Content\")")
|
||||
bool ShadersGenerateDebugData = false;
|
||||
|
||||
public:
|
||||
|
||||
// [SettingsBase]
|
||||
void RestoreDefault() final override
|
||||
{
|
||||
MaxAssetsPerPackage = 1024;
|
||||
MaxPackageSizeMB = 1024;
|
||||
ContentKey = 0;
|
||||
ForDistribution = false;
|
||||
SkipPackaging = false;
|
||||
AdditionalAssets.Clear();
|
||||
AdditionalAssetFolders.Clear();
|
||||
ShadersNoOptimize = false;
|
||||
ShadersGenerateDebugData = false;
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instance of the settings asset (default value if missing). Object returned by this method is always loaded with valid data to use.
|
||||
/// </summary>
|
||||
static BuildSettings* Get();
|
||||
|
||||
// [SettingsBase]
|
||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) final override
|
||||
{
|
||||
DESERIALIZE(MaxAssetsPerPackage);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
|
||||
#include "GameSettings.h"
|
||||
#include "Engine/Serialization/JsonTools.h"
|
||||
#include "Engine/Scripting/ScriptingType.h"
|
||||
#include "Engine/Physics/PhysicsSettings.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "LayersTagsSettings.h"
|
||||
@@ -17,30 +18,6 @@
|
||||
#include "Engine/Content/AssetReference.h"
|
||||
#include "Engine/Engine/EngineService.h"
|
||||
#include "Engine/Engine/Globals.h"
|
||||
#include "Engine/Engine/Time.h"
|
||||
|
||||
String GameSettings::ProductName;
|
||||
String GameSettings::CompanyName;
|
||||
String GameSettings::CopyrightNotice;
|
||||
Guid GameSettings::Icon;
|
||||
Guid GameSettings::FirstScene;
|
||||
bool GameSettings::NoSplashScreen = false;
|
||||
Guid GameSettings::SplashScreen;
|
||||
Dictionary<String, Guid> GameSettings::CustomSettings;
|
||||
|
||||
Array<Settings*> Settings::Containers(32);
|
||||
|
||||
#if USE_EDITOR
|
||||
extern void LoadPlatformSettingsEditor(ISerializable::DeserializeStream& data);
|
||||
#endif
|
||||
|
||||
void TimeSettings::Apply()
|
||||
{
|
||||
Time::UpdateFPS = UpdateFPS;
|
||||
Time::PhysicsFPS = PhysicsFPS;
|
||||
Time::DrawFPS = DrawFPS;
|
||||
Time::TimeScale = TimeScale;
|
||||
}
|
||||
|
||||
class GameSettingsService : public EngineService
|
||||
{
|
||||
@@ -49,9 +26,6 @@ public:
|
||||
GameSettingsService()
|
||||
: EngineService(TEXT("GameSettings"), -70)
|
||||
{
|
||||
GameSettings::Icon = Guid::Empty;
|
||||
GameSettings::FirstScene = Guid::Empty;
|
||||
GameSettings::SplashScreen = Guid::Empty;
|
||||
}
|
||||
|
||||
bool Init() override
|
||||
@@ -60,62 +34,141 @@ public:
|
||||
}
|
||||
};
|
||||
|
||||
IMPLEMENT_SETTINGS_GETTER(BuildSettings, GameCooking);
|
||||
IMPLEMENT_SETTINGS_GETTER(GraphicsSettings, Graphics);
|
||||
IMPLEMENT_SETTINGS_GETTER(LayersAndTagsSettings, LayersAndTags);
|
||||
IMPLEMENT_SETTINGS_GETTER(TimeSettings, Time);
|
||||
IMPLEMENT_SETTINGS_GETTER(AudioSettings, Audio);
|
||||
IMPLEMENT_SETTINGS_GETTER(PhysicsSettings, Physics);
|
||||
IMPLEMENT_SETTINGS_GETTER(InputSettings, Input);
|
||||
|
||||
#if !USE_EDITOR
|
||||
#if PLATFORM_WINDOWS
|
||||
IMPLEMENT_SETTINGS_GETTER(WindowsPlatformSettings, WindowsPlatform);
|
||||
#elif PLATFORM_UWP || PLATFORM_XBOX_ONE
|
||||
IMPLEMENT_SETTINGS_GETTER(UWPPlatformSettings, UWPPlatform);
|
||||
#elif PLATFORM_LINUX
|
||||
IMPLEMENT_SETTINGS_GETTER(LinuxPlatformSettings, LinuxPlatform);
|
||||
#elif PLATFORM_PS4
|
||||
IMPLEMENT_SETTINGS_GETTER(PS4PlatformSettings, PS4Platform);
|
||||
#elif PLATFORM_XBOX_SCARLETT
|
||||
IMPLEMENT_SETTINGS_GETTER(XboxScarlettPlatformSettings, XboxScarlettPlatform);
|
||||
#elif PLATFORM_ANDROID
|
||||
IMPLEMENT_SETTINGS_GETTER(AndroidPlatformSettings, AndroidPlatform);
|
||||
#else
|
||||
#error Unknown platform
|
||||
#endif
|
||||
#endif
|
||||
|
||||
GameSettingsService GameSettingsServiceInstance;
|
||||
AssetReference<JsonAsset> GameSettingsAsset;
|
||||
|
||||
GameSettings* GameSettings::Get()
|
||||
{
|
||||
if (!GameSettingsAsset)
|
||||
{
|
||||
// Load root game settings asset.
|
||||
// It may be missing in editor during dev but must be ready in the build game.
|
||||
const auto assetPath = Globals::ProjectContentFolder / TEXT("GameSettings.json");
|
||||
GameSettingsAsset = Content::LoadAsync<JsonAsset>(assetPath);
|
||||
if (GameSettingsAsset == nullptr)
|
||||
{
|
||||
LOG(Error, "Missing game settings asset.");
|
||||
return nullptr;
|
||||
}
|
||||
if (GameSettingsAsset->WaitForLoaded())
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
if (GameSettingsAsset->InstanceType != GameSettings::TypeInitializer)
|
||||
{
|
||||
LOG(Error, "Invalid game settings asset data type.");
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
auto asset = GameSettingsAsset.Get();
|
||||
if (asset && asset->WaitForLoaded())
|
||||
asset = nullptr;
|
||||
return asset ? (GameSettings*)asset->Instance : nullptr;
|
||||
}
|
||||
|
||||
bool GameSettings::Load()
|
||||
{
|
||||
// Load main settings asset
|
||||
auto settings = Get();
|
||||
if (!settings)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
// Preload all settings assets
|
||||
#define PRELOAD_SETTINGS(type) \
|
||||
{ \
|
||||
if (settings->type) \
|
||||
{ \
|
||||
Content::LoadAsync<JsonAsset>(settings->type); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
LOG(Warning, "Missing {0} settings", TEXT(#type)); \
|
||||
} \
|
||||
}
|
||||
PRELOAD_SETTINGS(Time);
|
||||
PRELOAD_SETTINGS(Audio);
|
||||
PRELOAD_SETTINGS(LayersAndTags);
|
||||
PRELOAD_SETTINGS(Physics);
|
||||
PRELOAD_SETTINGS(Input);
|
||||
PRELOAD_SETTINGS(Graphics);
|
||||
PRELOAD_SETTINGS(Navigation);
|
||||
PRELOAD_SETTINGS(GameCooking);
|
||||
#undef PRELOAD_SETTINGS
|
||||
|
||||
// Apply the game settings to the engine
|
||||
settings->Apply();
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void GameSettings::Apply()
|
||||
{
|
||||
// TODO: impl this
|
||||
#define APPLY_SETTINGS(type) \
|
||||
{ \
|
||||
type* obj = type::Get(); \
|
||||
if (obj) \
|
||||
{ \
|
||||
obj->Apply(); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
LOG(Warning, "Missing {0} settings", TEXT(#type)); \
|
||||
} \
|
||||
}
|
||||
APPLY_SETTINGS(TimeSettings);
|
||||
APPLY_SETTINGS(AudioSettings);
|
||||
APPLY_SETTINGS(LayersAndTagsSettings);
|
||||
APPLY_SETTINGS(PhysicsSettings);
|
||||
APPLY_SETTINGS(InputSettings);
|
||||
APPLY_SETTINGS(GraphicsSettings);
|
||||
APPLY_SETTINGS(NavigationSettings);
|
||||
APPLY_SETTINGS(BuildSettings);
|
||||
APPLY_SETTINGS(PlatformSettings);
|
||||
#undef APPLY_SETTINGS
|
||||
}
|
||||
|
||||
void GameSettings::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier)
|
||||
{
|
||||
// Load properties
|
||||
ProductName = JsonTools::GetString(stream, "ProductName");
|
||||
CompanyName = JsonTools::GetString(stream, "CompanyName");
|
||||
CopyrightNotice = JsonTools::GetString(stream, "CopyrightNotice");
|
||||
Icon = JsonTools::GetGuid(stream, "Icon");
|
||||
FirstScene = JsonTools::GetGuid(stream, "FirstScene");
|
||||
NoSplashScreen = JsonTools::GetBool(stream, "NoSplashScreen", NoSplashScreen);
|
||||
SplashScreen = JsonTools::GetGuid(stream, "SplashScreen");
|
||||
CustomSettings.Clear();
|
||||
|
||||
#if USE_EDITOR
|
||||
#define END_POINT(msg) LOG(Warning, msg " Using default values."); return false
|
||||
#else
|
||||
#define END_POINT(msg) LOG(Fatal, msg); return true
|
||||
#endif
|
||||
|
||||
#define LOAD_SETTINGS(nodeName, settingsType) \
|
||||
{ \
|
||||
Guid id = JsonTools::GetGuid(data, nodeName); \
|
||||
if (id.IsValid()) \
|
||||
{ \
|
||||
AssetReference<JsonAsset> subAsset = Content::LoadAsync<JsonAsset>(id); \
|
||||
if (subAsset && !subAsset->WaitForLoaded()) \
|
||||
{ \
|
||||
settingsType::Instance()->Deserialize(*subAsset->Data, nullptr); \
|
||||
settingsType::Instance()->Apply(); \
|
||||
} \
|
||||
else \
|
||||
{ LOG(Warning, "Cannot load " nodeName " settings"); } \
|
||||
} \
|
||||
else \
|
||||
{ LOG(Warning, "Missing " nodeName " settings"); } \
|
||||
}
|
||||
|
||||
// Load root game settings asset.
|
||||
// It may be missing in editor during dev but must be ready in the build game.
|
||||
const auto assetPath = Globals::ProjectContentFolder / TEXT("GameSettings.json");
|
||||
AssetReference<JsonAsset> asset = Content::LoadAsync<JsonAsset>(assetPath);
|
||||
if (asset == nullptr)
|
||||
{
|
||||
END_POINT("Missing game settings asset.");
|
||||
}
|
||||
if (asset->WaitForLoaded()
|
||||
|| asset->DataTypeName != TEXT("FlaxEditor.Content.Settings.GameSettings")
|
||||
|| asset->Data == nullptr)
|
||||
{
|
||||
END_POINT("Cannot load game settings asset.");
|
||||
}
|
||||
auto& data = *asset->Data;
|
||||
|
||||
// Load settings
|
||||
ProductName = JsonTools::GetString(data, "ProductName");
|
||||
CompanyName = JsonTools::GetString(data, "CompanyName");
|
||||
CopyrightNotice = JsonTools::GetString(data, "CopyrightNotice");
|
||||
Icon = JsonTools::GetGuid(data, "Icon");
|
||||
FirstScene = JsonTools::GetGuid(data, "FirstScene");
|
||||
NoSplashScreen = JsonTools::GetBool(data, "NoSplashScreen", NoSplashScreen);
|
||||
SplashScreen = JsonTools::GetGuid(data, "SplashScreen");
|
||||
const auto customSettings = data.FindMember("CustomSettings");
|
||||
if (customSettings != data.MemberEnd())
|
||||
const auto customSettings = stream.FindMember("CustomSettings");
|
||||
if (customSettings != stream.MemberEnd())
|
||||
{
|
||||
auto& items = customSettings->value;
|
||||
for (auto it = items.MemberBegin(); it != items.MemberEnd(); ++it)
|
||||
@@ -129,39 +182,21 @@ bool GameSettings::Load()
|
||||
}
|
||||
}
|
||||
|
||||
// Load child settings
|
||||
LOAD_SETTINGS("Time", TimeSettings);
|
||||
LOAD_SETTINGS("Physics", PhysicsSettings);
|
||||
LOAD_SETTINGS("LayersAndTags", LayersAndTagsSettings);
|
||||
LOAD_SETTINGS("Graphics", GraphicsSettings);
|
||||
LOAD_SETTINGS("GameCooking", BuildSettings);
|
||||
LOAD_SETTINGS("Input", InputSettings);
|
||||
LOAD_SETTINGS("Audio", AudioSettings);
|
||||
LOAD_SETTINGS("Navigation", NavigationSettings);
|
||||
// Settings containers
|
||||
DESERIALIZE(Time);
|
||||
DESERIALIZE(Audio);
|
||||
DESERIALIZE(LayersAndTags);
|
||||
DESERIALIZE(Physics);
|
||||
DESERIALIZE(Input);
|
||||
DESERIALIZE(Graphics);
|
||||
DESERIALIZE(Navigation);
|
||||
DESERIALIZE(GameCooking);
|
||||
|
||||
// Load platform settings
|
||||
#if PLATFORM_WINDOWS
|
||||
LOAD_SETTINGS("WindowsPlatform", WindowsPlatformSettings);
|
||||
#endif
|
||||
#if PLATFORM_UWP
|
||||
LOAD_SETTINGS("UWPPlatform", UWPPlatformSettings);
|
||||
#endif
|
||||
#if PLATFORM_LINUX
|
||||
LOAD_SETTINGS("LinuxPlatform", LinuxPlatformSettings);
|
||||
#endif
|
||||
#if PLATFORM_PS4
|
||||
LOAD_SETTINGS("PS4Platform", PS4PlatformSettings);
|
||||
#endif
|
||||
#if PLATFORM_XBOX_SCARLETT
|
||||
LOAD_SETTINGS("XboxScarlettPlatform", XboxScarlettPlatformSettings);
|
||||
#endif
|
||||
#if PLATFORM_ANDROID
|
||||
LOAD_SETTINGS("AndroidPlatform", AndroidPlatformSettings);
|
||||
#endif
|
||||
#if USE_EDITOR
|
||||
LoadPlatformSettingsEditor(data);
|
||||
#endif
|
||||
|
||||
return false;
|
||||
#undef END_POINT
|
||||
// Per-platform settings containers
|
||||
DESERIALIZE(WindowsPlatform);
|
||||
DESERIALIZE(UWPPlatform);
|
||||
DESERIALIZE(LinuxPlatform);
|
||||
DESERIALIZE(PS4Platform);
|
||||
DESERIALIZE(XboxScarlettPlatform);
|
||||
DESERIALIZE(AndroidPlatform);
|
||||
}
|
||||
|
||||
@@ -2,60 +2,96 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Settings.h"
|
||||
#include "Engine/Core/Types/Guid.h"
|
||||
#include "Engine/Core/Types/String.h"
|
||||
#include "Engine/Core/Collections/Dictionary.h"
|
||||
|
||||
/// <summary>
|
||||
/// Main engine configuration service. Loads and applies game configuration.
|
||||
/// The main game engine configuration service. Loads and applies game configuration.
|
||||
/// </summary>
|
||||
class GameSettings
|
||||
API_CLASS(sealed, Namespace="FlaxEditor.Content.Settings") class FLAXENGINE_API GameSettings : public SettingsBase
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(GameSettings);
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// The product full name.
|
||||
/// </summary>
|
||||
static String ProductName;
|
||||
API_FIELD(Attributes="EditorOrder(0), EditorDisplay(\"General\")")
|
||||
String ProductName;
|
||||
|
||||
/// <summary>
|
||||
/// The company full name.
|
||||
/// </summary>
|
||||
static String CompanyName;
|
||||
API_FIELD(Attributes="EditorOrder(10), EditorDisplay(\"General\")")
|
||||
String CompanyName;
|
||||
|
||||
/// <summary>
|
||||
/// The copyright note used for content signing (eg. source code header).
|
||||
/// </summary>
|
||||
static String CopyrightNotice;
|
||||
API_FIELD(Attributes="EditorOrder(15), EditorDisplay(\"General\")")
|
||||
String CopyrightNotice;
|
||||
|
||||
/// <summary>
|
||||
/// The default application icon.
|
||||
/// </summary>
|
||||
static Guid Icon;
|
||||
Guid Icon = Guid::Empty;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the first scene to load on a game startup.
|
||||
/// </summary>
|
||||
static Guid FirstScene;
|
||||
Guid FirstScene = Guid::Empty;
|
||||
|
||||
/// <summary>
|
||||
/// True if skip showing splash screen image on the game startup.
|
||||
/// </summary>
|
||||
static bool NoSplashScreen;
|
||||
bool NoSplashScreen = false;
|
||||
|
||||
/// <summary>
|
||||
/// Reference to the splash screen image to show on a game startup.
|
||||
/// </summary>
|
||||
static Guid SplashScreen;
|
||||
Guid SplashScreen = Guid::Empty;
|
||||
|
||||
/// <summary>
|
||||
/// The custom settings to use with a game. Can be specified by the user to define game-specific options and be used by the external plugins (used as key-value pair).
|
||||
/// </summary>
|
||||
static Dictionary<String, Guid> CustomSettings;
|
||||
Dictionary<String, Guid> CustomSettings;
|
||||
|
||||
public:
|
||||
|
||||
// Settings containers
|
||||
Guid Time;
|
||||
Guid Audio;
|
||||
Guid LayersAndTags;
|
||||
Guid Physics;
|
||||
Guid Input;
|
||||
Guid Graphics;
|
||||
Guid Navigation;
|
||||
Guid GameCooking;
|
||||
|
||||
// Per-platform settings containers
|
||||
Guid WindowsPlatform;
|
||||
Guid UWPPlatform;
|
||||
Guid LinuxPlatform;
|
||||
Guid PS4Platform;
|
||||
Guid XboxScarlettPlatform;
|
||||
Guid AndroidPlatform;
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instance of the game settings asset (null if missing). Object returned by this method is always loaded with valid data to use.
|
||||
/// </summary>
|
||||
static GameSettings* Get();
|
||||
|
||||
/// <summary>
|
||||
/// Loads the game settings (including other settings such as Physics, Input, etc.).
|
||||
/// </summary>
|
||||
/// <returns>True if failed, otherwise false.</returns>
|
||||
static bool Load();
|
||||
|
||||
// [SettingsBase]
|
||||
void Apply() override;
|
||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) final override;
|
||||
};
|
||||
|
||||
@@ -9,67 +9,68 @@
|
||||
/// <summary>
|
||||
/// Graphics rendering settings.
|
||||
/// </summary>
|
||||
class GraphicsSettings : public SettingsBase<GraphicsSettings>
|
||||
API_CLASS(sealed, Namespace="FlaxEditor.Content.Settings") class FLAXENGINE_API GraphicsSettings : public SettingsBase
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(GraphicsSettings);
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Enables rendering synchronization with the refresh rate of the display device to avoid "tearing" artifacts.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(20), DefaultValue(false), EditorDisplay(\"General\", \"Use V-Sync\")")
|
||||
bool UseVSync = false;
|
||||
|
||||
/// <summary>
|
||||
/// Anti Aliasing quality setting.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(1000), DefaultValue(Quality.Medium), EditorDisplay(\"Quality\", \"AA Quality\")")
|
||||
Quality AAQuality = Quality::Medium;
|
||||
|
||||
/// <summary>
|
||||
/// Screen Space Reflections quality setting.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(1100), DefaultValue(Quality.Medium), EditorDisplay(\"Quality\", \"SSR Quality\")")
|
||||
Quality SSRQuality = Quality::Medium;
|
||||
|
||||
/// <summary>
|
||||
/// Screen Space Ambient Occlusion quality setting.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(1200), DefaultValue(Quality.Medium), EditorDisplay(\"Quality\", \"SSAO Quality\")")
|
||||
Quality SSAOQuality = Quality::Medium;
|
||||
|
||||
/// <summary>
|
||||
/// Volumetric Fog quality setting.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(1250), DefaultValue(Quality.High), EditorDisplay(\"Quality\")")
|
||||
Quality VolumetricFogQuality = Quality::High;
|
||||
|
||||
/// <summary>
|
||||
/// The shadows quality.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(1300), DefaultValue(Quality.Medium), EditorDisplay(\"Quality\")")
|
||||
Quality ShadowsQuality = Quality::Medium;
|
||||
|
||||
/// <summary>
|
||||
/// The shadow maps quality (textures resolution).
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(1310), DefaultValue(Quality.Medium), EditorDisplay(\"Quality\")")
|
||||
Quality ShadowMapsQuality = Quality::Medium;
|
||||
|
||||
/// <summary>
|
||||
/// Enables cascades splits blending for directional light shadows.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(1320), DefaultValue(false), EditorDisplay(\"Quality\", \"Allow CSM Blending\")")
|
||||
bool AllowCSMBlending = false;
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instance of the settings asset (default value if missing). Object returned by this method is always loaded with valid data to use.
|
||||
/// </summary>
|
||||
static GraphicsSettings* Get();
|
||||
|
||||
// [SettingsBase]
|
||||
void Apply() override;
|
||||
|
||||
void RestoreDefault() final override
|
||||
{
|
||||
UseVSync = false;
|
||||
AAQuality = Quality::Medium;
|
||||
SSRQuality = Quality::Medium;
|
||||
SSAOQuality = Quality::Medium;
|
||||
VolumetricFogQuality = Quality::High;
|
||||
ShadowsQuality = Quality::Medium;
|
||||
ShadowMapsQuality = Quality::Medium;
|
||||
AllowCSMBlending = false;
|
||||
}
|
||||
|
||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) final override
|
||||
{
|
||||
DESERIALIZE(UseVSync);
|
||||
|
||||
@@ -7,8 +7,9 @@
|
||||
/// <summary>
|
||||
/// Layers and objects tags settings.
|
||||
/// </summary>
|
||||
class LayersAndTagsSettings : public SettingsBase<LayersAndTagsSettings>
|
||||
API_CLASS(sealed, Namespace="FlaxEditor.Content.Settings") class FLAXENGINE_API LayersAndTagsSettings : public SettingsBase
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(LayersAndTagsSettings);
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
@@ -24,43 +25,11 @@ public:
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Gets or adds the tag (returns the tag index).
|
||||
/// Gets the instance of the settings asset (default value if missing). Object returned by this method is always loaded with valid data to use.
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <returns>The tag index.</returns>
|
||||
int32 GetOrAddTag(const String& tag)
|
||||
{
|
||||
int32 index = Tags.Find(tag);
|
||||
if (index == INVALID_INDEX)
|
||||
{
|
||||
index = Tags.Count();
|
||||
Tags.Add(tag);
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the amount of non empty layer names (from the beginning, trims the last ones).
|
||||
/// </summary>
|
||||
/// <returns>The layers count.</returns>
|
||||
int32 GetNonEmptyLayerNamesCount() const
|
||||
{
|
||||
int32 result = 31;
|
||||
while (result >= 0 && Layers[result].IsEmpty())
|
||||
result--;
|
||||
return result + 1;
|
||||
}
|
||||
|
||||
public:
|
||||
static LayersAndTagsSettings* Get();
|
||||
|
||||
// [SettingsBase]
|
||||
void RestoreDefault() override
|
||||
{
|
||||
Tags.Clear();
|
||||
for (int32 i = 0; i < 32; i++)
|
||||
Layers[i].Clear();
|
||||
}
|
||||
|
||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) final override
|
||||
{
|
||||
const auto tags = stream.FindMember("Tags");
|
||||
|
||||
@@ -2,81 +2,46 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "Engine/Core/Singleton.h"
|
||||
#include "Engine/Core/Collections/Array.h"
|
||||
#include "Engine/Serialization/ISerializable.h"
|
||||
|
||||
/// <summary>
|
||||
/// Base class for all global settings containers for the engine. Helps to apply, store and expose properties to engine/game.
|
||||
/// </summary>
|
||||
class FLAXENGINE_API Settings
|
||||
API_CLASS(Abstract) class FLAXENGINE_API SettingsBase : public ISerializable
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(SettingsBase);
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// The settings containers.
|
||||
/// </summary>
|
||||
static Array<Settings*> Containers;
|
||||
|
||||
/// <summary>
|
||||
/// Restores the default settings for all the registered containers.
|
||||
/// </summary>
|
||||
static void RestoreDefaultAll()
|
||||
{
|
||||
for (int32 i = 0; i < Containers.Count(); i++)
|
||||
Containers[i]->RestoreDefault();
|
||||
}
|
||||
|
||||
private:
|
||||
|
||||
// Disable copy/move
|
||||
Settings(const Settings&) = delete;
|
||||
Settings& operator=(const Settings&) = delete;
|
||||
|
||||
protected:
|
||||
|
||||
Settings()
|
||||
{
|
||||
Containers.Add(this);
|
||||
}
|
||||
|
||||
public:
|
||||
|
||||
virtual ~Settings() = default;
|
||||
|
||||
public:
|
||||
|
||||
typedef ISerializable::DeserializeStream DeserializeStream;
|
||||
|
||||
/// <summary>
|
||||
/// Applies the settings to the target services.
|
||||
/// Applies the settings to the target system.
|
||||
/// </summary>
|
||||
virtual void Apply()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Restores the default settings.
|
||||
/// </summary>
|
||||
virtual void RestoreDefault() = 0;
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Deserializes the settings container.
|
||||
/// </summary>
|
||||
/// <param name="stream">The input data stream.</param>
|
||||
/// <param name="modifier">The deserialization modifier object. Always valid.</param>
|
||||
virtual void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) = 0;
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Base class for all global settings containers for the engine. Helps to apply, store and expose properties to engine/game.
|
||||
/// </summary>
|
||||
template<class T>
|
||||
class SettingsBase : public Settings, public Singleton<T>
|
||||
{
|
||||
protected:
|
||||
|
||||
SettingsBase()
|
||||
// [ISerializable]
|
||||
void Serialize(SerializeStream& stream, const void* otherObj) override
|
||||
{
|
||||
// Not supported (Editor C# edits settings data)
|
||||
}
|
||||
};
|
||||
|
||||
// Helper utility define for settings getter implementation code
|
||||
#define IMPLEMENT_SETTINGS_GETTER(type, field) \
|
||||
type* type::Get() \
|
||||
{ \
|
||||
static type DefaultInstance; \
|
||||
type* result = &DefaultInstance; \
|
||||
const auto gameSettings = GameSettings::Get(); \
|
||||
if (gameSettings) \
|
||||
{ \
|
||||
const auto asset = Content::Load<JsonAsset>(gameSettings->field); \
|
||||
if (asset && asset->Instance && asset->InstanceType == type::TypeInitializer) \
|
||||
{ \
|
||||
result = static_cast<type*>(asset->Instance); \
|
||||
} \
|
||||
} \
|
||||
return result; \
|
||||
}
|
||||
|
||||
@@ -3,60 +3,53 @@
|
||||
#pragma once
|
||||
|
||||
#include "Engine/Core/Config/Settings.h"
|
||||
#include "Engine/Serialization/Serialization.h"
|
||||
|
||||
/// <summary>
|
||||
/// Time and game simulation settings container.
|
||||
/// </summary>
|
||||
class TimeSettings : public SettingsBase<TimeSettings>
|
||||
API_CLASS(sealed, Namespace="FlaxEditor.Content.Settings") class FLAXENGINE_API TimeSettings : public SettingsBase
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(TimeSettings);
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// The target amount of the game logic updates per second (script updates frequency).
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(1), DefaultValue(30.0f), Limit(0, 1000), EditorDisplay(\"General\", \"Update FPS\")")
|
||||
float UpdateFPS = 30.0f;
|
||||
|
||||
/// <summary>
|
||||
/// The target amount of the physics simulation updates per second (also fixed updates frequency).
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(2), DefaultValue(60.0f), Limit(0, 1000), EditorDisplay(\"General\", \"Physics FPS\")")
|
||||
float PhysicsFPS = 60.0f;
|
||||
|
||||
/// <summary>
|
||||
/// The target amount of the frames rendered per second (actual game FPS).
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(3), DefaultValue(60.0f), Limit(0, 1000), EditorDisplay(\"General\", \"Draw FPS\")")
|
||||
float DrawFPS = 60.0f;
|
||||
|
||||
/// <summary>
|
||||
/// The game time scale factor. Default is 1.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(10), DefaultValue(1.0f), Limit(0, 1000.0f, 0.1f), EditorDisplay(\"General\")")
|
||||
float TimeScale = 1.0f;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum allowed delta time (in seconds) for the game logic update step.
|
||||
/// </summary>
|
||||
float MaxUpdateDeltaTime = (1.0f / 10.0f);
|
||||
API_FIELD(Attributes="EditorOrder(20), DefaultValue(0.1f), Limit(0.1f, 1000.0f, 0.01f), EditorDisplay(\"General\")")
|
||||
float MaxUpdateDeltaTime = 0.1f;
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instance of the settings asset (default value if missing). Object returned by this method is always loaded with valid data to use.
|
||||
/// </summary>
|
||||
static TimeSettings* Get();
|
||||
|
||||
// [SettingsBase]
|
||||
void Apply() override;
|
||||
|
||||
void RestoreDefault() override
|
||||
{
|
||||
UpdateFPS = 30.0f;
|
||||
PhysicsFPS = 60.0f;
|
||||
DrawFPS = 60.0f;
|
||||
TimeScale = 1.0f;
|
||||
MaxUpdateDeltaTime = 1.0f / 10.0f;
|
||||
}
|
||||
|
||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) final override
|
||||
{
|
||||
DESERIALIZE(UpdateFPS);
|
||||
DESERIALIZE(PhysicsFPS);
|
||||
DESERIALIZE(DrawFPS);
|
||||
DESERIALIZE(TimeScale);
|
||||
DESERIALIZE(MaxUpdateDeltaTime);
|
||||
}
|
||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) final override;
|
||||
};
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
void Math::SinCos(float angle, float& sine, float& cosine)
|
||||
{
|
||||
sine = sin(angle);
|
||||
cosine = cos(angle);
|
||||
sine = Math::Sin(angle);
|
||||
cosine = Math::Cos(angle);
|
||||
}
|
||||
|
||||
uint32 Math::FloorLog2(uint32 value)
|
||||
|
||||
@@ -119,7 +119,10 @@ bool GameBase::Init()
|
||||
}
|
||||
|
||||
// Preload first scene asset data
|
||||
GameBaseImpl::FirstScene = GameSettings::FirstScene;
|
||||
const auto gameSettings = GameSettings::Get();
|
||||
if (!gameSettings)
|
||||
return true;
|
||||
GameBaseImpl::FirstScene = gameSettings->FirstScene;
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -261,8 +264,8 @@ void GameBaseImpl::OnSplashScreenEnd()
|
||||
|
||||
// Load the first scene
|
||||
LOG(Info, "Loading the first scene");
|
||||
const auto sceneId = FirstScene ? FirstScene.GetID() : Guid::Empty;
|
||||
FirstScene.Unlink();
|
||||
const auto sceneId = GameSettings::FirstScene;
|
||||
if (Level::LoadSceneAsync(sceneId))
|
||||
{
|
||||
LOG(Fatal, "Cannot load the first scene.");
|
||||
|
||||
@@ -51,6 +51,9 @@
|
||||
namespace EngineImpl
|
||||
{
|
||||
bool IsReady = false;
|
||||
#if !USE_EDITOR
|
||||
bool RunInBackground = false;
|
||||
#endif
|
||||
String CommandLine = nullptr;
|
||||
int32 Fps = 0, FpsAccumulatedFrames = 0;
|
||||
double FpsAccumulated = 0.0;
|
||||
@@ -133,6 +136,9 @@ int32 Engine::Main(const Char* cmdLine)
|
||||
Platform::BeforeRun();
|
||||
EngineImpl::InitMainWindow();
|
||||
Application::BeforeRun();
|
||||
#if !USE_EDITOR && (PLATFORM_WINDOWS || PLATFORM_LINUX)
|
||||
EngineImpl::RunInBackground = PlatformSettings::Get()->RunInBackground;
|
||||
#endif
|
||||
Log::Logger::WriteFloor();
|
||||
LOG_FLUSH();
|
||||
Time::OnBeforeRun();
|
||||
@@ -279,11 +285,7 @@ void Engine::OnUpdate()
|
||||
bool isGameRunning = true;
|
||||
if (mainWindow && !mainWindow->IsFocused())
|
||||
{
|
||||
#if PLATFORM_WINDOWS || PLATFORM_LINUX
|
||||
isGameRunning = PlatformSettings::Instance()->RunInBackground;
|
||||
#else
|
||||
isGameRunning = false;
|
||||
#endif
|
||||
isGameRunning = EngineImpl::RunInBackground;
|
||||
}
|
||||
Time::SetGamePaused(!isGameRunning);
|
||||
#endif
|
||||
@@ -393,8 +395,11 @@ const String& Engine::GetCommandLine()
|
||||
|
||||
JsonAsset* Engine::GetCustomSettings(const StringView& key)
|
||||
{
|
||||
const auto settings = GameSettings::Get();
|
||||
if (!settings)
|
||||
return nullptr;
|
||||
Guid assetId = Guid::Empty;
|
||||
GameSettings::CustomSettings.TryGet(key, assetId);
|
||||
settings->CustomSettings.TryGet(key, assetId);
|
||||
return Content::LoadAsync<JsonAsset>(assetId);
|
||||
}
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ void LinuxGame::InitMainWindowSettings(CreateWindowSettings& settings)
|
||||
{
|
||||
// TODO: restore window size and fullscreen mode from the cached local settings saved after previous session
|
||||
|
||||
const auto platformSettings = LinuxPlatformSettings::Instance();
|
||||
const auto platformSettings = LinuxPlatformSettings::Get();
|
||||
auto windowMode = platformSettings->WindowMode;
|
||||
|
||||
// Use command line switches
|
||||
@@ -54,7 +54,7 @@ void LinuxGame::InitMainWindowSettings(CreateWindowSettings& settings)
|
||||
|
||||
bool LinuxGame::Init()
|
||||
{
|
||||
const auto platformSettings = LinuxPlatformSettings::Instance();
|
||||
const auto platformSettings = LinuxPlatformSettings::Get();
|
||||
|
||||
// Create mutex if need to
|
||||
if (platformSettings->ForceSingleInstance)
|
||||
|
||||
@@ -3,17 +3,19 @@
|
||||
#include "Time.h"
|
||||
#include "EngineService.h"
|
||||
#include "Engine/Core/Math/Math.h"
|
||||
#include "Engine/Core/Config/TimeSettings.h"
|
||||
#include "Engine/Platform/Platform.h"
|
||||
#include "Engine/Physics/PhysicsSettings.h"
|
||||
#include "Engine/Core/Config/TimeSettings.h"
|
||||
#include "Engine/Serialization/Serialization.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
bool FixedDeltaTimeEnable;
|
||||
float FixedDeltaTimeValue;
|
||||
float MaxUpdateDeltaTime = 0.1f;
|
||||
}
|
||||
|
||||
bool Time::_gamePaused = false;
|
||||
float Time::_physicsMaxDeltaTime = 0.1f;
|
||||
DateTime Time::StartupTime;
|
||||
float Time::UpdateFPS = 30.0f;
|
||||
float Time::PhysicsFPS = 60.0f;
|
||||
@@ -43,6 +45,24 @@ public:
|
||||
|
||||
TimeService TimeServiceInstance;
|
||||
|
||||
void TimeSettings::Apply()
|
||||
{
|
||||
Time::UpdateFPS = UpdateFPS;
|
||||
Time::PhysicsFPS = PhysicsFPS;
|
||||
Time::DrawFPS = DrawFPS;
|
||||
Time::TimeScale = TimeScale;
|
||||
::MaxUpdateDeltaTime = MaxUpdateDeltaTime;
|
||||
}
|
||||
|
||||
void TimeSettings::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier)
|
||||
{
|
||||
DESERIALIZE(UpdateFPS);
|
||||
DESERIALIZE(PhysicsFPS);
|
||||
DESERIALIZE(DrawFPS);
|
||||
DESERIALIZE(TimeScale);
|
||||
DESERIALIZE(MaxUpdateDeltaTime);
|
||||
}
|
||||
|
||||
void Time::TickData::OnBeforeRun(float targetFps, double currentTime)
|
||||
{
|
||||
Time = UnscaledTime = TimeSpan::Zero();
|
||||
@@ -219,7 +239,7 @@ void Time::OnBeforeRun()
|
||||
|
||||
bool Time::OnBeginUpdate()
|
||||
{
|
||||
if (Update.OnTickBegin(UpdateFPS, TimeSettings::Instance()->MaxUpdateDeltaTime))
|
||||
if (Update.OnTickBegin(UpdateFPS, MaxUpdateDeltaTime))
|
||||
{
|
||||
Current = &Update;
|
||||
return true;
|
||||
@@ -229,7 +249,7 @@ bool Time::OnBeginUpdate()
|
||||
|
||||
bool Time::OnBeginPhysics()
|
||||
{
|
||||
if (Physics.OnTickBegin(PhysicsFPS, PhysicsSettings::Instance()->MaxDeltaTime))
|
||||
if (Physics.OnTickBegin(PhysicsFPS, _physicsMaxDeltaTime))
|
||||
{
|
||||
Current = &Physics;
|
||||
return true;
|
||||
|
||||
@@ -15,6 +15,7 @@ API_CLASS(Static) class FLAXENGINE_API Time
|
||||
DECLARE_SCRIPTING_TYPE_NO_SPAWN(Time);
|
||||
friend class Engine;
|
||||
friend class TimeService;
|
||||
friend class PhysicsSettings;
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
@@ -100,6 +101,7 @@ public:
|
||||
private:
|
||||
|
||||
static bool _gamePaused;
|
||||
static float _physicsMaxDeltaTime;
|
||||
|
||||
public:
|
||||
|
||||
|
||||
@@ -11,7 +11,7 @@ void WindowsGame::InitMainWindowSettings(CreateWindowSettings& settings)
|
||||
{
|
||||
// TODO: restore window size and fullscreen mode from the cached local settings saved after previous session
|
||||
|
||||
const auto platformSettings = WindowsPlatformSettings::Instance();
|
||||
const auto platformSettings = WindowsPlatformSettings::Get();
|
||||
auto windowMode = platformSettings->WindowMode;
|
||||
|
||||
// Use command line switches
|
||||
@@ -45,7 +45,7 @@ void WindowsGame::InitMainWindowSettings(CreateWindowSettings& settings)
|
||||
|
||||
bool WindowsGame::Init()
|
||||
{
|
||||
const auto platformSettings = WindowsPlatformSettings::Instance();
|
||||
const auto platformSettings = WindowsPlatformSettings::Get();
|
||||
|
||||
// Create mutex if need to
|
||||
if (platformSettings->ForceSingleInstance)
|
||||
|
||||
@@ -91,7 +91,7 @@ GPUDevice* GPUDeviceDX11::Create()
|
||||
else if (CommandLine::Options.D3D11)
|
||||
maxAllowedFeatureLevel = D3D_FEATURE_LEVEL_11_0;
|
||||
#if !USE_EDITOR && PLATFORM_WINDOWS
|
||||
auto winSettings = WindowsPlatformSettings::Instance();
|
||||
auto winSettings = WindowsPlatformSettings::Get();
|
||||
if (!winSettings->SupportDX11 && !winSettings->SupportDX10)
|
||||
{
|
||||
// Skip if there is no support
|
||||
|
||||
@@ -45,7 +45,7 @@ GPUDevice* GPUDeviceDX12::Create()
|
||||
selectedAdapter.Description.VendorId = GPU_VENDOR_ID_AMD;
|
||||
#else
|
||||
#if !USE_EDITOR && PLATFORM_WINDOWS
|
||||
auto winSettings = WindowsPlatformSettings::Instance();
|
||||
auto winSettings = WindowsPlatformSettings::Get();
|
||||
if (!winSettings->SupportDX12)
|
||||
{
|
||||
// Skip if there is no support
|
||||
|
||||
@@ -1076,7 +1076,7 @@ GPUDeviceVulkan::GPUDeviceVulkan(ShaderProfile shaderProfile, GPUAdapterVulkan*
|
||||
GPUDevice* GPUDeviceVulkan::Create()
|
||||
{
|
||||
#if !USE_EDITOR && (PLATFORM_WINDOWS || PLATFORM_LINUX)
|
||||
auto settings = PlatformSettings::Instance();
|
||||
auto settings = PlatformSettings::Get();
|
||||
if (!settings->SupportVulkan)
|
||||
{
|
||||
// Skip if there is no support
|
||||
|
||||
@@ -98,6 +98,12 @@ Delegate<StringView> Input::ActionTriggered;
|
||||
Array<ActionConfig> Input::ActionMappings;
|
||||
Array<AxisConfig> Input::AxisMappings;
|
||||
|
||||
void InputSettings::Apply()
|
||||
{
|
||||
Input::ActionMappings = ActionMappings;
|
||||
Input::AxisMappings = AxisMappings;
|
||||
}
|
||||
|
||||
int32 Input::GetGamepadsCount()
|
||||
{
|
||||
return Gamepads.Count();
|
||||
|
||||
@@ -21,7 +21,6 @@ class InputDevice;
|
||||
API_CLASS(Static) class FLAXENGINE_API Input
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_NO_SPAWN(Input);
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Gets the mouse (null if platform does not support mouse or it is not connected).
|
||||
|
||||
@@ -5,14 +5,13 @@
|
||||
#include "Engine/Core/Config/Settings.h"
|
||||
#include "Engine/Serialization/JsonTools.h"
|
||||
#include "VirtualInput.h"
|
||||
#include "Input.h"
|
||||
|
||||
/// <summary>
|
||||
/// Input settings container.
|
||||
/// </summary>
|
||||
/// <seealso cref="SettingsBase{InputSettings}" />
|
||||
class InputSettings : public SettingsBase<InputSettings>
|
||||
API_CLASS(sealed, Namespace="FlaxEditor.Content.Settings") class FLAXENGINE_API InputSettings : public SettingsBase
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(InputSettings);
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
@@ -27,19 +26,14 @@ public:
|
||||
|
||||
public:
|
||||
|
||||
// [SettingsBase]
|
||||
void Apply() override
|
||||
{
|
||||
Input::ActionMappings = ActionMappings;
|
||||
Input::AxisMappings = AxisMappings;
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instance of the settings asset (default value if missing). Object returned by this method is always loaded with valid data to use.
|
||||
/// </summary>
|
||||
static InputSettings* Get();
|
||||
|
||||
// [SettingsBase]
|
||||
void Apply() override;
|
||||
|
||||
void RestoreDefault() override
|
||||
{
|
||||
ActionMappings.Resize(0);
|
||||
AxisMappings.Resize(0);
|
||||
}
|
||||
|
||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) final override
|
||||
{
|
||||
const auto actionMappings = stream.FindMember("ActionMappings");
|
||||
|
||||
@@ -8,7 +8,6 @@
|
||||
#include "Prefabs/Prefab.h"
|
||||
#include "Prefabs/PrefabManager.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Core/Config/LayersTagsSettings.h"
|
||||
#include "Engine/Scripting/Script.h"
|
||||
#include "Engine/Scripting/ManagedCLR/MClass.h"
|
||||
#include "Engine/Threading/Threading.h"
|
||||
@@ -386,21 +385,19 @@ Actor* Actor::GetChildByPrefabObjectId(const Guid& prefabObjectId) const
|
||||
|
||||
bool Actor::HasTag(const StringView& tag) const
|
||||
{
|
||||
return HasTag() && tag == LayersAndTagsSettings::Instance()->Tags[_tag];
|
||||
return HasTag() && tag == Level::Tags[_tag];
|
||||
}
|
||||
|
||||
const String& Actor::GetLayerName() const
|
||||
{
|
||||
const auto settings = LayersAndTagsSettings::Instance();
|
||||
return settings->Layers[_layer];
|
||||
return Level::Layers[_layer];
|
||||
}
|
||||
|
||||
const String& Actor::GetTag() const
|
||||
{
|
||||
if (HasTag())
|
||||
{
|
||||
const auto settings = LayersAndTagsSettings::Instance();
|
||||
return settings->Tags[_tag];
|
||||
return Level::Tags[_tag];
|
||||
}
|
||||
return String::Empty;
|
||||
}
|
||||
@@ -420,13 +417,13 @@ void Actor::SetTagIndex(int32 tagIndex)
|
||||
if (tagIndex == ACTOR_TAG_INVALID)
|
||||
{
|
||||
}
|
||||
else if (LayersAndTagsSettings::Instance()->Tags.IsEmpty())
|
||||
else if (Level::Tags.IsEmpty())
|
||||
{
|
||||
tagIndex = ACTOR_TAG_INVALID;
|
||||
}
|
||||
else
|
||||
{
|
||||
tagIndex = tagIndex < 0 ? ACTOR_TAG_INVALID : Math::Min(tagIndex, LayersAndTagsSettings::Instance()->Tags.Count() - 1);
|
||||
tagIndex = tagIndex < 0 ? ACTOR_TAG_INVALID : Math::Min(tagIndex, Level::Tags.Count() - 1);
|
||||
}
|
||||
if (tagIndex == _tag)
|
||||
return;
|
||||
@@ -444,7 +441,7 @@ void Actor::SetTag(const StringView& tagName)
|
||||
}
|
||||
else
|
||||
{
|
||||
tagIndex = LayersAndTagsSettings::Instance()->Tags.Find(tagName);
|
||||
tagIndex = Level::Tags.Find(tagName);
|
||||
if (tagIndex == -1)
|
||||
{
|
||||
LOG(Error, "Cannot change actor tag. Given value is invalid.");
|
||||
@@ -971,7 +968,7 @@ void Actor::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier)
|
||||
if (tag->value.IsString() && tag->value.GetStringLength())
|
||||
{
|
||||
const String tagName = tag->value.GetText();
|
||||
_tag = LayersAndTagsSettings::Instance()->GetOrAddTag(tagName);
|
||||
_tag = Level::GetOrAddTag(tagName);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -9,6 +9,7 @@
|
||||
#include "Engine/Core/Cache.h"
|
||||
#include "Engine/Core/Collections/CollectionPoolCache.h"
|
||||
#include "Engine/Core/ObjectsRemovalService.h"
|
||||
#include "Engine/Core/Config/LayersTagsSettings.h"
|
||||
#include "Engine/Debug/Exceptions/ArgumentException.h"
|
||||
#include "Engine/Debug/Exceptions/ArgumentNullException.h"
|
||||
#include "Engine/Debug/Exceptions/InvalidOperationException.h"
|
||||
@@ -97,6 +98,7 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
bool Init() override;
|
||||
void Update() override;
|
||||
void LateUpdate() override;
|
||||
void FixedUpdate() override;
|
||||
@@ -124,6 +126,8 @@ Delegate<Scene*, const Guid&> Level::SceneUnloaded;
|
||||
Action Level::ScriptsReloadStart;
|
||||
Action Level::ScriptsReload;
|
||||
Action Level::ScriptsReloadEnd;
|
||||
Array<String> Level::Tags;
|
||||
String Level::Layers[32];
|
||||
|
||||
bool LevelImpl::spawnActor(Actor* actor, Actor* parent)
|
||||
{
|
||||
@@ -158,6 +162,15 @@ bool LevelImpl::deleteActor(Actor* actor)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool LevelService::Init()
|
||||
{
|
||||
auto& settings = *LayersAndTagsSettings::Get();
|
||||
Level::Tags = settings.Tags;
|
||||
for (int32 i = 0; i < ARRAY_COUNT(Level::Layers); i++)
|
||||
Level::Layers[i] = settings.Layers[i];
|
||||
return false;
|
||||
}
|
||||
|
||||
void LevelService::Update()
|
||||
{
|
||||
PROFILE_CPU();
|
||||
@@ -642,6 +655,25 @@ void LevelImpl::CallSceneEvent(SceneEventType eventType, Scene* scene, Guid scen
|
||||
}
|
||||
}
|
||||
|
||||
int32 Level::GetOrAddTag(const StringView& tag)
|
||||
{
|
||||
int32 index = Tags.Find(tag);
|
||||
if (index == INVALID_INDEX)
|
||||
{
|
||||
index = Tags.Count();
|
||||
Tags.AddOne() = tag;
|
||||
}
|
||||
return index;
|
||||
}
|
||||
|
||||
int32 Level::GetNonEmptyLayerNamesCount()
|
||||
{
|
||||
int32 result = 31;
|
||||
while (result >= 0 && Layers[result].IsEmpty())
|
||||
result--;
|
||||
return result + 1;
|
||||
}
|
||||
|
||||
void Level::callActorEvent(ActorEventType eventType, Actor* a, Actor* b)
|
||||
{
|
||||
PROFILE_CPU();
|
||||
|
||||
@@ -420,6 +420,31 @@ public:
|
||||
/// <param name="output">Output array with only parents</param>
|
||||
static void ConstructParentActorsTreeList(const Array<Actor*>& input, Array<Actor*>& output);
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// The tags names.
|
||||
/// </summary>
|
||||
static Array<String> Tags;
|
||||
|
||||
/// <summary>
|
||||
/// The layers names.
|
||||
/// </summary>
|
||||
static String Layers[32];
|
||||
|
||||
/// <summary>
|
||||
/// Gets or adds the tag (returns the tag index).
|
||||
/// </summary>
|
||||
/// <param name="tag">The tag.</param>
|
||||
/// <returns>The tag index.</returns>
|
||||
static int32 GetOrAddTag(const StringView& tag);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the amount of non empty layer names (from the beginning, trims the last ones).
|
||||
/// </summary>
|
||||
/// <returns>The layers count.</returns>
|
||||
static int32 GetNonEmptyLayerNamesCount();
|
||||
|
||||
private:
|
||||
|
||||
// Actor API
|
||||
|
||||
@@ -461,13 +461,13 @@ bool GenerateTile(NavigationScene* scene, int32 x, int32 y, BoundingBox& tileBou
|
||||
|
||||
float GetTileSize()
|
||||
{
|
||||
auto& settings = *NavigationSettings::Instance();
|
||||
auto& settings = *NavigationSettings::Get();
|
||||
return settings.CellSize * settings.TileSize;
|
||||
}
|
||||
|
||||
void InitConfig(rcConfig& config)
|
||||
{
|
||||
auto& settings = *NavigationSettings::Instance();
|
||||
auto& settings = *NavigationSettings::Get();
|
||||
|
||||
config.cs = settings.CellSize;
|
||||
config.ch = settings.CellHeight;
|
||||
|
||||
@@ -1,8 +1,12 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "Navigation.h"
|
||||
#include "NavigationSettings.h"
|
||||
#include "NavMeshRuntime.h"
|
||||
#include "NavMeshBuilder.h"
|
||||
#include "Engine/Core/Config/GameSettings.h"
|
||||
#include "Engine/Content/Content.h"
|
||||
#include "Engine/Content/JsonAsset.h"
|
||||
#include "Engine/Threading/Threading.h"
|
||||
#include "Engine/Level/Scene/Scene.h"
|
||||
#include "Engine/Engine/EngineService.h"
|
||||
@@ -55,6 +59,8 @@ void* rcAllocDefault(size_t size, rcAllocHint)
|
||||
return Allocator::Allocate(size);
|
||||
}
|
||||
|
||||
IMPLEMENT_SETTINGS_GETTER(NavigationSettings, Navigation);
|
||||
|
||||
bool NavigationService::Init()
|
||||
{
|
||||
// Link memory allocation calls to use engine default allocator
|
||||
|
||||
8
Source/Engine/Navigation/NavigationSettings.cs
Normal file
8
Source/Engine/Navigation/NavigationSettings.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
// Copyright (c) 2012-2020 Wojciech Figat. All rights reserved.
|
||||
|
||||
namespace FlaxEditor.Content.Settings
|
||||
{
|
||||
partial class NavigationSettings
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -9,7 +9,7 @@
|
||||
/// <summary>
|
||||
/// The navigation system settings container.
|
||||
/// </summary>
|
||||
API_CLASS(sealed, Namespace="FlaxEditor.Content.Settings") class FLAXENGINE_API NavigationSettings : public SettingsBase<NavigationSettings>
|
||||
API_CLASS(sealed, Namespace="FlaxEditor.Content.Settings") class FLAXENGINE_API NavigationSettings : public SettingsBase
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(NavigationSettings);
|
||||
public:
|
||||
@@ -94,24 +94,12 @@ public:
|
||||
|
||||
public:
|
||||
|
||||
// [SettingsBase]
|
||||
void RestoreDefault() final override
|
||||
{
|
||||
CellHeight = 10.0f;
|
||||
CellSize = 30.0f;
|
||||
TileSize = 64;
|
||||
MinRegionArea = 0;
|
||||
MergeRegionArea = 20;
|
||||
MaxEdgeLen = 1200.0f;
|
||||
MaxEdgeError = 1.3f;
|
||||
DetailSamplingDist = 600.0f;
|
||||
MaxDetailSamplingError = 1.0f;
|
||||
WalkableRadius = 34.0f;
|
||||
WalkableHeight = 144.0f;
|
||||
WalkableMaxClimb = 35.0f;
|
||||
WalkableMaxSlopeAngle = 60.0f;
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instance of the settings asset (default value if missing). Object returned by this method is always loaded with valid data to use.
|
||||
/// </summary>
|
||||
static NavigationSettings* Get();
|
||||
|
||||
// [SettingsBase]
|
||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) final override
|
||||
{
|
||||
DESERIALIZE(CellHeight);
|
||||
|
||||
@@ -232,7 +232,7 @@ void Collider::UpdateLayerBits()
|
||||
filterData.word0 = GetLayerMask();
|
||||
|
||||
// Own layer mask
|
||||
filterData.word1 = PhysicsSettings::Instance()->LayerMasks[GetLayer()];
|
||||
filterData.word1 = Physics::LayerMasks[GetLayer()];
|
||||
|
||||
_shape->setSimulationFilterData(filterData);
|
||||
_shape->setQueryFilterData(filterData);
|
||||
|
||||
@@ -1,52 +0,0 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "PhysicalMaterial.h"
|
||||
#include "PhysicsSettings.h"
|
||||
#include "Physics.h"
|
||||
#include <ThirdParty/PhysX/PxPhysics.h>
|
||||
#include <ThirdParty/PhysX/PxMaterial.h>
|
||||
|
||||
PhysicalMaterial::PhysicalMaterial()
|
||||
: _material(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
PhysicalMaterial::~PhysicalMaterial()
|
||||
{
|
||||
if (_material)
|
||||
{
|
||||
Physics::RemoveMaterial(_material);
|
||||
}
|
||||
}
|
||||
|
||||
PxMaterial* PhysicalMaterial::GetPhysXMaterial()
|
||||
{
|
||||
if (_material == nullptr && CPhysX)
|
||||
{
|
||||
_material = CPhysX->createMaterial(Friction, Friction, Restitution);
|
||||
_material->userData = this;
|
||||
|
||||
const PhysicsCombineMode useFrictionCombineMode = (OverrideFrictionCombineMode ? FrictionCombineMode : PhysicsSettings::Instance()->FrictionCombineMode);
|
||||
_material->setFrictionCombineMode(static_cast<PxCombineMode::Enum>(useFrictionCombineMode));
|
||||
|
||||
const PhysicsCombineMode useRestitutionCombineMode = (OverrideRestitutionCombineMode ? RestitutionCombineMode : PhysicsSettings::Instance()->RestitutionCombineMode);
|
||||
_material->setRestitutionCombineMode(static_cast<PxCombineMode::Enum>(useRestitutionCombineMode));
|
||||
}
|
||||
|
||||
return _material;
|
||||
}
|
||||
|
||||
void PhysicalMaterial::UpdatePhysXMaterial()
|
||||
{
|
||||
if (_material != nullptr)
|
||||
{
|
||||
_material->setStaticFriction(Friction);
|
||||
_material->setDynamicFriction(Friction);
|
||||
const PhysicsCombineMode useFrictionCombineMode = (OverrideFrictionCombineMode ? FrictionCombineMode : PhysicsSettings::Instance()->FrictionCombineMode);
|
||||
_material->setFrictionCombineMode(static_cast<PxCombineMode::Enum>(useFrictionCombineMode));
|
||||
|
||||
_material->setRestitution(Restitution);
|
||||
const PhysicsCombineMode useRestitutionCombineMode = (OverrideRestitutionCombineMode ? RestitutionCombineMode : PhysicsSettings::Instance()->RestitutionCombineMode);
|
||||
_material->setRestitutionCombineMode(static_cast<PxCombineMode::Enum>(useRestitutionCombineMode));
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "Physics.h"
|
||||
#include "PhysicalMaterial.h"
|
||||
#include "Engine/Core/Log.h"
|
||||
#include "Engine/Threading/Threading.h"
|
||||
#include "Engine/Platform/CPUInfo.h"
|
||||
@@ -13,6 +14,8 @@
|
||||
#include "Engine/Profiler/ProfilerCPU.h"
|
||||
#include "Engine/Core/Memory/Memory.h"
|
||||
#include "Engine/Engine/EngineService.h"
|
||||
#include "Engine/Serialization/Serialization.h"
|
||||
#include "Engine/Engine/Time.h"
|
||||
#include <ThirdParty/PhysX/PxPhysicsAPI.h>
|
||||
#include <ThirdParty/PhysX/PxActor.h>
|
||||
#if WITH_PVD
|
||||
@@ -110,34 +113,43 @@ struct ActionData
|
||||
};
|
||||
|
||||
PxPhysics* CPhysX = nullptr;
|
||||
PhysXAllocator PhysXAllocatorCallback;
|
||||
PhysXError PhysXErrorCallback;
|
||||
PxSimulationFilterShader PhysXDefaultFilterShader = PxDefaultSimulationFilterShader;
|
||||
#if WITH_PVD
|
||||
PxPvd* CPVD = nullptr;
|
||||
#endif
|
||||
PxTolerancesScale ToleranceScale;
|
||||
SimulationEventCallback EventsCallback;
|
||||
void* ScratchMemory = nullptr;
|
||||
FixedStepper* Stepper = nullptr;
|
||||
CriticalSection FlushLocker;
|
||||
Array<PxActor*> NewActors;
|
||||
Array<ActionData> Actions;
|
||||
Array<PxActor*> DeadActors;
|
||||
Array<PxMaterial*> DeadMaterials;
|
||||
Array<PxBase*> _deadObjects;
|
||||
Array<PhysicsColliderActor*> DeadColliders;
|
||||
Array<Joint*> DeadJoints;
|
||||
bool _isDuringSimulation = false;
|
||||
PxFoundation* _foundation = nullptr;
|
||||
|
||||
namespace
|
||||
{
|
||||
PhysXAllocator PhysXAllocatorCallback;
|
||||
PhysXError PhysXErrorCallback;
|
||||
PxSimulationFilterShader PhysXDefaultFilterShader = PxDefaultSimulationFilterShader;
|
||||
PxTolerancesScale ToleranceScale;
|
||||
SimulationEventCallback EventsCallback;
|
||||
void* ScratchMemory = nullptr;
|
||||
FixedStepper* Stepper = nullptr;
|
||||
CriticalSection FlushLocker;
|
||||
Array<PxActor*> NewActors;
|
||||
Array<ActionData> Actions;
|
||||
Array<PxActor*> DeadActors;
|
||||
Array<PxMaterial*> DeadMaterials;
|
||||
Array<PxBase*> _deadObjects;
|
||||
Array<PhysicsColliderActor*> DeadColliders;
|
||||
Array<Joint*> DeadJoints;
|
||||
bool _queriesHitTriggers = true;
|
||||
bool _isDuringSimulation = false;
|
||||
PhysicsCombineMode _frictionCombineMode = PhysicsCombineMode::Average;
|
||||
PhysicsCombineMode _restitutionCombineMode = PhysicsCombineMode::Average;
|
||||
PxFoundation* _foundation = nullptr;
|
||||
#if COMPILE_WITH_PHYSICS_COOKING
|
||||
PxCooking* Cooking = nullptr;
|
||||
PxCooking* Cooking = nullptr;
|
||||
#endif
|
||||
PxScene* PhysicsScene = nullptr;
|
||||
PxMaterial* DefaultMaterial = nullptr;
|
||||
PxControllerManager* ControllerManager = nullptr;
|
||||
PxCpuDispatcher* CpuDispatcher = nullptr;
|
||||
PxScene* PhysicsScene = nullptr;
|
||||
PxMaterial* DefaultMaterial = nullptr;
|
||||
PxControllerManager* ControllerManager = nullptr;
|
||||
PxCpuDispatcher* CpuDispatcher = nullptr;
|
||||
}
|
||||
|
||||
bool Physics::AutoSimulation = true;
|
||||
uint32 Physics::LayerMasks[32];
|
||||
|
||||
class PhysicsService : public EngineService
|
||||
{
|
||||
@@ -146,6 +158,8 @@ public:
|
||||
PhysicsService()
|
||||
: EngineService(TEXT("Physics"), 0)
|
||||
{
|
||||
for (int32 i = 0; i < 32; i++)
|
||||
Physics::LayerMasks[i] = MAX_uint32;
|
||||
}
|
||||
|
||||
bool Init() override;
|
||||
@@ -155,12 +169,146 @@ public:
|
||||
|
||||
PhysicsService PhysicsServiceInstance;
|
||||
|
||||
PxShapeFlags GetShapeFlags(bool isTrigger, bool isEnabled)
|
||||
{
|
||||
#if WITH_PVD
|
||||
PxShapeFlags flags = PxShapeFlag::eVISUALIZATION;
|
||||
#else
|
||||
PxShapeFlags flags = static_cast<PxShapeFlags>(0);
|
||||
#endif
|
||||
|
||||
if (isEnabled)
|
||||
{
|
||||
if (isTrigger)
|
||||
{
|
||||
flags |= PxShapeFlag::eTRIGGER_SHAPE;
|
||||
if (_queriesHitTriggers)
|
||||
flags |= PxShapeFlag::eSCENE_QUERY_SHAPE;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags = PxShapeFlag::eSIMULATION_SHAPE | PxShapeFlag::eSCENE_QUERY_SHAPE;
|
||||
}
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
|
||||
void PhysicsSettings::Apply()
|
||||
{
|
||||
Time::_physicsMaxDeltaTime = MaxDeltaTime;
|
||||
_queriesHitTriggers = QueriesHitTriggers;
|
||||
_frictionCombineMode = FrictionCombineMode;
|
||||
_restitutionCombineMode = RestitutionCombineMode;
|
||||
Platform::MemoryCopy(Physics::LayerMasks, LayerMasks, sizeof(LayerMasks));
|
||||
Physics::SetGravity(DefaultGravity);
|
||||
Physics::SetBounceThresholdVelocity(BounceThresholdVelocity);
|
||||
Physics::SetEnableCCD(!DisableCCD);
|
||||
|
||||
// TODO: setting eADAPTIVE_FORCE requires PxScene setup (physx docs: This flag is not mutable, and must be set in PxSceneDesc at scene creation.)
|
||||
// TODO: update all shapes filter data
|
||||
// TODO: update all shapes flags
|
||||
|
||||
/*
|
||||
{
|
||||
get all actors and then:
|
||||
|
||||
const PxU32 numShapes = actor->getNbShapes();
|
||||
PxShape** shapes = (PxShape**)SAMPLE_ALLOC(sizeof(PxShape*)*numShapes);
|
||||
actor->getShapes(shapes, numShapes);
|
||||
for (PxU32 i = 0; i < numShapes; i++)
|
||||
{
|
||||
..
|
||||
}
|
||||
SAMPLE_FREE(shapes);
|
||||
}*/
|
||||
}
|
||||
|
||||
PhysicsSettings::PhysicsSettings()
|
||||
{
|
||||
for (int32 i = 0; i < 32; i++)
|
||||
LayerMasks[i] = MAX_uint32;
|
||||
}
|
||||
|
||||
void PhysicsSettings::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier)
|
||||
{
|
||||
DESERIALIZE(DefaultGravity);
|
||||
DESERIALIZE(TriangleMeshTriangleMinAreaThreshold);
|
||||
DESERIALIZE(BounceThresholdVelocity);
|
||||
DESERIALIZE(FrictionCombineMode);
|
||||
DESERIALIZE(RestitutionCombineMode);
|
||||
DESERIALIZE(DisableCCD);
|
||||
DESERIALIZE(EnableAdaptiveForce);
|
||||
DESERIALIZE(MaxDeltaTime);
|
||||
DESERIALIZE(EnableSubstepping);
|
||||
DESERIALIZE(SubstepDeltaTime);
|
||||
DESERIALIZE(MaxSubsteps);
|
||||
DESERIALIZE(QueriesHitTriggers);
|
||||
DESERIALIZE(SupportCookingAtRuntime);
|
||||
|
||||
const auto layers = stream.FindMember("LayerMasks");
|
||||
if (layers != stream.MemberEnd())
|
||||
{
|
||||
auto& layersArray = layers->value;
|
||||
ASSERT(layersArray.IsArray());
|
||||
for (uint32 i = 0; i < layersArray.Size() && i < 32; i++)
|
||||
{
|
||||
LayerMasks[i] = layersArray[i].GetUint();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
PhysicalMaterial::PhysicalMaterial()
|
||||
: _material(nullptr)
|
||||
{
|
||||
}
|
||||
|
||||
PhysicalMaterial::~PhysicalMaterial()
|
||||
{
|
||||
if (_material)
|
||||
{
|
||||
Physics::RemoveMaterial(_material);
|
||||
}
|
||||
}
|
||||
|
||||
PxMaterial* PhysicalMaterial::GetPhysXMaterial()
|
||||
{
|
||||
if (_material == nullptr && CPhysX)
|
||||
{
|
||||
_material = CPhysX->createMaterial(Friction, Friction, Restitution);
|
||||
_material->userData = this;
|
||||
|
||||
const PhysicsCombineMode useFrictionCombineMode = OverrideFrictionCombineMode ? FrictionCombineMode : _frictionCombineMode;
|
||||
_material->setFrictionCombineMode(static_cast<PxCombineMode::Enum>(useFrictionCombineMode));
|
||||
|
||||
const PhysicsCombineMode useRestitutionCombineMode = OverrideRestitutionCombineMode ? RestitutionCombineMode : _restitutionCombineMode;
|
||||
_material->setRestitutionCombineMode(static_cast<PxCombineMode::Enum>(useRestitutionCombineMode));
|
||||
}
|
||||
|
||||
return _material;
|
||||
}
|
||||
|
||||
void PhysicalMaterial::UpdatePhysXMaterial()
|
||||
{
|
||||
if (_material != nullptr)
|
||||
{
|
||||
_material->setStaticFriction(Friction);
|
||||
_material->setDynamicFriction(Friction);
|
||||
const PhysicsCombineMode useFrictionCombineMode = OverrideFrictionCombineMode ? FrictionCombineMode : _frictionCombineMode;
|
||||
_material->setFrictionCombineMode(static_cast<PxCombineMode::Enum>(useFrictionCombineMode));
|
||||
|
||||
_material->setRestitution(Restitution);
|
||||
const PhysicsCombineMode useRestitutionCombineMode = OverrideRestitutionCombineMode ? RestitutionCombineMode : _restitutionCombineMode;
|
||||
_material->setRestitutionCombineMode(static_cast<PxCombineMode::Enum>(useRestitutionCombineMode));
|
||||
}
|
||||
}
|
||||
|
||||
bool PhysicsService::Init()
|
||||
{
|
||||
#define CHECK_INIT(value, msg) if(!value) { LOG(Error, msg); return true; }
|
||||
|
||||
auto cpuInfo = Platform::GetCPUInfo();
|
||||
auto settings = PhysicsSettings::Instance();
|
||||
auto& settings = *PhysicsSettings::Get();
|
||||
|
||||
// Send info
|
||||
LOG(Info, "Setup NVIDIA PhysX {0}.{1}.{2}", PX_PHYSICS_VERSION_MAJOR, PX_PHYSICS_VERSION_MINOR, PX_PHYSICS_VERSION_BUGFIX);
|
||||
@@ -220,7 +368,7 @@ bool PhysicsService::Init()
|
||||
#if COMPILE_WITH_PHYSICS_COOKING
|
||||
|
||||
#if !USE_EDITOR
|
||||
if (settings->SupportCookingAtRuntime)
|
||||
if (settings.SupportCookingAtRuntime)
|
||||
#endif
|
||||
{
|
||||
// Init cooking
|
||||
@@ -235,16 +383,16 @@ bool PhysicsService::Init()
|
||||
|
||||
// Create scene description
|
||||
PxSceneDesc sceneDesc(CPhysX->getTolerancesScale());
|
||||
sceneDesc.gravity = C2P(settings->DefaultGravity);
|
||||
sceneDesc.gravity = C2P(settings.DefaultGravity);
|
||||
sceneDesc.flags |= PxSceneFlag::eENABLE_ACTIVE_ACTORS;
|
||||
//sceneDesc.flags |= PxSceneFlag::eEXCLUDE_KINEMATICS_FROM_ACTIVE_ACTORS; // TODO: set it?
|
||||
if (!settings->DisableCCD)
|
||||
if (!settings.DisableCCD)
|
||||
sceneDesc.flags |= PxSceneFlag::eENABLE_CCD;
|
||||
if (settings->EnableAdaptiveForce)
|
||||
if (settings.EnableAdaptiveForce)
|
||||
sceneDesc.flags |= PxSceneFlag::eADAPTIVE_FORCE;
|
||||
sceneDesc.simulationEventCallback = &EventsCallback;
|
||||
sceneDesc.filterShader = PhysiXFilterShader;
|
||||
sceneDesc.bounceThresholdVelocity = settings->BounceThresholdVelocity;
|
||||
sceneDesc.bounceThresholdVelocity = settings.BounceThresholdVelocity;
|
||||
if (sceneDesc.cpuDispatcher == nullptr)
|
||||
{
|
||||
CpuDispatcher = PxDefaultCpuDispatcherCreate(Math::Clamp<uint32>(cpuInfo.ProcessorCoreCount - 1, 1, 4));
|
||||
@@ -366,7 +514,7 @@ void Physics::SetGravity(const Vector3& value)
|
||||
|
||||
bool Physics::GetEnableCCD()
|
||||
{
|
||||
return PhysicsScene ? (PhysicsScene->getFlags() & PxSceneFlag::eENABLE_CCD) == PxSceneFlag::eENABLE_CCD : !PhysicsSettings_DisableCCD;
|
||||
return PhysicsScene ? (PhysicsScene->getFlags() & PxSceneFlag::eENABLE_CCD) == PxSceneFlag::eENABLE_CCD : !PhysicsSettings::Get()->DisableCCD;
|
||||
}
|
||||
|
||||
void Physics::SetEnableCCD(const bool value)
|
||||
@@ -377,7 +525,7 @@ void Physics::SetEnableCCD(const bool value)
|
||||
|
||||
float Physics::GetBounceThresholdVelocity()
|
||||
{
|
||||
return PhysicsScene ? PhysicsScene->getBounceThresholdVelocity() : PhysicsSettings_BounceThresholdVelocity;
|
||||
return PhysicsScene ? PhysicsScene->getBounceThresholdVelocity() : PhysicsSettings::Get()->BounceThresholdVelocity;
|
||||
}
|
||||
|
||||
void Physics::SetBounceThresholdVelocity(const float value)
|
||||
@@ -390,13 +538,13 @@ void Physics::Simulate(float dt)
|
||||
{
|
||||
ASSERT(IsInMainThread() && !_isDuringSimulation);
|
||||
ASSERT(CPhysX);
|
||||
const auto settings = PhysicsSettings::Instance();
|
||||
const auto& settings = *PhysicsSettings::Get();
|
||||
|
||||
// Flush the old/new objects and the other requests before the simulation
|
||||
FlushRequests();
|
||||
|
||||
// Clamp delta
|
||||
dt = Math::Clamp(dt, 0.0f, settings->MaxDeltaTime);
|
||||
dt = Math::Clamp(dt, 0.0f, settings.MaxDeltaTime);
|
||||
|
||||
// Prepare util objects
|
||||
if (ScratchMemory == nullptr)
|
||||
@@ -407,10 +555,10 @@ void Physics::Simulate(float dt)
|
||||
{
|
||||
Stepper = New<FixedStepper>();
|
||||
}
|
||||
if (settings->EnableSubstepping)
|
||||
if (settings.EnableSubstepping)
|
||||
{
|
||||
// Use substeps
|
||||
Stepper->Setup(settings->SubstepDeltaTime, settings->MaxSubsteps);
|
||||
Stepper->Setup(settings.SubstepDeltaTime, settings.MaxSubsteps);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@@ -155,6 +155,11 @@ public:
|
||||
/// </summary>
|
||||
API_PROPERTY() static void SetBounceThresholdVelocity(float value);
|
||||
|
||||
/// <summary>
|
||||
/// The collision layers masks. Used to define layer-based collision detection.
|
||||
/// </summary>
|
||||
static uint32 LayerMasks[32];
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -1,82 +0,0 @@
|
||||
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
|
||||
|
||||
#include "PhysicsSettings.h"
|
||||
#include "Engine/Serialization/Serialization.h"
|
||||
#include "Physics.h"
|
||||
|
||||
void PhysicsSettings::Apply()
|
||||
{
|
||||
// Set simulation parameters
|
||||
Physics::SetGravity(DefaultGravity);
|
||||
Physics::SetBounceThresholdVelocity(BounceThresholdVelocity);
|
||||
Physics::SetEnableCCD(!DisableCCD);
|
||||
|
||||
// TODO: setting eADAPTIVE_FORCE requires PxScene setup (physx docs: This flag is not mutable, and must be set in PxSceneDesc at scene creation.)
|
||||
|
||||
// Update all shapes
|
||||
|
||||
// TODO: update all shapes filter data
|
||||
// TODO: update all shapes flags
|
||||
|
||||
/*
|
||||
{
|
||||
get all actors and then:
|
||||
|
||||
const PxU32 numShapes = actor->getNbShapes();
|
||||
PxShape** shapes = (PxShape**)SAMPLE_ALLOC(sizeof(PxShape*)*numShapes);
|
||||
actor->getShapes(shapes, numShapes);
|
||||
for (PxU32 i = 0; i < numShapes; i++)
|
||||
{
|
||||
..
|
||||
}
|
||||
SAMPLE_FREE(shapes);
|
||||
}*/
|
||||
}
|
||||
|
||||
void PhysicsSettings::RestoreDefault()
|
||||
{
|
||||
DefaultGravity = PhysicsSettings_DefaultGravity;
|
||||
TriangleMeshTriangleMinAreaThreshold = PhysicsSettings_TriangleMeshTriangleMinAreaThreshold;
|
||||
BounceThresholdVelocity = PhysicsSettings_BounceThresholdVelocity;
|
||||
FrictionCombineMode = PhysicsSettings_FrictionCombineMode;
|
||||
RestitutionCombineMode = PhysicsSettings_RestitutionCombineMode;
|
||||
DisableCCD = PhysicsSettings_DisableCCD;
|
||||
EnableAdaptiveForce = PhysicsSettings_EnableAdaptiveForce;
|
||||
MaxDeltaTime = PhysicsSettings_MaxDeltaTime;
|
||||
EnableSubstepping = PhysicsSettings_EnableSubstepping;
|
||||
SubstepDeltaTime = PhysicsSettings_SubstepDeltaTime;
|
||||
MaxSubsteps = PhysicsSettings_MaxSubsteps;
|
||||
QueriesHitTriggers = PhysicsSettings_QueriesHitTriggers;
|
||||
SupportCookingAtRuntime = PhysicsSettings_SupportCookingAtRuntime;
|
||||
|
||||
for (int32 i = 0; i < 32; i++)
|
||||
LayerMasks[i] = MAX_uint32;
|
||||
}
|
||||
|
||||
void PhysicsSettings::Deserialize(DeserializeStream& stream, ISerializeModifier* modifier)
|
||||
{
|
||||
DESERIALIZE(DefaultGravity);
|
||||
DESERIALIZE(TriangleMeshTriangleMinAreaThreshold);
|
||||
DESERIALIZE(BounceThresholdVelocity);
|
||||
DESERIALIZE(FrictionCombineMode);
|
||||
DESERIALIZE(RestitutionCombineMode);
|
||||
DESERIALIZE(DisableCCD);
|
||||
DESERIALIZE(EnableAdaptiveForce);
|
||||
DESERIALIZE(MaxDeltaTime);
|
||||
DESERIALIZE(EnableSubstepping);
|
||||
DESERIALIZE(SubstepDeltaTime);
|
||||
DESERIALIZE(MaxSubsteps);
|
||||
DESERIALIZE(QueriesHitTriggers);
|
||||
DESERIALIZE(SupportCookingAtRuntime);
|
||||
|
||||
const auto layers = stream.FindMember("LayerMasks");
|
||||
if (layers != stream.MemberEnd())
|
||||
{
|
||||
auto& layersArray = layers->value;
|
||||
ASSERT(layersArray.IsArray());
|
||||
for (uint32 i = 0; i < layersArray.Size() && i < 32; i++)
|
||||
{
|
||||
LayerMasks[i] = layersArray[i].GetUint();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,105 +6,91 @@
|
||||
#include "Engine/Core/Math/Vector3.h"
|
||||
#include "Types.h"
|
||||
|
||||
// Default values for the physics settings
|
||||
|
||||
#define PhysicsSettings_DefaultGravity Vector3(0, -981.0f, 0)
|
||||
#define PhysicsSettings_TriangleMeshTriangleMinAreaThreshold (5.0f)
|
||||
#define PhysicsSettings_BounceThresholdVelocity (200.0f)
|
||||
#define PhysicsSettings_FrictionCombineMode PhysicsCombineMode::Average
|
||||
#define PhysicsSettings_RestitutionCombineMode PhysicsCombineMode::Average
|
||||
#define PhysicsSettings_DisableCCD false
|
||||
#define PhysicsSettings_EnableAdaptiveForce false
|
||||
#define PhysicsSettings_MaxDeltaTime (1.0f / 10.0f)
|
||||
#define PhysicsSettings_EnableSubstepping false
|
||||
#define PhysicsSettings_SubstepDeltaTime (1.0f / 120.0f)
|
||||
#define PhysicsSettings_MaxSubsteps 5
|
||||
#define PhysicsSettings_QueriesHitTriggers true
|
||||
#define PhysicsSettings_SupportCookingAtRuntime false
|
||||
|
||||
/// <summary>
|
||||
/// Physics simulation settings container.
|
||||
/// </summary>
|
||||
/// <seealso cref="SettingsBase{PhysicsSettings}" />
|
||||
class PhysicsSettings : public SettingsBase<PhysicsSettings>
|
||||
API_CLASS(sealed, Namespace="FlaxEditor.Content.Settings", NoConstructor) class FLAXENGINE_API PhysicsSettings : public SettingsBase
|
||||
{
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PhysicsSettings"/> class.
|
||||
/// </summary>
|
||||
PhysicsSettings()
|
||||
{
|
||||
for (int32 i = 0; i < 32; i++)
|
||||
LayerMasks[i] = MAX_uint32;
|
||||
}
|
||||
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(PhysicsSettings);
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// The default gravity force value (in cm^2/s).
|
||||
/// </summary>
|
||||
Vector3 DefaultGravity = PhysicsSettings_DefaultGravity;
|
||||
|
||||
/// <summary>
|
||||
/// Triangles from triangle meshes (CSG) with an area less than or equal to this value will be removed from physics collision data. Set to less than or equal 0 to disable.
|
||||
/// </summary>
|
||||
float TriangleMeshTriangleMinAreaThreshold = PhysicsSettings_TriangleMeshTriangleMinAreaThreshold;
|
||||
|
||||
/// <summary>
|
||||
/// Minimum relative velocity required for an object to bounce. A typical value for simulation stability is about 0.2 * gravity
|
||||
/// </summary>
|
||||
float BounceThresholdVelocity = PhysicsSettings_BounceThresholdVelocity;
|
||||
|
||||
/// <summary>
|
||||
/// Default friction combine mode, controls how friction is computed for multiple materials.
|
||||
/// </summary>
|
||||
PhysicsCombineMode FrictionCombineMode = PhysicsSettings_FrictionCombineMode;
|
||||
|
||||
/// <summary>
|
||||
/// Default restitution combine mode, controls how restitution is computed for multiple materials.
|
||||
/// </summary>
|
||||
PhysicsCombineMode RestitutionCombineMode = PhysicsSettings_RestitutionCombineMode;
|
||||
|
||||
/// <summary>
|
||||
/// If true CCD will be ignored. This is an optimization when CCD is never used which removes the need for physx to check it internally.
|
||||
/// </summary>
|
||||
bool DisableCCD = PhysicsSettings_DisableCCD;
|
||||
|
||||
/// <summary>
|
||||
/// Enables adaptive forces to accelerate convergence of the solver. Can improve physics simulation performance but lead to artifacts.
|
||||
/// </summary>
|
||||
bool EnableAdaptiveForce = PhysicsSettings_EnableAdaptiveForce;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum allowed delta time (in seconds) for the physics simulation step.
|
||||
/// </summary>
|
||||
float MaxDeltaTime = PhysicsSettings_MaxDeltaTime;
|
||||
|
||||
/// <summary>
|
||||
/// Whether to substep the physics simulation.
|
||||
/// </summary>
|
||||
bool EnableSubstepping = PhysicsSettings_EnableSubstepping;
|
||||
|
||||
/// <summary>
|
||||
/// Delta time (in seconds) for an individual simulation substep.
|
||||
/// </summary>
|
||||
float SubstepDeltaTime = PhysicsSettings_SubstepDeltaTime;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum number of substeps for physics simulation.
|
||||
/// </summary>
|
||||
int32 MaxSubsteps = PhysicsSettings_MaxSubsteps;
|
||||
API_FIELD(Attributes="EditorOrder(0), DefaultValue(typeof(Vector3), \"0,-981.0,0\"), EditorDisplay(\"Simulation\")")
|
||||
Vector3 DefaultGravity = Vector3(0, -981.0f, 0);
|
||||
|
||||
/// <summary>
|
||||
/// If enabled, any Raycast or other scene query that intersects with a Collider marked as a Trigger will returns with a hit. Individual raycasts can override this behavior.
|
||||
/// </summary>
|
||||
bool QueriesHitTriggers = PhysicsSettings_QueriesHitTriggers;
|
||||
API_FIELD(Attributes="EditorOrder(10), DefaultValue(true), EditorDisplay(\"Framerate\")")
|
||||
bool QueriesHitTriggers = true;
|
||||
|
||||
/// <summary>
|
||||
/// Triangles from triangle meshes (CSG) with an area less than or equal to this value will be removed from physics collision data. Set to less than or equal 0 to disable.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(20), DefaultValue(5.0f), EditorDisplay(\"Simulation\")")
|
||||
float TriangleMeshTriangleMinAreaThreshold = 5.0f;
|
||||
|
||||
/// <summary>
|
||||
/// Minimum relative velocity required for an object to bounce. A typical value for simulation stability is about 0.2 * gravity
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(30), DefaultValue(200.0f), EditorDisplay(\"Simulation\")")
|
||||
float BounceThresholdVelocity = 200.0f;
|
||||
|
||||
/// <summary>
|
||||
/// Default friction combine mode, controls how friction is computed for multiple materials.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(40), DefaultValue(PhysicsCombineMode.Average), EditorDisplay(\"Simulation\")")
|
||||
PhysicsCombineMode FrictionCombineMode = PhysicsCombineMode::Average;
|
||||
|
||||
/// <summary>
|
||||
/// Default restitution combine mode, controls how restitution is computed for multiple materials.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(40), DefaultValue(PhysicsCombineMode.Average), EditorDisplay(\"Simulation\")")
|
||||
PhysicsCombineMode RestitutionCombineMode = PhysicsCombineMode::Average;
|
||||
|
||||
/// <summary>
|
||||
/// If true CCD will be ignored. This is an optimization when CCD is never used which removes the need for physx to check it internally.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(70), DefaultValue(false), EditorDisplay(\"Simulation\")")
|
||||
bool DisableCCD = false;
|
||||
|
||||
/// <summary>
|
||||
/// Enables adaptive forces to accelerate convergence of the solver. Can improve physics simulation performance but lead to artifacts.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(80), DefaultValue(false), EditorDisplay(\"Simulation\")")
|
||||
bool EnableAdaptiveForce = false;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum allowed delta time (in seconds) for the physics simulation step.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(1000), DefaultValue(1.0f / 10.0f), EditorDisplay(\"Framerate\")")
|
||||
float MaxDeltaTime = 1.0f / 10.0f;
|
||||
|
||||
/// <summary>
|
||||
/// Whether to substep the physics simulation.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(1005), DefaultValue(false), EditorDisplay(\"Framerate\")")
|
||||
bool EnableSubstepping = false;
|
||||
|
||||
/// <summary>
|
||||
/// Delta time (in seconds) for an individual simulation substep.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(1010), DefaultValue(1.0f / 120.0f), EditorDisplay(\"Framerate\")")
|
||||
float SubstepDeltaTime = 1.0f / 120.0f;
|
||||
|
||||
/// <summary>
|
||||
/// The maximum number of substeps for physics simulation.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(1020), DefaultValue(5), EditorDisplay(\"Framerate\")")
|
||||
int32 MaxSubsteps = 5;
|
||||
|
||||
/// <summary>
|
||||
/// Enables support for cooking physical collision shapes geometry at runtime. Use it to enable generating runtime terrain collision or convex mesh colliders.
|
||||
/// </summary>
|
||||
bool SupportCookingAtRuntime = PhysicsSettings_SupportCookingAtRuntime;
|
||||
API_FIELD(Attributes="EditorOrder(1100), DefaultValue(false), EditorDisplay(\"Other\")")
|
||||
bool SupportCookingAtRuntime = false;
|
||||
|
||||
public:
|
||||
|
||||
@@ -115,8 +101,17 @@ public:
|
||||
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="PhysicsSettings"/> class.
|
||||
/// </summary>
|
||||
PhysicsSettings();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the instance of the settings asset (default value if missing). Object returned by this method is always loaded with valid data to use.
|
||||
/// </summary>
|
||||
static PhysicsSettings* Get();
|
||||
|
||||
// [SettingsBase]
|
||||
void Apply() override;
|
||||
void RestoreDefault() override;
|
||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) final override;
|
||||
};
|
||||
|
||||
@@ -14,9 +14,6 @@
|
||||
#include <ThirdParty/PhysX/foundation/PxBounds3.h>
|
||||
#include <ThirdParty/PhysX/characterkinematic/PxExtended.h>
|
||||
#include <ThirdParty/PhysX/PxShape.h>
|
||||
#include "PhysicsSettings.h"
|
||||
|
||||
//////////////////////////// Conversion between PhysX and Flax types
|
||||
|
||||
inline PxVec2& C2P(const Vector2& v)
|
||||
{
|
||||
@@ -43,8 +40,6 @@ inline PxBounds3& C2P(const BoundingBox& v)
|
||||
return *(PxBounds3*)&v;
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
|
||||
inline Vector2& P2C(const PxVec2& v)
|
||||
{
|
||||
return *(Vector2*)&v;
|
||||
@@ -79,29 +74,4 @@ inline Vector3 P2C(const PxExtendedVec3& v)
|
||||
#endif
|
||||
}
|
||||
|
||||
////////////////////////////
|
||||
|
||||
inline PxShapeFlags GetShapeFlags(bool isTrigger, bool isEnabled)
|
||||
{
|
||||
#if WITH_PVD
|
||||
PxShapeFlags flags = PxShapeFlag::eVISUALIZATION;
|
||||
#else
|
||||
PxShapeFlags flags = static_cast<PxShapeFlags>(0);
|
||||
#endif
|
||||
|
||||
if (isEnabled)
|
||||
{
|
||||
if (isTrigger)
|
||||
{
|
||||
flags |= PxShapeFlag::eTRIGGER_SHAPE;
|
||||
if (PhysicsSettings::Instance()->QueriesHitTriggers)
|
||||
flags |= PxShapeFlag::eSCENE_QUERY_SHAPE;
|
||||
}
|
||||
else
|
||||
{
|
||||
flags = PxShapeFlag::eSIMULATION_SHAPE | PxShapeFlag::eSCENE_QUERY_SHAPE;
|
||||
}
|
||||
}
|
||||
|
||||
return flags;
|
||||
}
|
||||
extern PxShapeFlags GetShapeFlags(bool isTrigger, bool isEnabled);
|
||||
|
||||
@@ -9,41 +9,37 @@
|
||||
/// <summary>
|
||||
/// Android platform settings.
|
||||
/// </summary>
|
||||
/// <seealso cref="SettingsBase{AndroidPlatformSettings}" />
|
||||
class AndroidPlatformSettings : public SettingsBase<AndroidPlatformSettings>
|
||||
API_CLASS(sealed, Namespace="FlaxEditor.Content.Settings") class FLAXENGINE_API AndroidPlatformSettings : public SettingsBase
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(AndroidPlatformSettings);
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// The application package name (eg. com.company.product). Custom tokens: ${PROJECT_NAME}, ${COMPANY_NAME}.
|
||||
/// </summary>
|
||||
String PackageName;
|
||||
API_FIELD(Attributes="EditorOrder(0), EditorDisplay(\"General\")")
|
||||
String PackageName = TEXT("com.${COMPANY_NAME}.${PROJECT_NAME}");
|
||||
|
||||
/// <summary>
|
||||
/// The application permissions list (eg. android.media.action.IMAGE_CAPTURE). Added to the generated manifest file.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(100), EditorDisplay(\"General\")")
|
||||
Array<String> Permissions;
|
||||
|
||||
/// <summary>
|
||||
/// Custom icon texture (asset id) to use for the application (overrides the default one).
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(1030), AssetReference(typeof(Texture)), EditorDisplay(\"Other\")")
|
||||
Guid OverrideIcon;
|
||||
|
||||
public:
|
||||
|
||||
AndroidPlatformSettings()
|
||||
{
|
||||
RestoreDefault();
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instance of the settings asset (default value if missing). Object returned by this method is always loaded with valid data to use.
|
||||
/// </summary>
|
||||
static AndroidPlatformSettings* Get();
|
||||
|
||||
// [SettingsBase]
|
||||
void RestoreDefault() final override
|
||||
{
|
||||
PackageName = TEXT("com.${COMPANY_NAME}.${PROJECT_NAME}");
|
||||
Permissions.Clear();
|
||||
OverrideIcon = Guid::Empty;
|
||||
}
|
||||
|
||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) final override
|
||||
{
|
||||
DESERIALIZE(PackageName);
|
||||
|
||||
@@ -9,66 +9,67 @@
|
||||
/// <summary>
|
||||
/// Linux platform settings.
|
||||
/// </summary>
|
||||
/// <seealso cref="SettingsBase{LinuxPlatformSettings}" />
|
||||
class LinuxPlatformSettings : public SettingsBase<LinuxPlatformSettings>
|
||||
API_CLASS(sealed, Namespace="FlaxEditor.Content.Settings") class FLAXENGINE_API LinuxPlatformSettings : public SettingsBase
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(LinuxPlatformSettings);
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// The default game window mode.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(10), DefaultValue(GameWindowMode.Windowed), EditorDisplay(\"Window\")")
|
||||
GameWindowMode WindowMode = GameWindowMode::Windowed;
|
||||
|
||||
/// <summary>
|
||||
/// The default game window width (in pixels).
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(20), DefaultValue(1280), EditorDisplay(\"Window\")")
|
||||
int32 ScreenWidth = 1280;
|
||||
|
||||
/// <summary>
|
||||
/// The default game window height (in pixels).
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(30), DefaultValue(720), EditorDisplay(\"Window\")")
|
||||
int32 ScreenHeight = 720;
|
||||
|
||||
/// <summary>
|
||||
/// Enables game running when application window loses focus.
|
||||
/// </summary>
|
||||
bool RunInBackground = false;
|
||||
|
||||
/// <summary>
|
||||
/// Enables resizing the game window by the user.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(40), DefaultValue(false), EditorDisplay(\"Window\")")
|
||||
bool ResizableWindow = false;
|
||||
|
||||
/// <summary>
|
||||
/// Enables game running when application window loses focus.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(1010), DefaultValue(false), EditorDisplay(\"Other\", \"Run In Background\")")
|
||||
bool RunInBackground = false;
|
||||
|
||||
/// <summary>
|
||||
/// Limits maximum amount of concurrent game instances running to one, otherwise user may launch application more than once.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(1020), DefaultValue(false), EditorDisplay(\"Other\")")
|
||||
bool ForceSingleInstance = false;
|
||||
|
||||
/// <summary>
|
||||
/// Custom icon texture (asset id) to use for the application (overrides the default one).
|
||||
/// </summary>
|
||||
Guid OverrideIcon = Guid::Empty;
|
||||
API_FIELD(Attributes="EditorOrder(1030), CustomEditorAlias(\"FlaxEditor.CustomEditors.Editors.AssetRefEditor\"), AssetReference(typeof(Texture)), EditorDisplay(\"Other\")")
|
||||
Guid OverrideIcon;
|
||||
|
||||
/// <summary>
|
||||
/// Enables support for Vulkan. Disabling it reduces compiled shaders count.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(2000), DefaultValue(true), EditorDisplay(\"Graphics\")")
|
||||
bool SupportVulkan = true;
|
||||
|
||||
public:
|
||||
|
||||
// [SettingsBase]
|
||||
void RestoreDefault() final override
|
||||
{
|
||||
WindowMode = GameWindowMode::Windowed;
|
||||
ScreenWidth = 1280;
|
||||
ScreenHeight = 720;
|
||||
RunInBackground = false;
|
||||
ResizableWindow = false;
|
||||
ForceSingleInstance = false;
|
||||
OverrideIcon = Guid::Empty;
|
||||
SupportVulkan = true;
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instance of the settings asset (default value if missing). Object returned by this method is always loaded with valid data to use.
|
||||
/// </summary>
|
||||
static LinuxPlatformSettings* Get();
|
||||
|
||||
// [SettingsBase]
|
||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) final override
|
||||
{
|
||||
DESERIALIZE(WindowMode);
|
||||
|
||||
@@ -62,5 +62,15 @@ public class Platform : EngineModule
|
||||
break;
|
||||
default: throw new InvalidPlatformException(options.Platform.Target);
|
||||
}
|
||||
if (options.Target.IsEditor)
|
||||
{
|
||||
// Include platform settings headers
|
||||
options.SourceFiles.Add(Path.Combine(FolderPath, "Windows", "WindowsPlatformSettings.h"));
|
||||
options.SourceFiles.Add(Path.Combine(FolderPath, "UWP", "UWPPlatformSettings.h"));
|
||||
options.SourceFiles.Add(Path.Combine(FolderPath, "Linux", "LinuxPlatformSettings.h"));
|
||||
options.SourceFiles.Add(Path.Combine(FolderPath, "Android", "AndroidPlatformSettings.h"));
|
||||
AddSourceFileIfExists(options, Path.Combine(Globals.EngineRoot, "Source", "Platforms", "XboxScarlett", "Engine", "Platform", "XboxScarlettPlatformSettings.h"));
|
||||
AddSourceFileIfExists(options, Path.Combine(Globals.EngineRoot, "Source", "Platforms", "PS4", "Engine", "Platform", "PS4PlatformSettings.h"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,15 +9,15 @@
|
||||
/// <summary>
|
||||
/// Universal Windows Platform settings.
|
||||
/// </summary>
|
||||
/// <seealso cref="SettingsBase{UWPPlatformSettings}" />
|
||||
class UWPPlatformSettings : public SettingsBase<UWPPlatformSettings>
|
||||
API_CLASS(sealed, Namespace="FlaxEditor.Content.Settings") class FLAXENGINE_API UWPPlatformSettings : public SettingsBase
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(UWPPlatformSettings);
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// The preferred launch windowing mode.
|
||||
/// </summary>
|
||||
enum class WindowMode
|
||||
API_ENUM() enum class WindowMode
|
||||
{
|
||||
/// <summary>
|
||||
/// The full screen mode
|
||||
@@ -33,7 +33,7 @@ public:
|
||||
/// <summary>
|
||||
/// The display orientation modes. Can be combined as flags.
|
||||
/// </summary>
|
||||
enum class DisplayOrientations
|
||||
API_ENUM(Attributes="Flags") enum class DisplayOrientations
|
||||
{
|
||||
/// <summary>
|
||||
/// The none.
|
||||
@@ -71,40 +71,41 @@ public:
|
||||
/// <summary>
|
||||
/// The preferred launch windowing mode. Always fullscreen on Xbox.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(10), DefaultValue(WindowMode.FullScreen), EditorDisplay(\"Window\")")
|
||||
WindowMode PreferredLaunchWindowingMode = WindowMode::FullScreen;
|
||||
|
||||
/// <summary>
|
||||
/// The display orientation modes. Can be combined as flags.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(20), DefaultValue(DisplayOrientations.All), EditorDisplay(\"Window\")")
|
||||
DisplayOrientations AutoRotationPreferences = DisplayOrientations::All;
|
||||
|
||||
/// <summary>
|
||||
/// The location of the package certificate (relative to the project).
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(1010), DefaultValue(\"\"), EditorDisplay(\"Other\")")
|
||||
String CertificateLocation;
|
||||
|
||||
/// <summary>
|
||||
/// Enables support for DirectX 11. Disabling it reduces compiled shaders count.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(2000), DefaultValue(true), EditorDisplay(\"Graphics\", \"Support DirectX 11\")")
|
||||
bool SupportDX11 = true;
|
||||
|
||||
/// <summary>
|
||||
/// Enables support for DirectX 10 and DirectX 10.1. Disabling it reduces compiled shaders count.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(2010), DefaultValue(false), EditorDisplay(\"Graphics\", \"Support DirectX 10\")")
|
||||
bool SupportDX10 = false;
|
||||
|
||||
public:
|
||||
|
||||
// [SettingsBase]
|
||||
void RestoreDefault() final override
|
||||
{
|
||||
PreferredLaunchWindowingMode = WindowMode::FullScreen;
|
||||
AutoRotationPreferences = DisplayOrientations::All;
|
||||
CertificateLocation.Clear();
|
||||
SupportDX11 = true;
|
||||
SupportDX10 = false;
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instance of the settings asset (default value if missing). Object returned by this method is always loaded with valid data to use.
|
||||
/// </summary>
|
||||
static UWPPlatformSettings* Get();
|
||||
|
||||
// [SettingsBase]
|
||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) final override
|
||||
{
|
||||
DESERIALIZE(PreferredLaunchWindowingMode);
|
||||
|
||||
@@ -9,84 +9,85 @@
|
||||
/// <summary>
|
||||
/// Windows platform settings.
|
||||
/// </summary>
|
||||
/// <seealso cref="SettingsBase{WindowsPlatformSettings}" />
|
||||
class WindowsPlatformSettings : public SettingsBase<WindowsPlatformSettings>
|
||||
API_CLASS(sealed, Namespace="FlaxEditor.Content.Settings") class FLAXENGINE_API WindowsPlatformSettings : public SettingsBase
|
||||
{
|
||||
DECLARE_SCRIPTING_TYPE_MINIMAL(WindowsPlatformSettings);
|
||||
public:
|
||||
|
||||
/// <summary>
|
||||
/// The default game window mode.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(10), DefaultValue(GameWindowMode.Windowed), EditorDisplay(\"Window\")")
|
||||
GameWindowMode WindowMode = GameWindowMode::Windowed;
|
||||
|
||||
/// <summary>
|
||||
/// The default game window width (in pixels).
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(20), DefaultValue(1280), EditorDisplay(\"Window\")")
|
||||
int32 ScreenWidth = 1280;
|
||||
|
||||
/// <summary>
|
||||
/// The default game window height (in pixels).
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(30), DefaultValue(720), EditorDisplay(\"Window\")")
|
||||
int32 ScreenHeight = 720;
|
||||
|
||||
/// <summary>
|
||||
/// Enables game running when application window loses focus.
|
||||
/// </summary>
|
||||
bool RunInBackground = false;
|
||||
|
||||
/// <summary>
|
||||
/// Enables resizing the game window by the user.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(40), DefaultValue(false), EditorDisplay(\"Window\")")
|
||||
bool ResizableWindow = false;
|
||||
|
||||
/// <summary>
|
||||
/// Enables game running when application window loses focus.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(1010), DefaultValue(false), EditorDisplay(\"Other\", \"Run In Background\")")
|
||||
bool RunInBackground = false;
|
||||
|
||||
/// <summary>
|
||||
/// Limits maximum amount of concurrent game instances running to one, otherwise user may launch application more than once.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(1020), DefaultValue(false), EditorDisplay(\"Other\")")
|
||||
bool ForceSingleInstance = false;
|
||||
|
||||
/// <summary>
|
||||
/// Custom icon texture (asset id) to use for the application (overrides the default one).
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(1030), CustomEditorAlias(\"FlaxEditor.CustomEditors.Editors.AssetRefEditor\"), AssetReference(typeof(Texture)), EditorDisplay(\"Other\")")
|
||||
Guid OverrideIcon;
|
||||
|
||||
/// <summary>
|
||||
/// Enables support for DirectX 12. Disabling it reduces compiled shaders count.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(2000), DefaultValue(false), EditorDisplay(\"Graphics\", \"Support DirectX 12\")")
|
||||
bool SupportDX12 = false;
|
||||
|
||||
/// <summary>
|
||||
/// Enables support for DirectX 11. Disabling it reduces compiled shaders count.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(2010), DefaultValue(true), EditorDisplay(\"Graphics\", \"Support DirectX 11\")")
|
||||
bool SupportDX11 = true;
|
||||
|
||||
/// <summary>
|
||||
/// Enables support for DirectX 10 and DirectX 10.1. Disabling it reduces compiled shaders count.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(2020), DefaultValue(false), EditorDisplay(\"Graphics\", \"Support DirectX 10\")")
|
||||
bool SupportDX10 = false;
|
||||
|
||||
/// <summary>
|
||||
/// Enables support for Vulkan. Disabling it reduces compiled shaders count.
|
||||
/// </summary>
|
||||
API_FIELD(Attributes="EditorOrder(2030), DefaultValue(false), EditorDisplay(\"Graphics\")")
|
||||
bool SupportVulkan = false;
|
||||
|
||||
public:
|
||||
|
||||
// [SettingsBase]
|
||||
void RestoreDefault() final override
|
||||
{
|
||||
WindowMode = GameWindowMode::Windowed;
|
||||
ScreenWidth = 1280;
|
||||
ScreenHeight = 720;
|
||||
RunInBackground = false;
|
||||
ResizableWindow = false;
|
||||
ForceSingleInstance = false;
|
||||
OverrideIcon = Guid::Empty;
|
||||
SupportDX12 = false;
|
||||
SupportDX11 = true;
|
||||
SupportDX10 = false;
|
||||
SupportVulkan = false;
|
||||
}
|
||||
/// <summary>
|
||||
/// Gets the instance of the settings asset (default value if missing). Object returned by this method is always loaded with valid data to use.
|
||||
/// </summary>
|
||||
static WindowsPlatformSettings* Get();
|
||||
|
||||
// [SettingsBase]
|
||||
void Deserialize(DeserializeStream& stream, ISerializeModifier* modifier) final override
|
||||
{
|
||||
DESERIALIZE(WindowMode);
|
||||
|
||||
@@ -69,7 +69,7 @@ void Terrain::UpdateLayerBits()
|
||||
filterData.word0 = GetLayerMask();
|
||||
|
||||
// Own layer mask
|
||||
filterData.word1 = PhysicsSettings::Instance()->LayerMasks[GetLayer()];
|
||||
filterData.word1 = Physics::LayerMasks[GetLayer()];
|
||||
|
||||
// Update the shapes layer bits
|
||||
for (int32 pathIndex = 0; pathIndex < _patches.Count(); pathIndex++)
|
||||
|
||||
Reference in New Issue
Block a user