14#include <physx/PxSceneDesc.h>
15#include <physx/PxSceneLock.h>
16#include <physx/PxPhysics.h>
18#include <physx/extensions/PxDefaultCpuDispatcher.h>
19#include <physx/extensions/PxDefaultSimulationFilterShader.h>
25 constexpr U32 g_parallelPartitionSize = 32;
34 static void setupMBP( physx::PxScene& scene )
36 using namespace physx;
38 const float range = 1000.0f;
39 const PxU32 subdiv = 4;
44 const PxVec3 min( -range );
45 const PxVec3 max( range );
46 const PxBounds3 globalBounds( min, max );
48 PxBounds3 bounds[256];
49 const PxU32 nbRegions = PxBroadPhaseExt::createRegionsFromWorldBounds( bounds, globalBounds, subdiv );
51 for ( PxU32 i = 0; i < nbRegions; i++ )
53 PxBroadPhaseRegion region;
54 region.bounds = bounds[i];
55 region.userData = (
void*)i;
56 scene.addBroadPhaseRegion( region );
74 physx::PxPhysics* gPhysicsSDK = physX.
getSDK();
82 physx::PxSceneDesc sceneDesc( gPhysicsSDK->getTolerancesScale() );
84 if ( !sceneDesc.cpuDispatcher )
86 _cpuDispatcher = physx::PxDefaultCpuDispatcherCreate( std::min(std::thread::hardware_concurrency(), 4u) );
94 if ( !sceneDesc.filterShader )
96 sceneDesc.filterShader = physx::PxDefaultSimulationFilterShader;
99#if PX_SUPPORT_GPU_PHYSX
100 if ( !sceneDesc.cudaContextManager )
101 sceneDesc.cudaContextManager = physX.cudaContextManager();
107 sceneDesc.flags |= physx::PxSceneFlag::eENABLE_PCM;
109 sceneDesc.flags |= physx::PxSceneFlag::eENABLE_STABILIZATION;
111 sceneDesc.flags |= physx::PxSceneFlag::eENABLE_ACTIVE_ACTORS;
112 sceneDesc.sceneQueryUpdateMode = physx::PxSceneQueryUpdateMode::eBUILD_ENABLED_COMMIT_DISABLED;
117 sceneDesc.gpuMaxNumPartitions = 8;
120 sceneDesc.broadPhaseType = physx::PxBroadPhaseType::eMBP;
123 _gScene = gPhysicsSDK->createScene( sceneDesc );
130 physx::PxSceneWriteLock scopedLock( *
_gScene );
131 [[maybe_unused]]
const physx::PxSceneFlags flag =
_gScene->getFlags();
137 physx::PxPvdSceneClient* pvdClient =
_gScene->getScenePvdClient();
138 if ( pvdClient !=
nullptr )
140 pvdClient->setScenePvdFlag( physx::PxPvdSceneFlag::eTRANSMIT_CONSTRAINTS,
true );
141 pvdClient->setScenePvdFlag( physx::PxPvdSceneFlag::eTRANSMIT_CONTACTS,
true );
142 pvdClient->setScenePvdFlag( physx::PxPvdSceneFlag::eTRANSMIT_SCENEQUERIES,
true );
157#define SAFE_RELEASE(X) if (X != nullptr) { X->release(); X = nullptr;}
177 bool expected =
true;
207 bool expected =
true;
213 while ( !
_gScene->fetchResults( block ) )
221 physx::PxU32 nbActiveActors = 0;
222 physx::PxActor** activeActors =
_gScene->getActiveActors( nbActiveActors );
224 if ( nbActiveActors > 0u )
234 for (
U32 i = start; i < end; ++i )
246 const physx::PxRigidActor* rigidActor =
static_cast<physx::PxRigidActor*
>(actor);
249 const physx::PxTransform pT = rigidActor->getGlobalPose();
250 const physx::PxQuat pQ = pT.q.getConjugate();
261 _gScene->simulate( Time::MicrosecondsToMilliseconds<physx::PxReal>( deltaTimeGameUS ) );
268 assert( actor !=
nullptr );
276 if ( oldActor !=
nullptr )
278 _gScene->removeActor( *oldActor );
280 if ( newActor !=
nullptr )
282 _gScene->addActor( *newActor );
288 physx::PxRaycastBuffer hit;
290 const physx::PxHitFlags outputFlags = physx::PxHitFlag::eMESH_ANY | physx::PxHitFlag::ePOSITION | physx::PxHitFlag::eNORMAL;
296 if (
_gScene->raycast( origin + unitDir * range.
min, unitDir, range.
max, hit, outputFlags ) )
298 const physx::PxU32 numHits = hit.getNbAnyHits();
300 for ( physx::PxU32 i = 0; i < numHits; ++i )
302 hit.block = hit.getAnyHit( i );
303 PX_ASSERT( hit.block.shape );
304 PX_ASSERT( hit.block.actor );
305 PX_ASSERT( hit.block.distance <= probeLength + extra );
308 intersectionsOut.push_back( {
#define PROFILE_SCOPE_AUTO(CATEGORY)
#define PROFILE_SCOPE(NAME, CATEGORY)
FORCE_INLINE I64 getGUID() const noexcept
PhysicsAPIWrapper & getImpl()
physx::PxRigidActor * _actor
physx::PxPhysics * getSDK() const noexcept
physx::PxDefaultCpuDispatcher * _cpuDispatcher
void frameStarted(U64 deltaTimeGameUS) override
Custom process step.
void frameEnded(U64 deltaTimeGameUS) override
Physics update callback for custom behavior.
RigidMap _sceneRigidActors
void idle() override
Custom physics idle calls.
bool init() override
Pre PHYSICS_DEVICE initialisation call.
virtual ~PhysXSceneInterface() override
void updateRigidActor(physx::PxRigidActor *oldActor, physx::PxRigidActor *newActor) const
bool intersect(const Ray &intersectionRay, vec2< F32 > range, vector< SGNRayResult > &intersectionsOut) const
static void UpdateActor(physx::PxActor *actor)
PhysXSceneInterface(Scene &parentScene)
LoadQueue _sceneRigidQueue
void addRigidActor(PhysXActor *actor)
std::atomic_bool _physxResultsPending
std::atomic_bool _rigidActorsQueued
bool isInit() const noexcept override
Should return true if init() was called successfully.
void release() override
Called on interface destruction.
PlatformContext & context() noexcept
PXDevice & pfx() noexcept
void idle(bool fast=true, U64 deltaTimeUSGame=0u, U64 deltaTimeUSApp=0u)
Scene & parentScene() noexcept
constexpr bool IS_SHIPPING_BUILD
constexpr Optick::Category::Type Physics
vec3< F32 > toVec3(const physx::PxVec3 &vec) noexcept
Handle console commands that start with a forward slash.
constexpr U32 to_U32(const T value)
eastl::vector< Type > vector
static const vec3< F32 > DEFAULT_GRAVITY
void Parallel_For(TaskPool &pool, const ParallelForDescriptor &descriptor, const DELEGATE< void, const Task *, U32, U32 > &cbk)
constexpr auto to_base(const Type value) -> Type
static NO_INLINE void d_printfn(const char *format, T &&... args)
static NO_INLINE void errorfn(const char *format, T &&... args)
U32 _partitionSize
How many elements should we process per async task.
U32 _iterCount
For loop iteration count.