|
|
|
|
@@ -51,7 +51,7 @@
|
|
|
|
|
#define PHYSX_DEBUG_NAMING 0
|
|
|
|
|
|
|
|
|
|
// Temporary result buffer size
|
|
|
|
|
#define PHYSX_HIT_BUFFER_SIZE 128
|
|
|
|
|
#define PHYSX_HIT_BUFFER_SIZE 128
|
|
|
|
|
|
|
|
|
|
struct ActionDataPhysX
|
|
|
|
|
{
|
|
|
|
|
@@ -75,7 +75,8 @@ struct ScenePhysX
|
|
|
|
|
Array<ActionDataPhysX> Actions;
|
|
|
|
|
#if WITH_VEHICLE
|
|
|
|
|
Array<WheeledVehicle*> WheelVehicles;
|
|
|
|
|
PxBatchQuery* WheelRaycastBatchQuery = nullptr;
|
|
|
|
|
PxBatchQueryExt* WheelRaycastBatchQuery = nullptr;
|
|
|
|
|
int32 WheelRaycastBatchQuerySize = 0;
|
|
|
|
|
#endif
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
@@ -83,6 +84,7 @@ class AllocatorPhysX : public PxAllocatorCallback
|
|
|
|
|
{
|
|
|
|
|
void* allocate(size_t size, const char* typeName, const char* filename, int line) override
|
|
|
|
|
{
|
|
|
|
|
ASSERT(size < 1024 * 1024 * 32); // Prevent invalid allocation size
|
|
|
|
|
return Allocator::Allocate(size, 16);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -124,7 +126,7 @@ class QueryFilterPhysX : public PxQueryFilterCallback
|
|
|
|
|
return blockSingle ? PxQueryHitType::eBLOCK : PxQueryHitType::eTOUCH;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PxQueryHitType::Enum postFilter(const PxFilterData& filterData, const PxQueryHit& hit) override
|
|
|
|
|
PxQueryHitType::Enum postFilter(const PxFilterData& filterData, const PxQueryHit& hit, const PxShape* shape, const PxRigidActor* actor) override
|
|
|
|
|
{
|
|
|
|
|
// Not used
|
|
|
|
|
return PxQueryHitType::eNONE;
|
|
|
|
|
@@ -151,7 +153,7 @@ class CharacterQueryFilterPhysX : public PxQueryFilterCallback
|
|
|
|
|
return PxQueryHitType::eNONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PxQueryHitType::Enum postFilter(const PxFilterData& filterData, const PxQueryHit& hit) override
|
|
|
|
|
PxQueryHitType::Enum postFilter(const PxFilterData& filterData, const PxQueryHit& hit, const PxShape* shape, const PxRigidActor* actor) override
|
|
|
|
|
{
|
|
|
|
|
// Not used
|
|
|
|
|
return PxQueryHitType::eNONE;
|
|
|
|
|
@@ -200,6 +202,35 @@ class CharacterControllerFilterPhysX : public PxControllerFilterCallback
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#if WITH_VEHICLE
|
|
|
|
|
|
|
|
|
|
class WheelFilterPhysX : public PxQueryFilterCallback
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
PxQueryHitType::Enum preFilter(const PxFilterData& filterData, const PxShape* shape, const PxRigidActor* actor, PxHitFlags& queryFlags) override
|
|
|
|
|
{
|
|
|
|
|
if (!shape)
|
|
|
|
|
return PxQueryHitType::eNONE;
|
|
|
|
|
const PxFilterData shapeFilter = shape->getQueryFilterData();
|
|
|
|
|
|
|
|
|
|
// Hardcoded id for vehicle shapes masking
|
|
|
|
|
if (filterData.word3 == shapeFilter.word3)
|
|
|
|
|
{
|
|
|
|
|
return PxQueryHitType::eNONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Collide for pairs (A,B) where the filtermask of A contains the ID of B and vice versa
|
|
|
|
|
if ((filterData.word0 & shapeFilter.word1) && (shapeFilter.word0 & filterData.word1))
|
|
|
|
|
{
|
|
|
|
|
return PxQueryHitType::eBLOCK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return PxQueryHitType::eNONE;
|
|
|
|
|
}
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
class WriteStreamPhysX : public PxOutputStream
|
|
|
|
|
{
|
|
|
|
|
public:
|
|
|
|
|
@@ -363,13 +394,12 @@ namespace
|
|
|
|
|
#if WITH_VEHICLE
|
|
|
|
|
bool VehicleSDKInitialized = false;
|
|
|
|
|
Array<PxVehicleWheels*> WheelVehiclesCache;
|
|
|
|
|
Array<PxRaycastQueryResult> WheelQueryResults;
|
|
|
|
|
Array<PxRaycastHit> WheelHitResults;
|
|
|
|
|
Array<PxWheelQueryResult> WheelVehiclesResultsPerWheel;
|
|
|
|
|
Array<PxVehicleWheelQueryResult> WheelVehiclesResultsPerVehicle;
|
|
|
|
|
PxVehicleDrivableSurfaceToTireFrictionPairs* WheelTireFrictions = nullptr;
|
|
|
|
|
bool WheelTireFrictionsDirty = false;
|
|
|
|
|
Array<float> WheelTireTypes;
|
|
|
|
|
WheelFilterPhysX WheelRaycastFilter;
|
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -482,23 +512,6 @@ void InitVehicleSDK()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
PxQueryHitType::Enum WheelRaycastPreFilter(PxFilterData filterData0, PxFilterData filterData1, const void* constantBlock, PxU32 constantBlockSize, PxHitFlags& queryFlags)
|
|
|
|
|
{
|
|
|
|
|
// Hardcoded id for vehicle shapes masking
|
|
|
|
|
if (filterData0.word3 == filterData1.word3)
|
|
|
|
|
{
|
|
|
|
|
return PxQueryHitType::eNONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Collide for pairs (A,B) where the filtermask of A contains the ID of B and vice versa
|
|
|
|
|
if ((filterData0.word0 & filterData1.word1) && (filterData1.word0 & filterData0.word1))
|
|
|
|
|
{
|
|
|
|
|
return PxQueryHitType::eBLOCK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return PxQueryHitType::eNONE;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
void* PhysicalMaterial::GetPhysicsMaterial()
|
|
|
|
|
@@ -757,8 +770,6 @@ void PhysicsBackend::Shutdown()
|
|
|
|
|
// Cleanup any resources
|
|
|
|
|
#if WITH_VEHICLE
|
|
|
|
|
RELEASE_PHYSX(WheelTireFrictions);
|
|
|
|
|
WheelQueryResults.Resize(0);
|
|
|
|
|
WheelHitResults.Resize(0);
|
|
|
|
|
WheelVehiclesResultsPerWheel.Resize(0);
|
|
|
|
|
WheelVehiclesResultsPerVehicle.Resize(0);
|
|
|
|
|
#endif
|
|
|
|
|
@@ -794,7 +805,6 @@ void PhysicsBackend::ApplySettings(const PhysicsSettings& settings)
|
|
|
|
|
_frictionCombineMode = settings.FrictionCombineMode;
|
|
|
|
|
_restitutionCombineMode = settings.RestitutionCombineMode;
|
|
|
|
|
|
|
|
|
|
// 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
|
|
|
|
|
|
|
|
|
|
@@ -824,11 +834,10 @@ void* PhysicsBackend::CreateScene(const PhysicsSettings& settings)
|
|
|
|
|
sceneDesc.flags |= PxSceneFlag::eENABLE_ACTIVE_ACTORS;
|
|
|
|
|
if (!settings.DisableCCD)
|
|
|
|
|
sceneDesc.flags |= PxSceneFlag::eENABLE_CCD;
|
|
|
|
|
if (settings.EnableAdaptiveForce)
|
|
|
|
|
sceneDesc.flags |= PxSceneFlag::eADAPTIVE_FORCE;
|
|
|
|
|
sceneDesc.simulationEventCallback = &scenePhysX->EventsCallback;
|
|
|
|
|
sceneDesc.filterShader = FilterShader;
|
|
|
|
|
sceneDesc.bounceThresholdVelocity = settings.BounceThresholdVelocity;
|
|
|
|
|
sceneDesc.solverType = PxSolverType::ePGS;
|
|
|
|
|
if (sceneDesc.cpuDispatcher == nullptr)
|
|
|
|
|
{
|
|
|
|
|
scenePhysX->CpuDispatcher = PxDefaultCpuDispatcherCreate(Math::Clamp<uint32>(Platform::GetCPUInfo().ProcessorCoreCount - 1, 1, 4));
|
|
|
|
|
@@ -870,6 +879,7 @@ void PhysicsBackend::DestroyScene(void* scene)
|
|
|
|
|
SceneOrigins.Remove(scenePhysX->Scene);
|
|
|
|
|
#if WITH_VEHICLE
|
|
|
|
|
RELEASE_PHYSX(scenePhysX->WheelRaycastBatchQuery);
|
|
|
|
|
scenePhysX->WheelRaycastBatchQuerySize = 0;
|
|
|
|
|
#endif
|
|
|
|
|
RELEASE_PHYSX(scenePhysX->ControllerManager);
|
|
|
|
|
SAFE_DELETE(scenePhysX->CpuDispatcher);
|
|
|
|
|
@@ -1108,18 +1118,12 @@ void PhysicsBackend::EndSimulateScene(void* scene)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Update batches queries cache
|
|
|
|
|
if (wheelsCount > WheelQueryResults.Count())
|
|
|
|
|
if (wheelsCount > scenePhysX->WheelRaycastBatchQuerySize)
|
|
|
|
|
{
|
|
|
|
|
if (scenePhysX->WheelRaycastBatchQuery)
|
|
|
|
|
scenePhysX->WheelRaycastBatchQuery->release();
|
|
|
|
|
WheelQueryResults.Resize(wheelsCount, false);
|
|
|
|
|
WheelHitResults.Resize(wheelsCount, false);
|
|
|
|
|
PxBatchQueryDesc desc(wheelsCount, 0, 0);
|
|
|
|
|
desc.queryMemory.userRaycastResultBuffer = WheelQueryResults.Get();
|
|
|
|
|
desc.queryMemory.userRaycastTouchBuffer = WheelHitResults.Get();
|
|
|
|
|
desc.queryMemory.raycastTouchBufferSize = wheelsCount;
|
|
|
|
|
desc.preFilterShader = WheelRaycastPreFilter;
|
|
|
|
|
scenePhysX->WheelRaycastBatchQuery = scenePhysX->Scene->createBatchQuery(desc);
|
|
|
|
|
scenePhysX->WheelRaycastBatchQuerySize = wheelsCount;
|
|
|
|
|
scenePhysX->WheelRaycastBatchQuery = PxCreateBatchQueryExt(*scenePhysX->Scene, &WheelRaycastFilter, wheelsCount, wheelsCount, 0, 0, 0, 0);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// Update lookup table that maps wheel type into the surface friction
|
|
|
|
|
@@ -1169,7 +1173,7 @@ void PhysicsBackend::EndSimulateScene(void* scene)
|
|
|
|
|
// Update vehicles
|
|
|
|
|
if (WheelVehiclesCache.Count() != 0)
|
|
|
|
|
{
|
|
|
|
|
PxVehicleSuspensionRaycasts(scenePhysX->WheelRaycastBatchQuery, WheelVehiclesCache.Count(), WheelVehiclesCache.Get(), WheelQueryResults.Count(), WheelQueryResults.Get());
|
|
|
|
|
PxVehicleSuspensionRaycasts(scenePhysX->WheelRaycastBatchQuery, WheelVehiclesCache.Count(), WheelVehiclesCache.Get());
|
|
|
|
|
PxVehicleUpdates(scenePhysX->LastDeltaTime, scenePhysX->Scene->getGravity(), *WheelTireFrictions, WheelVehiclesCache.Count(), WheelVehiclesCache.Get(), WheelVehiclesResultsPerVehicle.Get());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -2045,7 +2049,7 @@ bool PhysicsBackend::ComputeShapesPenetration(void* shapeA, void* shapeB, const
|
|
|
|
|
const PxTransform poseA(C2P(positionA), C2P(orientationA));
|
|
|
|
|
const PxTransform poseB(C2P(positionB), C2P(orientationB));
|
|
|
|
|
PxVec3 dir = C2P(direction);
|
|
|
|
|
const bool result = PxGeometryQuery::computePenetration(dir, distance, shapeAPhysX->getGeometry().any(), poseA, shapeBPhysX->getGeometry().any(), poseB);
|
|
|
|
|
const bool result = PxGeometryQuery::computePenetration(dir, distance, shapeAPhysX->getGeometry(), poseA, shapeBPhysX->getGeometry(), poseB);
|
|
|
|
|
direction = P2C(dir);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
@@ -2054,7 +2058,7 @@ float PhysicsBackend::ComputeShapeSqrDistanceToPoint(void* shape, const Vector3&
|
|
|
|
|
{
|
|
|
|
|
auto shapePhysX = (PxShape*)shape;
|
|
|
|
|
const PxTransform trans(C2P(position), C2P(orientation));
|
|
|
|
|
return PxGeometryQuery::pointDistance(C2P(point), shapePhysX->getGeometry().any(), trans, (PxVec3*)closestPoint);
|
|
|
|
|
return PxGeometryQuery::pointDistance(C2P(point), shapePhysX->getGeometry(), trans, (PxVec3*)closestPoint);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool PhysicsBackend::RayCastShape(void* shape, const Vector3& position, const Quaternion& orientation, const Vector3& origin, const Vector3& direction, float& resultHitDistance, float maxDistance)
|
|
|
|
|
@@ -2064,7 +2068,7 @@ bool PhysicsBackend::RayCastShape(void* shape, const Vector3& position, const Qu
|
|
|
|
|
const PxTransform trans(C2P(position - sceneOrigin), C2P(orientation));
|
|
|
|
|
const PxHitFlags hitFlags = (PxHitFlags)0;
|
|
|
|
|
PxRaycastHit hit;
|
|
|
|
|
if (PxGeometryQuery::raycast(C2P(origin - sceneOrigin), C2P(direction), shapePhysX->getGeometry().any(), trans, maxDistance, hitFlags, 1, &hit) != 0)
|
|
|
|
|
if (PxGeometryQuery::raycast(C2P(origin - sceneOrigin), C2P(direction), shapePhysX->getGeometry(), trans, maxDistance, hitFlags, 1, &hit) != 0)
|
|
|
|
|
{
|
|
|
|
|
resultHitDistance = hit.distance;
|
|
|
|
|
return true;
|
|
|
|
|
@@ -2079,7 +2083,7 @@ bool PhysicsBackend::RayCastShape(void* shape, const Vector3& position, const Qu
|
|
|
|
|
const PxTransform trans(C2P(position - sceneOrigin), C2P(orientation));
|
|
|
|
|
const PxHitFlags hitFlags = PxHitFlag::ePOSITION | PxHitFlag::eNORMAL | PxHitFlag::eFACE_INDEX | PxHitFlag::eUV;
|
|
|
|
|
PxRaycastHit hit;
|
|
|
|
|
if (PxGeometryQuery::raycast(C2P(origin - sceneOrigin), C2P(direction), shapePhysX->getGeometry().any(), trans, maxDistance, hitFlags, 1, &hit) == 0)
|
|
|
|
|
if (PxGeometryQuery::raycast(C2P(origin - sceneOrigin), C2P(direction), shapePhysX->getGeometry(), trans, maxDistance, hitFlags, 1, &hit) == 0)
|
|
|
|
|
return false;
|
|
|
|
|
P2C(hit, hitInfo);
|
|
|
|
|
hitInfo.Point += sceneOrigin;
|
|
|
|
|
@@ -2905,7 +2909,8 @@ void* PhysicsBackend::CreateConvexMesh(byte* data, int32 dataSize, BoundingBox&
|
|
|
|
|
{
|
|
|
|
|
PxDefaultMemoryInputData input(data, dataSize);
|
|
|
|
|
PxConvexMesh* convexMesh = PhysX->createConvexMesh(input);
|
|
|
|
|
localBounds = P2C(convexMesh->getLocalBounds());
|
|
|
|
|
if (convexMesh)
|
|
|
|
|
localBounds = P2C(convexMesh->getLocalBounds());
|
|
|
|
|
return convexMesh;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
@@ -2913,7 +2918,8 @@ void* PhysicsBackend::CreateTriangleMesh(byte* data, int32 dataSize, BoundingBox
|
|
|
|
|
{
|
|
|
|
|
PxDefaultMemoryInputData input(data, dataSize);
|
|
|
|
|
PxTriangleMesh* triangleMesh = PhysX->createTriangleMesh(input);
|
|
|
|
|
localBounds = P2C(triangleMesh->getLocalBounds());
|
|
|
|
|
if (triangleMesh)
|
|
|
|
|
localBounds = P2C(triangleMesh->getLocalBounds());
|
|
|
|
|
return triangleMesh;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|