Refactor settings types to use scripting API

This commit is contained in:
Wojtek Figat
2021-01-05 14:14:34 +01:00
parent cc8e78b505
commit be319c446d
75 changed files with 955 additions and 1431 deletions

View File

@@ -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
{