diff --git a/Source/Engine/Physics/CollisionData.cpp b/Source/Engine/Physics/CollisionData.cpp index d73b760af..36f28c111 100644 --- a/Source/Engine/Physics/CollisionData.cpp +++ b/Source/Engine/Physics/CollisionData.cpp @@ -268,18 +268,28 @@ CollisionData::LoadResult CollisionData::load(const SerializedOptions* options, if (dataSize <= 0) return LoadResult::InvalidData; - // Create PhysX object + // Create physics object if (_options.Type == CollisionDataType::ConvexMesh) { _convexMesh = PhysicsBackend::CreateConvexMesh(dataPtr, dataSize, _options.Box); + if (!_convexMesh) + { + LOG(Error, "Failed to create convex mesh"); + return LoadResult::Failed; + } } else if (_options.Type == CollisionDataType::TriangleMesh) { _triangleMesh = PhysicsBackend::CreateTriangleMesh(dataPtr, dataSize, _options.Box); + if (!_triangleMesh) + { + LOG(Error, "Failed to create triangle mesh"); + return LoadResult::Failed; + } } else { - LOG(Warning, "Invalid collision data type."); + LOG(Error, "Invalid collision data type."); return LoadResult::InvalidData; } } diff --git a/Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp b/Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp index 3863d2c13..91e795a83 100644 --- a/Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp +++ b/Source/Engine/Physics/PhysX/PhysicsBackendPhysX.cpp @@ -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 Actions; #if WITH_VEHICLE Array 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 WheelVehiclesCache; - Array WheelQueryResults; - Array WheelHitResults; Array WheelVehiclesResultsPerWheel; Array WheelVehiclesResultsPerVehicle; PxVehicleDrivableSurfaceToTireFrictionPairs* WheelTireFrictions = nullptr; bool WheelTireFrictionsDirty = false; Array 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(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; } diff --git a/Source/Engine/Physics/PhysX/PhysicsStepperPhysX.cpp b/Source/Engine/Physics/PhysX/PhysicsStepperPhysX.cpp index a7ba06296..6e7660511 100644 --- a/Source/Engine/Physics/PhysX/PhysicsStepperPhysX.cpp +++ b/Source/Engine/Physics/PhysX/PhysicsStepperPhysX.cpp @@ -32,7 +32,7 @@ bool MultiThreadStepper::advance(PxScene* scene, PxReal dt, void* scratchBlock, mScratchBlockSize = scratchBlockSize; if (!mSync) - mSync = New(); + mSync = New(); substepStrategy(dt, mNbSubSteps, mSubStepSize); diff --git a/Source/Engine/Physics/PhysX/PhysicsStepperPhysX.h b/Source/Engine/Physics/PhysX/PhysicsStepperPhysX.h index 1b616eac2..5c62a6fa3 100644 --- a/Source/Engine/Physics/PhysX/PhysicsStepperPhysX.h +++ b/Source/Engine/Physics/PhysX/PhysicsStepperPhysX.h @@ -7,7 +7,7 @@ #include "Types.h" #include #include -#include +#include class MultiThreadStepper; @@ -135,7 +135,7 @@ protected: StepperTaskSimulate mSimulateTask; StepperTask mCompletion0, mCompletion1; PxScene* mScene; - shdfnd::Sync* mSync; + PxSync* mSync; PxU32 mCurrentSubStep; PxU32 mNbSubSteps; diff --git a/Source/Engine/Physics/PhysX/Types.h b/Source/Engine/Physics/PhysX/Types.h index ed570867d..d95d6b140 100644 --- a/Source/Engine/Physics/PhysX/Types.h +++ b/Source/Engine/Physics/PhysX/Types.h @@ -21,16 +21,44 @@ namespace physx { + template + class PxVec2T; + typedef PxVec2T PxVec2; + + template + class PxVec3T; + typedef PxVec3T PxVec3; + + template + class PxVec4T; + typedef PxVec4T PxVec4; + + template + class PxQuatT; + typedef PxQuatT PxQuat; + + template + class PxMat33T; + typedef PxMat33T PxMat33; + + template + class PxMat34T; + typedef PxMat34T PxMat34; + + template + class PxMat44T; + typedef PxMat44T PxMat44; + + template + class PxTransformT; + typedef PxTransformT PxTransform; + class PxScene; class PxConvexMesh; class PxTriangleMesh; class PxCooking; class PxPhysics; - class PxVec3; - class PxVec4; - class PxTransform; class PxJoint; - class PxMat44; class PxCpuDispatcher; class PxGpuDispatcher; class PxSimulationEventCallback; @@ -55,6 +83,8 @@ namespace physx class PxQueryFilterCallback; class PxControllerFilterCallback; class PxHeightField; + class PxPlane; + class PxBounds3; struct PxFilterData; struct PxRaycastHit; struct PxSweepHit; diff --git a/Source/Engine/Physics/Physics.cpp b/Source/Engine/Physics/Physics.cpp index 0a0178622..30d5cbe0c 100644 --- a/Source/Engine/Physics/Physics.cpp +++ b/Source/Engine/Physics/Physics.cpp @@ -56,7 +56,6 @@ void PhysicsSettings::Deserialize(DeserializeStream& stream, ISerializeModifier* DESERIALIZE(FrictionCombineMode); DESERIALIZE(RestitutionCombineMode); DESERIALIZE(DisableCCD); - DESERIALIZE(EnableAdaptiveForce); DESERIALIZE(MaxDeltaTime); DESERIALIZE(EnableSubstepping); DESERIALIZE(SubstepDeltaTime); diff --git a/Source/Engine/Physics/PhysicsSettings.h b/Source/Engine/Physics/PhysicsSettings.h index c90d50c42..1533665e8 100644 --- a/Source/Engine/Physics/PhysicsSettings.h +++ b/Source/Engine/Physics/PhysicsSettings.h @@ -43,12 +43,6 @@ public: API_FIELD(Attributes="EditorOrder(70), EditorDisplay(\"Simulation\")") bool DisableCCD = false; - /// - /// Enables adaptive forces to accelerate convergence of the solver. Can improve physics simulation performance but lead to artifacts. - /// - API_FIELD(Attributes="EditorOrder(80), EditorDisplay(\"Simulation\")") - bool EnableAdaptiveForce = false; - /// /// The maximum allowed delta time (in seconds) for the physics simulation step. /// diff --git a/Source/Engine/Terrain/TerrainPatch.cpp b/Source/Engine/Terrain/TerrainPatch.cpp index e7889049a..d98827ce1 100644 --- a/Source/Engine/Terrain/TerrainPatch.cpp +++ b/Source/Engine/Terrain/TerrainPatch.cpp @@ -892,7 +892,7 @@ bool TerrainPatch::SetupHeightMap(int32 heightMapLength, const float* heightMap, collisionData = &tmpData; } - // Generate PhysX height field data for the runtime + // Generate physics backend height field data for the runtime if (CookCollision(info, initData, _terrain->_collisionLod, collisionData)) { return true; @@ -1853,7 +1853,7 @@ void TerrainPatch::SaveHeightData() return; } - // Generate PhysX height field data for the runtime + // Generate physics backend height field data for the runtime if (_heightfield->WaitForLoaded()) { LOG(Error, "Failed to load patch heightfield data."); diff --git a/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXCharacterKinematic_static.a b/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXCharacterKinematic_static.a deleted file mode 100644 index 5ee88ade3..000000000 --- a/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXCharacterKinematic_static.a +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:fb0b758d0e51d14ecdd18b2c55c801a7a729da06aa116c729602c7bbdc564bb9 -size 2656678 diff --git a/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXCharacterKinematic_static_64.a b/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXCharacterKinematic_static_64.a new file mode 100644 index 000000000..884943f02 --- /dev/null +++ b/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXCharacterKinematic_static_64.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:5c07afaaa62724f7f8f532a1bc65a5fc50753e266495248a608d9f4b9476aa0b +size 2025020 diff --git a/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXCommon_static.a b/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXCommon_static.a deleted file mode 100644 index f4f65287e..000000000 --- a/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXCommon_static.a +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:299ece94b714429fcb541599927daec994919fbb87bcee4345f1f1a6b43ba548 -size 48900330 diff --git a/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXCommon_static_64.a b/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXCommon_static_64.a new file mode 100644 index 000000000..59899248c --- /dev/null +++ b/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXCommon_static_64.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:9817730bdeae1cfeb5207470d721b27f448cdd36b9eba85da73dec59e8a5bf99 +size 52205712 diff --git a/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXCooking_static.a b/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXCooking_static.a deleted file mode 100644 index d34e0c5e5..000000000 --- a/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXCooking_static.a +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:067245b08a742cc488503300a78c7c7c2975b5b13d2a072b041480dc6d9eb55c -size 3900056 diff --git a/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXCooking_static_64.a b/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXCooking_static_64.a new file mode 100644 index 000000000..37e24dc4c --- /dev/null +++ b/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXCooking_static_64.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:524ded53592c687bc834c9db24c6ccfa8449f3392ec3fd99627c87cf7f069368 +size 111200 diff --git a/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXExtensions_static.a b/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXExtensions_static.a deleted file mode 100644 index 02c14d19e..000000000 --- a/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXExtensions_static.a +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6e4b27fec3205418a57f118dab8afe86a7cc4427c9a14298fc0579ed38bb8aa5 -size 25755118 diff --git a/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXExtensions_static_64.a b/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXExtensions_static_64.a new file mode 100644 index 000000000..b13b12074 --- /dev/null +++ b/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXExtensions_static_64.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:759aa0379faa5f010c66654e46d352f24c1f837507ffa0178022546540f4ca0f +size 31683652 diff --git a/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXFoundation_static.a b/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXFoundation_static.a deleted file mode 100644 index bb19eabdd..000000000 --- a/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXFoundation_static.a +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bad24dff285b711e7fd8bfa79fac21e7536158e02a5c995e8f970bd359ffc3dd -size 755994 diff --git a/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXFoundation_static_64.a b/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXFoundation_static_64.a new file mode 100644 index 000000000..dedea10bc --- /dev/null +++ b/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXFoundation_static_64.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:426053c4e44445b7d4e57d843b7d12f48c93b85ae3a29086e2f29f5965986fad +size 570452 diff --git a/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXPvdSDK_static.a b/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXPvdSDK_static.a deleted file mode 100644 index 56c1149b2..000000000 --- a/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXPvdSDK_static.a +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4e44058be0cd48106fee815ac2e472ad1f6897725464d7ae49eff61a954891a4 -size 4188330 diff --git a/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXPvdSDK_static_64.a b/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXPvdSDK_static_64.a new file mode 100644 index 000000000..e681dfc1b --- /dev/null +++ b/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXPvdSDK_static_64.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7369e2822a705f592c67942c0ba354694b857fa9d83db6bed4dc0dcf3a4875f0 +size 3405028 diff --git a/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXVehicle_static.a b/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXVehicle_static.a deleted file mode 100644 index 67e626f3f..000000000 --- a/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXVehicle_static.a +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:c3b2ffb1343ff8246833c364010bea8f496b6965b0aa66ccc53edb771022df27 -size 13785474 diff --git a/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXVehicle_static_64.a b/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXVehicle_static_64.a new file mode 100644 index 000000000..815ea1e4a --- /dev/null +++ b/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysXVehicle_static_64.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4eff2cf32d6bfed5f32d26b5478ec4e1eda31d3959e71f79fa6e205905b1e67c +size 12277380 diff --git a/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysX_static.a b/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysX_static.a deleted file mode 100644 index e9ed78ee0..000000000 --- a/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysX_static.a +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f391f69d9692ca06710d489089da7a00978028918af1e7c4e8c5d9239a03a423 -size 97447380 diff --git a/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysX_static_64.a b/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysX_static_64.a new file mode 100644 index 000000000..a37ba9028 --- /dev/null +++ b/Source/Platforms/Android/Binaries/ThirdParty/ARM64/libPhysX_static_64.a @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ee3f4e2cc3160b7556dd8678c49f27160d401fbef729c81568dbc184b07fbab5 +size 37483230 diff --git a/Source/Platforms/Linux/Binaries/ThirdParty/x64/libPhysXCharacterKinematic_static_64.a b/Source/Platforms/Linux/Binaries/ThirdParty/x64/libPhysXCharacterKinematic_static_64.a deleted file mode 100644 index c0dad1db7..000000000 --- a/Source/Platforms/Linux/Binaries/ThirdParty/x64/libPhysXCharacterKinematic_static_64.a +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:00b720d5334a37b789279ef6b722ae7caab196e81c7aa87c631d42f10a1b00ad -size 275100 diff --git a/Source/Platforms/Linux/Binaries/ThirdParty/x64/libPhysXCommon_static_64.a b/Source/Platforms/Linux/Binaries/ThirdParty/x64/libPhysXCommon_static_64.a deleted file mode 100644 index f375e25b2..000000000 --- a/Source/Platforms/Linux/Binaries/ThirdParty/x64/libPhysXCommon_static_64.a +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:06746bc2ab705240b02acb57343c04d300ab631764284e6d739ad18f68e9c5e8 -size 3427120 diff --git a/Source/Platforms/Linux/Binaries/ThirdParty/x64/libPhysXCooking_static_64.a b/Source/Platforms/Linux/Binaries/ThirdParty/x64/libPhysXCooking_static_64.a deleted file mode 100644 index 1d53a5a11..000000000 --- a/Source/Platforms/Linux/Binaries/ThirdParty/x64/libPhysXCooking_static_64.a +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:763898108b13a0b9a893116fabf9b19fd965cff562b53cfb2efa5065e260e042 -size 472564 diff --git a/Source/Platforms/Linux/Binaries/ThirdParty/x64/libPhysXExtensions_static_64.a b/Source/Platforms/Linux/Binaries/ThirdParty/x64/libPhysXExtensions_static_64.a deleted file mode 100644 index ca3082211..000000000 --- a/Source/Platforms/Linux/Binaries/ThirdParty/x64/libPhysXExtensions_static_64.a +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a59c674702234d870023cff9116d8efb28a46909fda667131b86c673ef4d77f9 -size 2695786 diff --git a/Source/Platforms/Linux/Binaries/ThirdParty/x64/libPhysXFoundation_static_64.a b/Source/Platforms/Linux/Binaries/ThirdParty/x64/libPhysXFoundation_static_64.a deleted file mode 100644 index 32454526c..000000000 --- a/Source/Platforms/Linux/Binaries/ThirdParty/x64/libPhysXFoundation_static_64.a +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8d67b436ca3aae026cab321a7903d9129edfaee0e505445daf177c291bebd93c -size 124634 diff --git a/Source/Platforms/Linux/Binaries/ThirdParty/x64/libPhysXPvdSDK_static_64.a b/Source/Platforms/Linux/Binaries/ThirdParty/x64/libPhysXPvdSDK_static_64.a deleted file mode 100644 index 6bdc9ed2a..000000000 --- a/Source/Platforms/Linux/Binaries/ThirdParty/x64/libPhysXPvdSDK_static_64.a +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:57ed89feefb710a61a1cf7febdfa841702b49a786e3fb9dc4cb56e6f8b14565d -size 522950 diff --git a/Source/Platforms/Linux/Binaries/ThirdParty/x64/libPhysXVehicle_static_64.a b/Source/Platforms/Linux/Binaries/ThirdParty/x64/libPhysXVehicle_static_64.a deleted file mode 100644 index 76f988461..000000000 --- a/Source/Platforms/Linux/Binaries/ThirdParty/x64/libPhysXVehicle_static_64.a +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3fa5897e9bdd806ba15c372caed3d4c2e095305584af19a8a4ad159010159c63 -size 1180008 diff --git a/Source/Platforms/Linux/Binaries/ThirdParty/x64/libPhysX_static_64.a b/Source/Platforms/Linux/Binaries/ThirdParty/x64/libPhysX_static_64.a deleted file mode 100644 index 33641cf8b..000000000 --- a/Source/Platforms/Linux/Binaries/ThirdParty/x64/libPhysX_static_64.a +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:87c0afbb01ce9d8fba8073e16c757c7d23b422d3298c481ee1ebe1fd5398c5c7 -size 6304412 diff --git a/Source/Platforms/Mac/Binaries/ThirdParty/x64/libPhysXCharacterKinematic_static_64.a b/Source/Platforms/Mac/Binaries/ThirdParty/x64/libPhysXCharacterKinematic_static_64.a deleted file mode 100644 index 1d3731f16..000000000 --- a/Source/Platforms/Mac/Binaries/ThirdParty/x64/libPhysXCharacterKinematic_static_64.a +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2cf7081f324d5bf8e967c8d48c4da241c08ba66445f748bd015047777f3445f4 -size 215640 diff --git a/Source/Platforms/Mac/Binaries/ThirdParty/x64/libPhysXCommon_static_64.a b/Source/Platforms/Mac/Binaries/ThirdParty/x64/libPhysXCommon_static_64.a deleted file mode 100644 index 4fc99bdb5..000000000 --- a/Source/Platforms/Mac/Binaries/ThirdParty/x64/libPhysXCommon_static_64.a +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4ec2a657d5477a68001a50e9aefe72f6d841aaba821dbb93a43d616977f88977 -size 2753520 diff --git a/Source/Platforms/Mac/Binaries/ThirdParty/x64/libPhysXCooking_static_64.a b/Source/Platforms/Mac/Binaries/ThirdParty/x64/libPhysXCooking_static_64.a deleted file mode 100644 index 5657e7133..000000000 --- a/Source/Platforms/Mac/Binaries/ThirdParty/x64/libPhysXCooking_static_64.a +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:f4086238bce0ad9af66b138a73985791527d93d1bc9d9704446850aaf8ea7a7c -size 368640 diff --git a/Source/Platforms/Mac/Binaries/ThirdParty/x64/libPhysXExtensions_static_64.a b/Source/Platforms/Mac/Binaries/ThirdParty/x64/libPhysXExtensions_static_64.a deleted file mode 100644 index e0c15aee3..000000000 --- a/Source/Platforms/Mac/Binaries/ThirdParty/x64/libPhysXExtensions_static_64.a +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:30ad63973d25d799e8e3dcd35442a277fa71ba7f7cd77f30ef261b186bc42c1f -size 2072848 diff --git a/Source/Platforms/Mac/Binaries/ThirdParty/x64/libPhysXFoundation_static_64.a b/Source/Platforms/Mac/Binaries/ThirdParty/x64/libPhysXFoundation_static_64.a deleted file mode 100644 index 891dda9f0..000000000 --- a/Source/Platforms/Mac/Binaries/ThirdParty/x64/libPhysXFoundation_static_64.a +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bd337d353b0a27b8ef7931540f00abb033fdaaa3199d02fbc09165bd0ebe990e -size 95112 diff --git a/Source/Platforms/Mac/Binaries/ThirdParty/x64/libPhysXPvdSDK_static_64.a b/Source/Platforms/Mac/Binaries/ThirdParty/x64/libPhysXPvdSDK_static_64.a deleted file mode 100644 index 1baf0d321..000000000 --- a/Source/Platforms/Mac/Binaries/ThirdParty/x64/libPhysXPvdSDK_static_64.a +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1ce7094a88ae99a4f0376d10a3c6350b63528c8c434bbf6ea4e840950082113e -size 383880 diff --git a/Source/Platforms/Mac/Binaries/ThirdParty/x64/libPhysXVehicle_static_64.a b/Source/Platforms/Mac/Binaries/ThirdParty/x64/libPhysXVehicle_static_64.a deleted file mode 100644 index 55093ddad..000000000 --- a/Source/Platforms/Mac/Binaries/ThirdParty/x64/libPhysXVehicle_static_64.a +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ceedf1ee2493bcbffe2ffbad59344df064613bc751e897d33d2af725b98b3eea -size 960504 diff --git a/Source/Platforms/Mac/Binaries/ThirdParty/x64/libPhysX_static_64.a b/Source/Platforms/Mac/Binaries/ThirdParty/x64/libPhysX_static_64.a deleted file mode 100644 index bfaf1a4fa..000000000 --- a/Source/Platforms/Mac/Binaries/ThirdParty/x64/libPhysX_static_64.a +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:a01e2f6a00c434fac09608791fad9bbcc0bdfbcf3ab6c4b33fca466f765c1f7f -size 4919264 diff --git a/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXCharacterKinematic_static_64.lib b/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXCharacterKinematic_static_64.lib deleted file mode 100644 index c888ffd30..000000000 --- a/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXCharacterKinematic_static_64.lib +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:0571528452727fee3a549ed5af34e8e490f2fc110242c31c9e2d7ddc83233994 -size 1160130 diff --git a/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXCharacterKinematic_static_64.pdb b/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXCharacterKinematic_static_64.pdb deleted file mode 100644 index 435dfa81b..000000000 --- a/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXCharacterKinematic_static_64.pdb +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b161b975752a45a3f2962253e60acd1d6dfc537fc1eb79901dc816ea46b52a98 -size 602112 diff --git a/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXCommon_static_64.lib b/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXCommon_static_64.lib deleted file mode 100644 index 5f72568a4..000000000 --- a/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXCommon_static_64.lib +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d87ec531014f81cb37b856c1dee7d6aaceefb0fc0df845bad11a684c760ebb9e -size 17406032 diff --git a/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXCommon_static_64.pdb b/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXCommon_static_64.pdb deleted file mode 100644 index 623b3dee2..000000000 --- a/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXCommon_static_64.pdb +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d0a565064744bca4e999549a7c4ff9c4b409c95323499386b2dbf9f471119ccf -size 1052672 diff --git a/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXCooking_static_64.lib b/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXCooking_static_64.lib deleted file mode 100644 index b5ecda9d7..000000000 --- a/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXCooking_static_64.lib +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4829f63d35c4a13fb74b76434034ce5c31088a1d20962f6a3ace8da48195c908 -size 1895882 diff --git a/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXCooking_static_64.pdb b/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXCooking_static_64.pdb deleted file mode 100644 index 5cb4419ab..000000000 --- a/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXCooking_static_64.pdb +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2c6c8f83a948442b243dfe964f441e235c0c7b9a82d5eb66c51e0c3e0b39d8bf -size 634880 diff --git a/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXExtensions_static_64.lib b/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXExtensions_static_64.lib deleted file mode 100644 index 8498518d4..000000000 --- a/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXExtensions_static_64.lib +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7827629e569c2fecb9a8297540e2fd96a0096cfe7e11021f39b094220416e82e -size 9502710 diff --git a/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXExtensions_static_64.pdb b/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXExtensions_static_64.pdb deleted file mode 100644 index 5e4f7f7bd..000000000 --- a/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXExtensions_static_64.pdb +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:23b4209baa69da95ed349b29a09cb40cc58bd1dcc107ec7eba2c4c5a59c0e285 -size 3461120 diff --git a/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXFoundation_static_64.lib b/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXFoundation_static_64.lib deleted file mode 100644 index 7793462ae..000000000 --- a/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXFoundation_static_64.lib +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:29ceab6e7982a7eee1fcb08bcbd14da2c5eb5db2cf2baf3e7b3f3877ea2af6f8 -size 953572 diff --git a/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXFoundation_static_64.pdb b/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXFoundation_static_64.pdb deleted file mode 100644 index d0e993c4e..000000000 --- a/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXFoundation_static_64.pdb +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4b5776536edb32d48cb260715bc300cf62bbb3cd633422c28f89f8bbdc9b0bef -size 397312 diff --git a/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXPvdSDK_static_64.lib b/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXPvdSDK_static_64.lib deleted file mode 100644 index 04a12cc7d..000000000 --- a/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXPvdSDK_static_64.lib +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b1abc62ab207c381493d527ade096ca18bd5fdfb95de261cb3a786c93d475abd -size 1940572 diff --git a/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXPvdSDK_static_64.pdb b/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXPvdSDK_static_64.pdb deleted file mode 100644 index e791352df..000000000 --- a/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXPvdSDK_static_64.pdb +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b216451e6c8709b8cfbe9c4500fc8c99cafea96e79c5977fa464f7f92eeb4543 -size 921600 diff --git a/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXVehicle_static_64.lib b/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXVehicle_static_64.lib deleted file mode 100644 index f03c17fb7..000000000 --- a/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXVehicle_static_64.lib +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1ac6081bd15cc37822b7cf9bf3cb7e58ece2855d28ced1fff400d11943e951ce -size 5114896 diff --git a/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXVehicle_static_64.pdb b/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXVehicle_static_64.pdb deleted file mode 100644 index f638c05a1..000000000 --- a/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysXVehicle_static_64.pdb +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:09fd3bab5ff2ee97a29e0ba3f926874afe2498ba2093c4b872b1c4adf5f904cd -size 3125248 diff --git a/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysX_static_64.lib b/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysX_static_64.lib deleted file mode 100644 index ce8e79f48..000000000 --- a/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysX_static_64.lib +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:23f9743ffe79198c2f477de893d2c858d328f401e6f59ed1e93fce136bf84e48 -size 28750814 diff --git a/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysX_static_64.pdb b/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysX_static_64.pdb deleted file mode 100644 index 831c56eb0..000000000 --- a/Source/Platforms/UWP/Binaries/ThirdParty/x64/PhysX_static_64.pdb +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:92c07fb1ddd180374be99bd9e119600afd5e38639f43a78c9e40d818f18e39d4 -size 3518464 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/FastXml_64.pdb b/Source/Platforms/Windows/Binaries/ThirdParty/x64/FastXml_64.pdb index fb7641343..1d188f62f 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/FastXml_64.pdb +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/FastXml_64.pdb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6f750ddb111526b83b5613a3831a662ad4c1e3ea59af3ed77958953d9b8daf4d -size 102400 +oid sha256:6ca4be11982ae6754b9927fc8d4ab3c04d29a530b146416ec9bce6b6b11baa1c +size 118784 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/LowLevelAABB_64.pdb b/Source/Platforms/Windows/Binaries/ThirdParty/x64/LowLevelAABB_64.pdb index 1d95f1e7e..cceac7991 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/LowLevelAABB_64.pdb +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/LowLevelAABB_64.pdb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6fd6a4071042e5d89d5309383b78b55c15e4eac473da3fd38f3b9a4fc68778ce -size 618496 +oid sha256:04a182876dfbe9e27831c45f11aa5f4e165a21d7bced5d1e792594944708a0fc +size 593920 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/LowLevelDynamics_64.pdb b/Source/Platforms/Windows/Binaries/ThirdParty/x64/LowLevelDynamics_64.pdb index 214dd67f9..1ad63a052 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/LowLevelDynamics_64.pdb +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/LowLevelDynamics_64.pdb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ec9dfc61ef830e7c60f17207c8dc6e16bbae5edebd2857fa765e70f97ad4c308 -size 1183744 +oid sha256:a6e8036243ae74ed8c6db612af90b3e0b0dfc8ba926ca8abc93954f24c6d92bf +size 1339392 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/LowLevel_64.pdb b/Source/Platforms/Windows/Binaries/ThirdParty/x64/LowLevel_64.pdb index 6984ff3cc..df91b0910 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/LowLevel_64.pdb +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/LowLevel_64.pdb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:14a04e5a22a3160788575e9a90d1c342f1ca659b2a68d62971d20fd19c4fd3d7 -size 1003520 +oid sha256:dcdd2cabfaeb8fe69c47fbf8c0aa15741d2ed5d4b97df406059fd4ecaec167be +size 1257472 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXCharacterKinematic_static_64.lib b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXCharacterKinematic_static_64.lib index 6e8a292cd..36ce33a1a 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXCharacterKinematic_static_64.lib +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXCharacterKinematic_static_64.lib @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:af188ecf8db6cdf7c674acf10a974df921cf8031db2f72e821bec6284a6df030 -size 1123270 +oid sha256:74d822966f60d0c76952b8927786e54cbcff7bed06f35e3a89b04d3cbd57959d +size 1306220 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXCharacterKinematic_static_64.pdb b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXCharacterKinematic_static_64.pdb index 358f282fa..f0650f66f 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXCharacterKinematic_static_64.pdb +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXCharacterKinematic_static_64.pdb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c30d8a01ab33c44b8fed8827bd4844f93ee2a8f5bbdb0457ea6f040c36b53c76 -size 602112 +oid sha256:8b163820ce99f7c7a0b7444ed18238b674c2b9b3eec2bfbf4bafc61c6c39e134 +size 675840 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXCommon_static_64.lib b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXCommon_static_64.lib index a9e082525..59cd9616a 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXCommon_static_64.lib +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXCommon_static_64.lib @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:69534d12a3bd51641dbeb88557a0cbc5e904d8aac691e31b75c0d61b7459c8a6 -size 16676186 +oid sha256:7577901f23a10372b22a72f98a616d2793873461ca8b508dd4c83baee2d243d4 +size 26130976 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXCommon_static_64.pdb b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXCommon_static_64.pdb index c8ebe8701..7093de251 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXCommon_static_64.pdb +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXCommon_static_64.pdb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0bed63cba17ff5fc909eb6e398f49d6d8e74650d5e99ed93a970848e64b51aad -size 1052672 +oid sha256:2c57ca4b4ef8bdc4a9da435d722ccfe8c6dec0b3611e02ba1c8a3c1bf91fff4e +size 1822720 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXCooking_static_64.lib b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXCooking_static_64.lib index 1ee0be725..967d6f078 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXCooking_static_64.lib +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXCooking_static_64.lib @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bb3edb333102f96be621b41a7436d7009ebf1bd85eec10a481bb226ff2951933 -size 1785248 +oid sha256:bfb03f07fe8baf770491faa0f48994d55bf023345d3a8851bcbaa71fc0d6c418 +size 130200 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXCooking_static_64.pdb b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXCooking_static_64.pdb index dfd47dad6..9f67a1bc7 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXCooking_static_64.pdb +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXCooking_static_64.pdb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cb03d9c045c60d9ecf336555d36e73b8f5a0013196843c579df3f3320f4293ed -size 643072 +oid sha256:f079a31113ae7f2647dac3555c5ffb6110760063f7f2d248f799336575bf1776 +size 397312 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXExtensions_static_64.lib b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXExtensions_static_64.lib index 65a0491e8..1b2702b2d 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXExtensions_static_64.lib +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXExtensions_static_64.lib @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e0c40331f0f3699de270b13e4e3902351cee4453d303267ef26efbb74ffce68d -size 11528512 +oid sha256:84e255cd3a6e8a7b5138c93e12f9213e5123fbcb0f26be3e5a15ad94dc8c3ec5 +size 17300374 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXExtensions_static_64.pdb b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXExtensions_static_64.pdb index be03ed1d4..54ec4f8ef 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXExtensions_static_64.pdb +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXExtensions_static_64.pdb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f124ce8a0c90c95530b59fb2853d719da1d1593f2b8fe028d3b124f73225254f -size 3452928 +oid sha256:d42a14cffa11e040c488f3fb4361cd25255af86c35becab87fa1e1a0c7ed1349 +size 5156864 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXFoundation_static_64.lib b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXFoundation_static_64.lib index 551d0c1b6..74d36375a 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXFoundation_static_64.lib +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXFoundation_static_64.lib @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3d835510d536e817c3af9eecd8aabf4d080280714daa3220b944ff791de8d2ba -size 401660 +oid sha256:45d16f65aa7d8df12881163048ae62b3d59a343c553c7332a9c60047e1b52889 +size 585126 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXFoundation_static_64.pdb b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXFoundation_static_64.pdb index ebc0b6a3d..e038fe7a6 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXFoundation_static_64.pdb +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXFoundation_static_64.pdb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:acf68cf96b5d43d4349e6fddb0e2a32ad8216c7a3bd30fe14303befc818dca27 -size 282624 +oid sha256:ffcde8e421c8423431c07d2ba94faa7b496c24005274943b9399c5b6794855a6 +size 299008 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXPvdSDK_static_64.lib b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXPvdSDK_static_64.lib index a3606e504..648d5813a 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXPvdSDK_static_64.lib +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXPvdSDK_static_64.lib @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:05dee85c255e798f0bfcdff521370fcc8cb744a7e962da3c2e63e4318109b92f -size 1969384 +oid sha256:e01a533081a79800fd43ad4dd4104de99c1d0de8046c4e6647aab20f809a7bfd +size 2073834 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXPvdSDK_static_64.pdb b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXPvdSDK_static_64.pdb index 94675ac83..ca3aa2cae 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXPvdSDK_static_64.pdb +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXPvdSDK_static_64.pdb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:495b53259f8b6fd8fab6d955a634d485c49c3dfd8107ea115f219e64696a3e06 -size 913408 +oid sha256:3c02b1dd54bc27adeeade030dfcecf4d97c2da7f04a9b99978be62985dd332ad +size 946176 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXTask_64.pdb b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXTask_64.pdb index 1b314f838..9f54b50fc 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXTask_64.pdb +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXTask_64.pdb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:198a0524f71154057a2de8f15d01e520ef2fc3395448bc269b2ff8cfff7bc9cf -size 135168 +oid sha256:68944495400735cd79292544cbcf19e67329dfbe441148a9250d0f54c2218808 +size 143360 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXVehicle_static_64.lib b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXVehicle_static_64.lib index 1c32f639e..4203b02c1 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXVehicle_static_64.lib +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXVehicle_static_64.lib @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d9834c255066c95f779e16821b503e5bd8ba13d6c245d1945f0b96c79f09518f -size 6573276 +oid sha256:7b91aa1f8b5708720b2f5034278e29963a58d5e9c77ce34c06d48d716de99615 +size 5843352 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXVehicle_static_64.pdb b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXVehicle_static_64.pdb index 7e7c940e0..fe9c50972 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXVehicle_static_64.pdb +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysXVehicle_static_64.pdb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:99007463b16736a56f03caed5112cdb9996c64d43fd5b725d3328a2f1f83da1c -size 3125248 +oid sha256:84bace49f8b29a5c2f5d712e5c4b450bee2c43f22fee259943b37c3371932fdc +size 3862528 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysX_static_64.lib b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysX_static_64.lib index 25369b45b..5b2e0edad 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysX_static_64.lib +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysX_static_64.lib @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a7db86e26551e2571591ad561e3b2625a4ca810537dfa80e689aaceab96b7930 -size 28035948 +oid sha256:8e7beea7fa52be9afb7a70a497bede747b993066ccd398572be79c88ec1684da +size 34826088 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysX_static_64.pdb b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysX_static_64.pdb index a518ff696..a530874e9 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysX_static_64.pdb +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/PhysX_static_64.pdb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:325986c22c99cb302edb03c328bea61e4b6650352d00ee2e0058d2034b3450d0 -size 3575808 +oid sha256:b9b08c8d24258dc2cd8fbfaa49c188f922ab81646c52bb1d81f15b95263b1a58 +size 4558848 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/SceneQuery_64.pdb b/Source/Platforms/Windows/Binaries/ThirdParty/x64/SceneQuery_64.pdb index b46ad5252..af64dd315 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/SceneQuery_64.pdb +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/SceneQuery_64.pdb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cf69c8a1ae3a867e05873fbacab78fa9d6892494282cc5bab80b0a49bc5d95f0 -size 1937408 +oid sha256:35e45499935f1fe2526d20c3fef136de9daf11b5dfa4a562c69b71e78a6ed09f +size 544768 diff --git a/Source/Platforms/Windows/Binaries/ThirdParty/x64/SimulationController_64.pdb b/Source/Platforms/Windows/Binaries/ThirdParty/x64/SimulationController_64.pdb index 62ed91d2c..02bbdeded 100644 --- a/Source/Platforms/Windows/Binaries/ThirdParty/x64/SimulationController_64.pdb +++ b/Source/Platforms/Windows/Binaries/ThirdParty/x64/SimulationController_64.pdb @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4174639bf5353187de2dca86901bd15a617ac4d16b5a8e9de42c71a92ee8cef2 -size 2191360 +oid sha256:8d3e81616d41ec4ef1cbbce89198408e8da614b0466f910ee5f095e09f48fbf6 +size 2699264 diff --git a/Source/ThirdParty/PhysX/License.txt b/Source/ThirdParty/PhysX/License.txt index f767ab7aa..c39b0b8f4 100644 --- a/Source/ThirdParty/PhysX/License.txt +++ b/Source/ThirdParty/PhysX/License.txt @@ -1,9 +1,31 @@ -Copyright (c) 2018 NVIDIA Corporation. All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: +BSD 3-Clause License -Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. +Copyright (c) 2023, NVIDIA Corporation +All rights reserved. -Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: -Neither the name of NVIDIA CORPORATION nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + * Neither the name of NVIDIA CORPORATION nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. \ No newline at end of file +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS "AS IS" AND ANY +EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/Source/ThirdParty/PhysX/PhysX.Build.cs b/Source/ThirdParty/PhysX/PhysX.Build.cs index 2e2f2ffad..631fbccf9 100644 --- a/Source/ThirdParty/PhysX/PhysX.Build.cs +++ b/Source/ThirdParty/PhysX/PhysX.Build.cs @@ -6,7 +6,7 @@ using Flax.Build; using Flax.Build.NativeCpp; /// -/// https://github.com/NVIDIAGameWorks/PhysX +/// https://github.com/NVIDIA-Omniverse/PhysX /// public class PhysX : DepsModule { @@ -27,7 +27,7 @@ public class PhysX : DepsModule { base.Setup(options); - // PhysX 4 configuration: + // PhysX configuration: // PX_BUILDSNIPPETS = False // PX_BUILDSAMPLES = False // PX_BUILDPUBLICSAMPLES = False @@ -59,14 +59,18 @@ public class PhysX : DepsModule case TargetPlatform.XboxOne: case TargetPlatform.XboxScarlett: case TargetPlatform.Mac: + case TargetPlatform.Android: switch (options.Architecture) { case TargetArchitecture.x86: + case TargetArchitecture.ARM: archPostFix = "_32"; break; case TargetArchitecture.x64: + case TargetArchitecture.ARM64: archPostFix = "_64"; break; + default: throw new InvalidArchitectureException(options.Architecture); } break; } diff --git a/Source/ThirdParty/PhysX/PxActor.h b/Source/ThirdParty/PhysX/PxActor.h index 0dfef1f8a..cb884ed69 100644 --- a/Source/ThirdParty/PhysX/PxActor.h +++ b/Source/ThirdParty/PhysX/PxActor.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_NX_ACTOR -#define PX_PHYSICS_NX_ACTOR +#ifndef PX_ACTOR_H +#define PX_ACTOR_H /** \addtogroup physics @{ @@ -49,11 +47,12 @@ class PxRigidActor; class PxRigidBody; class PxRigidStatic; class PxRigidDynamic; -class PxArticulation; class PxArticulationLink; +class PxScene; - -/** Group index which allows to specify 1- or 2-way interaction */ +/** +\brief Group index which allows to specify 1- or 2-way interaction +*/ typedef PxU8 PxDominanceGroup; // Must be < 32, PxU8. /** @@ -93,7 +92,7 @@ struct PxActorFlag \note Setting this flag will remove all constraints attached to the actor from the scene. \note If this flag is set, the following calls are forbidden: - \li PxRigidBody: setLinearVelocity(), setAngularVelocity(), addForce(), addTorque(), clearForce(), clearTorque() + \li PxRigidBody: setLinearVelocity(), setAngularVelocity(), addForce(), addTorque(), clearForce(), clearTorque(), setForceAndTorque() \li PxRigidDynamic: setKinematicTarget(), setWakeCounter(), wakeUp(), putToSleep() \par Sleeping: @@ -138,9 +137,57 @@ struct PxActorType */ eARTICULATION_LINK, - //brief internal use only! + /** + \brief A FEM-based soft body + @see PxSoftBody + */ + eSOFTBODY, + + /** + \brief A FEM-based cloth + \note In development + @see PxFEMCloth + */ + eFEMCLOTH, + + /** + \brief A PBD ParticleSystem + @see PxPBDParticleSystem + */ + ePBD_PARTICLESYSTEM, + + /** + \brief A FLIP ParticleSystem + \note In development + @see PxFLIPParticleSystem + */ + eFLIP_PARTICLESYSTEM, + + /** + \brief A MPM ParticleSystem + \note In development + @see PxMPMParticleSystem + */ + eMPM_PARTICLESYSTEM, + + /** + \brief A CUSTOM ParticleSystem + \note In development + @see PxCUSTOMParticleSystem + */ + eCUSTOM_PARTICLESYSTEM, + + /** + \brief A HairSystem + \note In development + @see PxHairSystem + */ + eHAIRSYSTEM, + + //! \brief internal use only! eACTOR_COUNT, + //! \brief internal use only! eACTOR_FORCE_DWORD = 0x7fffffff }; }; @@ -149,7 +196,6 @@ struct PxActorType \brief PxActor is the base class for the main simulation objects in the physics SDK. The actor is owned by and contained in a PxScene. - */ class PxActor : public PxBase { @@ -211,6 +257,9 @@ public: /** \brief Retrieves the axis aligned bounding box enclosing the actor. + \note It is not allowed to use this method while the simulation is running (except during PxScene::collide(), + in PxContactModifyCallback or in contact report callbacks). + \param[in] inflation Scale factor for computed world bounds. Box extents are multiplied by this value. \return The actor's bounding box. @@ -229,13 +278,12 @@ public: \param[in] flag The PxActor flag to raise(set) or clear. See #PxActorFlag. \param[in] value The boolean value to assign to the flag. - Default: PxActorFlag::eVISUALIZATION - @see PxActorFlag getActorFlags() */ virtual void setActorFlag(PxActorFlag::Enum flag, bool value) = 0; + /** - \brief sets the actor flags + \brief Sets the actor flags. See the list of flags #PxActorFlag @see PxActorFlag setActorFlag() @@ -293,7 +341,7 @@ public: virtual void setOwnerClient( PxClientID inClient ) = 0; /** - \brief Returns the owner client that was specified with at creation time. + \brief Returns the owner client that was specified at creation time. This value cannot be changed once the object is placed into the scene. diff --git a/Source/ThirdParty/PhysX/PxActorData.h b/Source/ThirdParty/PhysX/PxActorData.h new file mode 100644 index 000000000..4fe5d7feb --- /dev/null +++ b/Source/ThirdParty/PhysX/PxActorData.h @@ -0,0 +1,111 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + + +#ifndef PX_ACTOR_DATA_H +#define PX_ACTOR_DATA_H + +/** \addtogroup physics + @{ +*/ + +#include "foundation/PxVec4.h" +#include "foundation/PxQuat.h" +#include "foundation/PxFlags.h" +#include "PxNodeIndex.h" + + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + /** + \brief Identifies each type of information for retrieving from actor. + @see PxScene::applyActorData + */ + struct PxActorCacheFlag + { + enum Enum + { + eACTOR_DATA = (1 << 0), //include transform and velocity + eFORCE = (1 << 2), + eTORQUE = (1 << 3) + }; + }; + + /** + \brief Collection of set bits defined in PxActorCacheFlag. + + @see PxActorCacheFlag + */ + typedef PxFlags PxActorCacheFlags; + PX_FLAGS_OPERATORS(PxActorCacheFlag::Enum, PxU16) + + /** + \brief State of a body used when interfacing with the GPU rigid body pipeline + @see PxScene.copyBodyData() + */ + PX_ALIGN_PREFIX(16) + struct PxGpuBodyData + { + PxQuat quat; /*!< actor global pose quaternion in world frame */ + PxVec4 pos; /*!< (x,y,z members): actor global pose position in world frame */ + PxVec4 linVel; /*!< (x,y,z members): linear velocity at center of gravity in world frame */ + PxVec4 angVel; /*!< (x,y,z members): angular velocity in world frame */ + } + PX_ALIGN_SUFFIX(16); + + /** + \brief Pair correspondence used for matching array indices with body node indices + */ + PX_ALIGN_PREFIX(8) + struct PxGpuActorPair + { + PxU32 srcIndex; //Defines which index in src array we read + PxNodeIndex nodeIndex; //Defines which actor this entry in src array is updating + } + PX_ALIGN_SUFFIX(8); + + /** + \brief Maps numeric index to a data pointer. + + @see PxScene::computeDenseJacobians(), PxScene::computeGeneralizedMassMatrices(), PxScene::computeGeneralizedGravityForces(), PxScene::computeCoriolisAndCentrifugalForces() + */ + struct PxIndexDataPair + { + PxU32 index; + void* data; + }; + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/PxAggregate.h b/Source/ThirdParty/PhysX/PxAggregate.h index f794de22d..5a1cd1d43 100644 --- a/Source/ThirdParty/PhysX/PxAggregate.h +++ b/Source/ThirdParty/PhysX/PxAggregate.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_NX_AGGREGATE -#define PX_PHYSICS_NX_AGGREGATE +#ifndef PX_AGGREGATE_H +#define PX_AGGREGATE_H /** \addtogroup physics @{ @@ -38,14 +36,44 @@ #include "PxPhysXConfig.h" #include "common/PxBase.h" - #if !PX_DOXYGEN namespace physx { #endif class PxActor; -class PxBVHStructure; +class PxBVH; +class PxScene; + + struct PxAggregateType + { + enum Enum + { + eGENERIC = 0, //!< Aggregate will contain various actors of unspecified types + eSTATIC = 1, //!< Aggregate will only contain static actors + eKINEMATIC = 2 //!< Aggregate will only contain kinematic actors + }; + }; + + // PxAggregateFilterHint is used for more efficient filtering of aggregates outside of the broadphase. + // It is a combination of a PxAggregateType and a self-collision bit. + typedef PxU32 PxAggregateFilterHint; + + PX_CUDA_CALLABLE PX_FORCE_INLINE PxAggregateFilterHint PxGetAggregateFilterHint(PxAggregateType::Enum type, bool enableSelfCollision) + { + const PxU32 selfCollisionBit = enableSelfCollision ? 1 : 0; + return PxAggregateFilterHint((PxU32(type)<<1)|selfCollisionBit); + } + + PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 PxGetAggregateSelfCollisionBit(PxAggregateFilterHint hint) + { + return hint & 1; + } + + PX_CUDA_CALLABLE PX_FORCE_INLINE PxAggregateType::Enum PxGetAggregateType(PxAggregateFilterHint hint) + { + return PxAggregateType::Enum(hint>>1); + } /** \brief Class to aggregate actors into a single broad-phase entry. @@ -66,7 +94,6 @@ large number of attached shapes). @see PxActor, PxPhysics.createAggregate */ - class PxAggregate : public PxBase { public: @@ -79,7 +106,7 @@ public: to delete both the PxAggregate and its actors, it is best to release the actors first, then release the PxAggregate when it is empty. */ - virtual void release() = 0; + virtual void release() = 0; /** \brief Adds an actor to the aggregate object. @@ -92,17 +119,16 @@ public: If the actor already belongs to a scene, a warning is output and the call is ignored. You need to remove the actor from the scene first, before adding it to the aggregate. - \note When BVHStructure is provided the actor shapes are grouped together. + \note When a BVH is provided the actor shapes are grouped together. The scene query pruning structure inside PhysX SDK will store/update one bound per actor. The scene queries against such an actor will query actor - bounds and then make a local space query against the provided BVH structure, which is in - actor's local space. + bounds and then make a local space query against the provided BVH, which is in actor's local space. - \param [in] actor The actor that should be added to the aggregate - \param [in] bvhStructure BVHStructure for actor shapes. + \param [in] actor The actor that should be added to the aggregate + \param [in] bvh BVH for actor shapes. return true if success */ - virtual bool addActor(PxActor& actor, const PxBVHStructure* bvhStructure = NULL) = 0; + virtual bool addActor(PxActor& actor, const PxBVH* bvh = NULL) = 0; /** \brief Removes an actor from the aggregate object. @@ -115,7 +141,7 @@ public: \param [in] actor The actor that should be removed from the aggregate return true if success */ - virtual bool removeActor(PxActor& actor) = 0; + virtual bool removeActor(PxActor& actor) = 0; /** \brief Adds an articulation to the aggregate object. @@ -131,20 +157,20 @@ public: \param [in] articulation The articulation that should be added to the aggregate return true if success */ - virtual bool addArticulation(PxArticulationBase& articulation) = 0; + virtual bool addArticulation(PxArticulationReducedCoordinate& articulation) = 0; /** \brief Removes an articulation from the aggregate object. A warning is output if the incoming articulation does not belong to the aggregate. Otherwise the articulation is removed from the aggregate. If the aggregate belongs to a scene, the articulation is reinserted in that - scene. If you intend to delete the articulation, it is best to call #PxArticulation::release() directly. That way + scene. If you intend to delete the articulation, it is best to call #PxArticulationReducedCoordinate::release() directly. That way the articulation will be automatically removed from its aggregate (if any) and not reinserted in a scene. \param [in] articulation The articulation that should be removed from the aggregate return true if success */ - virtual bool removeArticulation(PxArticulationBase& articulation) = 0; + virtual bool removeArticulation(PxArticulationReducedCoordinate& articulation) = 0; /** \brief Returns the number of actors contained in the aggregate. @@ -155,16 +181,29 @@ public: @see PxActor getActors() */ - virtual PxU32 getNbActors() const = 0; + virtual PxU32 getNbActors() const = 0; /** \brief Retrieves max amount of actors that can be contained in the aggregate. - \return Max aggregate size. + \note PxAggregate now supports an arbitrary number of actors. This method return PX_MAX_U32 and will be + removed in a future release. + + \return Max actor size. + + @see PxPhysics::createAggregate() + @deprecated + */ + PX_DEPRECATED virtual PxU32 getMaxNbActors() const = 0; + + /** + \brief Retrieves max amount of shapes that can be contained in the aggregate. + + \return Max shape size. @see PxPhysics::createAggregate() */ - virtual PxU32 getMaxNbActors() const = 0; + virtual PxU32 getMaxNbShapes() const = 0; /** \brief Retrieve all actors contained in the aggregate. @@ -178,7 +217,7 @@ public: @see PxShape getNbShapes() */ - virtual PxU32 getActors(PxActor** userBuffer, PxU32 bufferSize, PxU32 startIndex=0) const = 0; + virtual PxU32 getActors(PxActor** userBuffer, PxU32 bufferSize, PxU32 startIndex=0) const = 0; /** \brief Retrieves the scene which this aggregate belongs to. @@ -198,8 +237,10 @@ public: virtual const char* getConcreteTypeName() const { return "PxAggregate"; } + void* userData; //!< user can assign this to whatever, usually to create a 1:1 relationship with a user object. + protected: - PX_INLINE PxAggregate(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags) {} + PX_INLINE PxAggregate(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags), userData(NULL) {} PX_INLINE PxAggregate(PxBaseFlags baseFlags) : PxBase(baseFlags) {} virtual ~PxAggregate() {} virtual bool isKindOf(const char* name) const { return !::strcmp("PxAggregate", name) || PxBase::isKindOf(name); } diff --git a/Source/ThirdParty/PhysX/PxArticulation.h b/Source/ThirdParty/PhysX/PxArticulation.h deleted file mode 100644 index 4cd51ce52..000000000 --- a/Source/ThirdParty/PhysX/PxArticulation.h +++ /dev/null @@ -1,281 +0,0 @@ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of NVIDIA CORPORATION nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. -// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. -// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - - -#ifndef PX_PHYSICS_NX_ARTICULATION -#define PX_PHYSICS_NX_ARTICULATION -/** \addtogroup physics -@{ */ - -#include "PxArticulationBase.h" - - -#if !PX_DOXYGEN -namespace physx -{ -#endif - -class PxArticulationLink; - -/** -\brief Articulation drive cache - -This cache is used for making one or more impulse applications to the articulation. - -@see PxArticulation PxArticulation.createDriveCache -*/ -class PxArticulationDriveCache -{ -protected: - PxArticulationDriveCache(); -}; - - -/** -\brief a tree structure of bodies connected by joints that is treated as a unit by the dynamics solver - -Articulations are more expensive to simulate than the equivalent collection of -PxRigidDynamic and PxJoint structures, but because the dynamics solver treats -each articulation as a single object, they are much less prone to separation and -have better support for actuation. An articulation may have at most 64 links. - -@see PxArticulationJoint PxArticulationLink PxPhysics.createArticulation -*/ - -#if PX_VC -#pragma warning(push) -#pragma warning(disable : 4435) -#endif - -class PxArticulation : public PxArticulationBase -{ -public: - - virtual void release() = 0; - - /** - \brief sets maxProjectionIterations. - - This is the maximum number of iterations to run projection on the articulation to bring - the links back together if the separation tolerance is exceeded. - - - \param[in] iterations the maximum number of projection iterations - Default: 4 - - @see getMaxProjectionIterations() - */ - virtual void setMaxProjectionIterations(PxU32 iterations) = 0; - - /** - \brief gets maxProjectionIterations. - - \return the maximum number of projection iterations - - @see setMaxProjectionIterations() - */ - - virtual PxU32 getMaxProjectionIterations() const = 0; - - /** - \brief sets separationTolerance. - - This is the maximum allowed separation of any joint in the articulation before projection is used - - Default: 0.1f, scaled by the tolerance scale - - \param[in] tolerance the separation tolerance for the articulation - - @see getSeparationTolerance() - */ - virtual void setSeparationTolerance(PxReal tolerance) = 0; - - /** - \brief gets separationTolerance. - - \return the separation tolerance - - @see setSeparationTolerance() - */ - - virtual PxReal getSeparationTolerance() const = 0; - - - /** - \brief sets the number of iterations used to compute the drive response to internal forces - - The drive model uses an iterative algorithm to determine the load on each joint of the articulation. - This is the number of iterations to use when computing response of the drive to internal forces. - - \param[in] iterations the number of iterations used to compute the drive response to internal forces. - - Default: 4 - - @see getInternalDriveIterations() - */ - virtual void setInternalDriveIterations(PxU32 iterations) = 0; - - /** - \brief gets internal driveIterations. - - \return the number of iterations used to compute the drive response to internal forces - - @see setInternalDriveIterations() - */ - - virtual PxU32 getInternalDriveIterations() const = 0; - - - /** - \brief sets the number of iterations for drive response to external forces. - - The drive model uses an iterative algorithm to determine the load on each joint of the articulation. - This is the number of iterations to use when computing response of the drive to external forces. - - \param[in] iterations the number of iterations used to compute the drive response to external forces. - - Default: 4 - - @see getExternalDriveIterations() - */ - - virtual void setExternalDriveIterations(PxU32 iterations) = 0; - - /** - \brief gets externalDriveIterations. - - \return the number of iterations used to compute the drive response to external forces - - @see setExternalDriveIterations() - */ - - virtual PxU32 getExternalDriveIterations() const = 0; - - /** - \brief create a drive cache for applying impulses which are propagated to the entire articulation - - \param[in] compliance the compliance value to use at all joints of the articulation. This is equivalent to the external compliance - parameter for articulation joints, as the impulse is treated as an external force - \param[in] driveIterations the number of iterations to use to evaluate the drive strengths - - \return a drive cache - - @see PxArticulationDriveCache updateDriveCache releaseDriveCache applyImpulse computeImpulseResponse - - \note this call may only be made on articulations that are in a scene, and may not be made during simulation - - */ - virtual PxArticulationDriveCache* - createDriveCache(PxReal compliance, PxU32 driveIterations) const = 0; - - - /** - \brief update a drive cache - - \param[in] driveCache the drive cache to update - \param[in] compliance the compliance value to use at all joints of the articulation. - \param[in] driveIterations the number of iterations to use to evaluate the drive strengths - - @see releaseDriveCache createDriveCache applyImpulse computeImpulseResponse - - \note this call may only be made on articulations that are in a scene, and may not be made during simulation - - */ - virtual void updateDriveCache(PxArticulationDriveCache& driveCache, - PxReal compliance, - PxU32 driveIterations) const = 0; - - /** - \brief release a drive cache - - \param[in] driveCache the drive cache to release - - @see createDriveCache updateDriveCache - */ - virtual void releaseDriveCache(PxArticulationDriveCache& driveCache) const = 0; - - /** - \brief apply an impulse to an entire articulation - - \param[in] link the link to which to apply the impulse - \param[in] driveCache the drive cache - \param[in] linearImpulse the linear impulse to apply - \param[in] angularImpulse the angular impulse to apply - - @see computeImpulseResponse - - \note this call may only be made on articulations that are in a scene, and may not be made during simulation - - */ - virtual void applyImpulse(PxArticulationLink* link, - const PxArticulationDriveCache& driveCache, - const PxVec3& linearImpulse, - const PxVec3& angularImpulse) = 0; - - /** - \brief determine the effect of applying an impulse to an entire articulation, without applying the impulse - - \param[in] link the link to which to apply the impulse - \param[out] linearResponse the change in linear velocity of the articulation link - \param[out] angularResponse the change in angular velocity of the articulation link - \param[in] driveCache the drive cache - \param[in] linearImpulse the linear impulse to apply - \param[in] angularImpulse the angular impulse to apply - - @see applyImpulse - - This call will wake up the articulation if it is asleep. - - \note this call may only be made on articulations that are in a scene, and may not be made during simulation - */ - - virtual void computeImpulseResponse(PxArticulationLink*link, - PxVec3& linearResponse, - PxVec3& angularResponse, - const PxArticulationDriveCache& driveCache, - const PxVec3& linearImpulse, - const PxVec3& angularImpulse) const = 0; - -protected: - PX_INLINE PxArticulation(PxType concreteType, PxBaseFlags baseFlags) : PxArticulationBase(concreteType, baseFlags){} - PX_INLINE PxArticulation(PxBaseFlags baseFlags) : PxArticulationBase(baseFlags){} - virtual ~PxArticulation() {} - -}; - -#if PX_VC -#pragma warning(pop) -#endif - -#if !PX_DOXYGEN -} // namespace physx -#endif - -/** @} */ -#endif diff --git a/Source/ThirdParty/PhysX/PxArticulationBase.h b/Source/ThirdParty/PhysX/PxArticulationBase.h deleted file mode 100644 index 66237fdbd..000000000 --- a/Source/ThirdParty/PhysX/PxArticulationBase.h +++ /dev/null @@ -1,320 +0,0 @@ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of NVIDIA CORPORATION nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. -// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. -// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - - -#ifndef PX_PHYSICS_NX_ARTICULATION_BASE -#define PX_PHYSICS_NX_ARTICULATION_BASE -/** \addtogroup physics -@{ */ - -#include "PxPhysXConfig.h" -#include "common/PxBase.h" - -#if !PX_DOXYGEN -namespace physx -{ -#endif - - class PxArticulationImpl; - - /** - \brief a tree structure of bodies connected by joints that is treated as a unit by the dynamics solver - - Articulations are more expensive to simulate than the equivalent collection of - PxRigidDynamic and PxJoint structures, but because the dynamics solver treats - each articulation as a single object, they are much less prone to separation and - have better support for actuation. An articulation may have at most 64 links. - - @see PxArticulationJoint PxArticulationLink PxPhysics.createArticulation - */ - class PxArticulationBase : public PxBase - { - public: - - /** - \brief Retrieves the scene which this articulation belongs to. - - \return Owner Scene. NULL if not part of a scene. - - @see PxScene - */ - virtual PxScene* getScene() const = 0; - - /** - \brief Sets the solver iteration counts for the articulation. - - The solver iteration count determines how accurately joints and contacts are resolved. - If you are having trouble with jointed bodies oscillating and behaving erratically, then - setting a higher position iteration count may improve their stability. - - If intersecting bodies are being depenetrated too violently, increase the number of velocity - iterations. More velocity iterations will drive the relative exit velocity of the intersecting - objects closer to the correct value given the restitution. - - \param[in] minPositionIters Number of position iterations the solver should perform for this articulation. Range: [1,255] - \param[in] minVelocityIters Number of velocity iterations the solver should perform for this articulation. Range: [1,255] - - @see getSolverIterationCounts() - */ - virtual void setSolverIterationCounts(PxU32 minPositionIters, PxU32 minVelocityIters = 1) = 0; - - /** - \brief Retrieves the solver iteration counts. - - @see setSolverIterationCounts() - */ - virtual void getSolverIterationCounts(PxU32 & minPositionIters, PxU32 & minVelocityIters) const = 0; - - /** - \brief Returns true if this articulation is sleeping. - - When an actor does not move for a period of time, it is no longer simulated in order to save time. This state - is called sleeping. However, because the object automatically wakes up when it is either touched by an awake object, - or a sleep-affecting property is changed by the user, the entire sleep mechanism should be transparent to the user. - - An articulation can only go to sleep if all links are ready for sleeping. An articulation is guaranteed to be awake - if at least one of the following holds: - - \li The wake counter is positive (see #setWakeCounter()). - \li The linear or angular velocity of any link is non-zero. - \li A non-zero force or torque has been applied to the articulation or any of its links. - - If an articulation is sleeping, the following state is guaranteed: - - \li The wake counter is zero. - \li The linear and angular velocity of all links is zero. - \li There is no force update pending. - - When an articulation gets inserted into a scene, it will be considered asleep if all the points above hold, else it will - be treated as awake. - - If an articulation is asleep after the call to PxScene::fetchResults() returns, it is guaranteed that the poses of the - links were not changed. You can use this information to avoid updating the transforms of associated of dependent objects. - - \note It is invalid to use this method if the articulation has not been added to a scene already. - - \return True if the articulation is sleeping. - - @see isSleeping() wakeUp() putToSleep() getSleepThreshold() - */ - virtual bool isSleeping() const = 0; - - /** - \brief Sets the mass-normalized energy threshold below which an articulation may go to sleep. - - The articulation will sleep if the energy of each body is below this threshold. - - \param[in] threshold Energy below which an actor may go to sleep. Range: [0, PX_MAX_F32) - - @see isSleeping() getSleepThreshold() wakeUp() putToSleep() - */ - virtual void setSleepThreshold(PxReal threshold) = 0; - - /** - \brief Returns the mass-normalized energy below which an articulation may go to sleep. - - \return The energy threshold for sleeping. - - @see isSleeping() wakeUp() putToSleep() setSleepThreshold() - */ - virtual PxReal getSleepThreshold() const = 0; - - /** - \brief Sets the mass-normalized kinetic energy threshold below which an articulation may participate in stabilization. - - Articulation whose kinetic energy divided by their mass is above this threshold will not participate in stabilization. - - This value has no effect if PxSceneFlag::eENABLE_STABILIZATION was not enabled on the PxSceneDesc. - - Default: 0.01 * PxTolerancesScale::speed * PxTolerancesScale::speed - - \param[in] threshold Energy below which an actor may participate in stabilization. Range: [0,inf) - - @see getStabilizationThreshold() PxSceneFlag::eENABLE_STABILIZATION - */ - virtual void setStabilizationThreshold(PxReal threshold) = 0; - - /** - \brief Returns the mass-normalized kinetic energy below which an articulation may participate in stabilization. - - Articulations whose kinetic energy divided by their mass is above this threshold will not participate in stabilization. - - \return The energy threshold for participating in stabilization. - - @see setStabilizationThreshold() PxSceneFlag::eENABLE_STABILIZATION - */ - virtual PxReal getStabilizationThreshold() const = 0; - - /** - \brief Sets the wake counter for the articulation. - - The wake counter value determines the minimum amount of time until the articulation can be put to sleep. Please note - that an articulation will not be put to sleep if the energy is above the specified threshold (see #setSleepThreshold()) - or if other awake objects are touching it. - - \note Passing in a positive value will wake the articulation up automatically. - - Default: 0.4 (which corresponds to 20 frames for a time step of 0.02) - - \param[in] wakeCounterValue Wake counter value. Range: [0, PX_MAX_F32) - - @see isSleeping() getWakeCounter() - */ - virtual void setWakeCounter(PxReal wakeCounterValue) = 0; - - /** - \brief Returns the wake counter of the articulation. - - \return The wake counter of the articulation. - - @see isSleeping() setWakeCounter() - */ - virtual PxReal getWakeCounter() const = 0; - - /** - \brief Wakes up the articulation if it is sleeping. - - The articulation will get woken up and might cause other touching objects to wake up as well during the next simulation step. - - \note This will set the wake counter of the articulation to the value specified in #PxSceneDesc::wakeCounterResetValue. - - \note It is invalid to use this method if the articulation has not been added to a scene already. - - @see isSleeping() putToSleep() - */ - virtual void wakeUp() = 0; - - /** - \brief Forces the articulation to sleep. - - The articulation will stay asleep during the next simulation step if not touched by another non-sleeping actor. - - \note This will set any applied force, the velocity and the wake counter of all bodies in the articulation to zero. - - \note It is invalid to use this method if the articulation has not been added to a scene already. - - @see isSleeping() wakeUp() - */ - virtual void putToSleep() = 0; - - /** - \brief adds a link to the articulation with default attribute values. - - \param[in] parent the parent link of the articulation. Should be NULL if (and only if) this is the root link - \param[in] pose the initial pose of the new link. Must be a valid transform - - \return the new link, or NULL if the link cannot be created because the articulation has reached - its maximum link count (currently 64). - - @see PxArticulationLink - */ - virtual PxArticulationLink* createLink(PxArticulationLink* parent, const PxTransform& pose) = 0; - - /** - \brief returns the number of links in the articulation - */ - virtual PxU32 getNbLinks() const = 0; - - /** - \brief returns the set of links in the articulation - - \param[in] userBuffer buffer into which to write an array of articulation link pointers - \param[in] bufferSize the size of the buffer. If this is not large enough to contain all the pointers to links, - only as many as will fit are written. - \param[in] startIndex Index of first link pointer to be retrieved - - \return the number of links written into the buffer. - - @see ArticulationLink - */ - virtual PxU32 getLinks(PxArticulationLink** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0; - - /** - \brief Sets a name string for the object that can be retrieved with getName(). - - This is for debugging and is not used by the SDK. The string is not copied by the SDK, - only the pointer is stored. - - \param[in] name String to set the objects name to. - - @see getName() - */ - virtual void setName(const char* name) = 0; - - /** - \brief Retrieves the name string set with setName(). - - \return Name string associated with object. - - @see setName() - */ - virtual const char* getName() const = 0; - - /** - \brief Retrieves the axis aligned bounding box enclosing the articulation. - - \param[in] inflation Scale factor for computed world bounds. Box extents are multiplied by this value. - - \return The articulation's bounding box. - - @see PxBounds3 - */ - virtual PxBounds3 getWorldBounds(float inflation = 1.01f) const = 0; - - /** - \brief Retrieves the aggregate the articulation might be a part of. - - \return The aggregate the articulation is a part of, or NULL if the articulation does not belong to an aggregate. - - @see PxAggregate - */ - virtual PxAggregate* getAggregate() const = 0; - - virtual PxArticulationImpl* getImpl() = 0; - virtual const PxArticulationImpl* getImpl() const = 0; - - void* userData; //!< user can assign this to whatever, usually to create a 1:1 relationship with a user object. - - virtual ~PxArticulationBase() {} - - protected: - PX_INLINE PxArticulationBase(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags), userData(NULL) {} - PX_INLINE PxArticulationBase(PxBaseFlags baseFlags) : PxBase(baseFlags) {} - - public: - virtual PxArticulationJointBase* createArticulationJoint(PxArticulationLink& parent, const PxTransform& parentFrame, PxArticulationLink& child, const PxTransform& childFrame) = 0; - virtual void releaseArticulationJoint(PxArticulationJointBase* joint) = 0; - }; - -#if !PX_DOXYGEN -} // namespace physx -#endif - - /** @} */ -#endif diff --git a/Source/ThirdParty/PhysX/PxArticulationFlag.h b/Source/ThirdParty/PhysX/PxArticulationFlag.h new file mode 100644 index 000000000..75870439d --- /dev/null +++ b/Source/ThirdParty/PhysX/PxArticulationFlag.h @@ -0,0 +1,106 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_ARTICULATION_FLAG_H +#define PX_ARTICULATION_FLAG_H + +#include "PxPhysXConfig.h" +#include "foundation/PxFlags.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + /** + \brief A description of the types of articulation data that may be directly written to and read from the GPU using the functions + PxScene::copyArticulationData() and PxScene::applyArticulationData(). Types that are read-only may only be used in conjunction with + PxScene::copyArticulationData(). Types that are write-only may only be used in conjunction with PxScene::applyArticulationData(). + A subset of data types may be used in conjunction with both PxScene::applyArticulationData() and PxScene::applyArticulationData(). + + @see PxArticulationCache, PxScene::copyArticulationData(), PxScene::applyArticulationData() + */ + class PxArticulationGpuDataType + { + public: + enum Enum + { + eJOINT_POSITION = 0, //!< The joint positions, read and write, see PxScene::copyArticulationData(), PxScene::applyArticulationData() + eJOINT_VELOCITY, //!< The joint velocities, read and write, see PxScene::copyArticulationData(), PxScene::applyArticulationData() + eJOINT_ACCELERATION, //!< The joint accelerations, read only, see PxScene::copyArticulationData() + eJOINT_FORCE, //!< The applied joint forces, write only, see PxScene::applyArticulationData() + eJOINT_SOLVER_FORCE, //!< The computed joint constraint solver forces, read only, see PxScene::copyArticulationData()() + eJOINT_TARGET_VELOCITY, //!< The velocity targets for the joint drives, write only, see PxScene::applyArticulationData() + eJOINT_TARGET_POSITION, //!< The position targets for the joint drives, write only, see PxScene::applyArticulationData() + eSENSOR_FORCE, //!< The spatial sensor forces, read only, see PxScene::copyArticulationData() + eROOT_TRANSFORM, //!< The root link transform, read and write, see PxScene::copyArticulationData(), PxScene::applyArticulationData() + eROOT_VELOCITY, //!< The root link velocity, read and write, see PxScene::copyArticulationData(), PxScene::applyArticulationData() + eLINK_TRANSFORM, //!< The link transforms including root link, read only, see PxScene::copyArticulationData() + eLINK_VELOCITY, //!< The link velocities including root link, read only, see PxScene::copyArticulationData() + eLINK_FORCE, //!< The forces to apply to links, write only, see PxScene::applyArticulationData() + eLINK_TORQUE, //!< The torques to apply to links, write only, see PxScene::applyArticulationData() + eFIXED_TENDON, //!< Fixed tendon data, write only, see PxScene::applyArticulationData() + eFIXED_TENDON_JOINT, //!< Fixed tendon joint data, write only, see PxScene::applyArticulationData() + eSPATIAL_TENDON, //!< Spatial tendon data, write only, see PxScene::applyArticulationData() + eSPATIAL_TENDON_ATTACHMENT //!< Spatial tendon attachment data, write only, see PxScene::applyArticulationData() + }; + }; + + + /** + \brief These flags determine what data is read or written to the internal articulation data via cache. + + @see PxArticulationCache PxArticulationReducedCoordinate::copyInternalStateToCache PxArticulationReducedCoordinate::applyCache + */ + class PxArticulationCacheFlag + { + public: + enum Enum + { + eVELOCITY = (1 << 0), //!< The joint velocities, see PxArticulationCache::jointVelocity. + eACCELERATION = (1 << 1), //!< The joint accelerations, see PxArticulationCache::jointAcceleration. + ePOSITION = (1 << 2), //!< The joint positions, see PxArticulationCache::jointPosition. + eFORCE = (1 << 3), //!< The joint forces, see PxArticulationCache::jointForce. + eLINK_VELOCITY = (1 << 4), //!< The link velocities, see PxArticulationCache::linkVelocity. + eLINK_ACCELERATION = (1 << 5), //!< The link accelerations, see PxArticulationCache::linkAcceleration. + eROOT_TRANSFORM = (1 << 6), //!< Root link transform, see PxArticulationCache::rootLinkData. + eROOT_VELOCITIES = (1 << 7), //!< Root link velocities (read/write) and accelerations (read), see PxArticulationCache::rootLinkData. + eSENSOR_FORCES = (1 << 8), //!< The spatial sensor forces, see PxArticulationCache::sensorForces. + eJOINT_SOLVER_FORCES = (1 << 9), //!< Solver constraint joint forces, see PxArticulationCache::jointSolverForces. + eALL = (eVELOCITY | eACCELERATION | ePOSITION | eLINK_VELOCITY | eLINK_ACCELERATION | eROOT_TRANSFORM | eROOT_VELOCITIES) + }; + }; + + typedef PxFlags PxArticulationCacheFlags; + PX_FLAGS_OPERATORS(PxArticulationCacheFlag::Enum, PxU32) + +#if !PX_DOXYGEN +} +#endif + +#endif diff --git a/Source/ThirdParty/PhysX/PxArticulationJoint.h b/Source/ThirdParty/PhysX/PxArticulationJoint.h deleted file mode 100644 index 4f5031326..000000000 --- a/Source/ThirdParty/PhysX/PxArticulationJoint.h +++ /dev/null @@ -1,495 +0,0 @@ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of NVIDIA CORPORATION nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. -// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. -// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - - -#ifndef PX_PHYSICS_NX_ARTICULATION_JOINT -#define PX_PHYSICS_NX_ARTICULATION_JOINT -/** \addtogroup physics -@{ */ - -#include "PxPhysXConfig.h" -#include "common/PxBase.h" -#include "solver/PxSolverDefs.h" - -#if !PX_DOXYGEN -namespace physx -{ -#endif - -class PxArticulationJointImpl; - -/** -\brief The type of joint drive to use for the articulation joint. - -Two drive models are currently supported. in the TARGET model, the drive spring displacement will be determined -as the rotation vector from the relative quaternion beetween child and parent, and the target quaternion. - -In the ERROR model, the drive spring displacement will be taken directly from the imaginary part of the relative -quaternion. This drive model requires more computation on the part of the application, but allows driving the joint -with a spring displacement that is more than a complete rotation. - -@see PxArticulationJoint -*/ - -struct PxArticulationJointDriveType -{ - enum Enum - { - eTARGET = 0, // use the quaternion as the drive target - eERROR = 1 // use the vector part of the quaternion as the drive error. - }; -}; - -class PxArticulationJointBase : public PxBase -{ -public: - /** - \brief get the parent articulation link to which this articulation joint belongs - - \return the articulation link to which this joint belongs - */ - virtual PxArticulationLink& getParentArticulationLink() const = 0; - - /** - \brief set the joint pose in the parent frame - - \param[in] pose the joint pose in the parent frame - Default: the identity matrix - - @see getParentPose() - */ - virtual void setParentPose(const PxTransform& pose) = 0; - - /** - \brief get the joint pose in the parent frame - - \return the joint pose in the parent frame - - @see setParentPose() - */ - virtual PxTransform getParentPose() const = 0; - - /** - \brief get the child articulation link to which this articulation joint belongs - - \return the articulation link to which this joint belongs - */ - virtual PxArticulationLink& getChildArticulationLink() const = 0; - - /** - \brief set the joint pose in the child frame - - \param[in] pose the joint pose in the child frame - Default: the identity matrix - - @see getChildPose() - */ - virtual void setChildPose(const PxTransform& pose) = 0; - - /** - \brief get the joint pose in the child frame - - \return the joint pose in the child frame - - @see setChildPose() - */ - virtual PxTransform getChildPose() const = 0; - - virtual PxArticulationJointImpl* getImpl() = 0; - virtual const PxArticulationJointImpl* getImpl() const = 0; - - virtual ~PxArticulationJointBase() {} - -private: -protected: - PX_INLINE PxArticulationJointBase(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags) {} - PX_INLINE PxArticulationJointBase(PxBaseFlags baseFlags) : PxBase(baseFlags) {} - - virtual bool isKindOf(const char* name) const { return !::strcmp("PxArticulationJointBase", name) || PxBase::isKindOf(name); } -}; - - - -/** -\brief a joint between two links in an articulation. - -The joint model is very similar to a PxSphericalJoint with swing and twist limits, -and an implicit drive model. - -@see PxArticulation PxArticulationLink -*/ - -class PxArticulationJoint : public PxArticulationJointBase -{ -public: - - /** - \brief set the target drive - - This is the target position for the joint drive, measured in the parent constraint frame. - - \param[in] orientation the target orientation for the joint - Range: a unit quaternion - Default: the identity quaternion - - @see getTargetOrientation() - */ - virtual void setTargetOrientation(const PxQuat& orientation) = 0; - - /** - \brief get the target drive position - - \return the joint drive target position - - @see setTargetOrientation() - */ - virtual PxQuat getTargetOrientation() const = 0; - - /** - \brief set the target drive velocity - - This is the target velocity for the joint drive, measured in the parent constraint frame - - \param[in] velocity the target velocity for the joint - Default: the zero vector - - @see getTargetVelocity() - */ - virtual void setTargetVelocity(const PxVec3& velocity) = 0; - - /** - \brief get the target drive velocity - - \return the target velocity for the joint - - @see setTargetVelocity() - */ - virtual PxVec3 getTargetVelocity() const = 0; - - /** - \brief set the drive type - - \param[in] driveType the drive type for the joint - Default: PxArticulationJointDriveType::eTARGET - - @see getDriveType() - */ - virtual void setDriveType(PxArticulationJointDriveType::Enum driveType) = 0; - - /** - \brief get the drive type - - \return the drive type - - @see setDriveType() - */ - virtual PxArticulationJointDriveType::Enum getDriveType() const = 0; - - /** - \brief set the drive strength of the joint acceleration spring. - - The acceleration generated by the spring drive is proportional to - this value and the angle between the drive target position and the - current position. - - \param[in] spring the spring strength of the joint - Range: [0, PX_MAX_F32)
- Default: 0.0 - - @see getStiffness() - */ - virtual void setStiffness(PxReal spring) = 0; - - /** - \brief get the drive strength of the joint acceleration spring - - \return the spring strength of the joint - - @see setStiffness() - */ - virtual PxReal getStiffness() const = 0; - - /** - \brief set the damping of the joint acceleration spring - - The acceleration generated by the spring drive is proportional to - this value and the difference between the angular velocity of the - joint and the target drive velocity. - - \param[in] damping the damping of the joint drive - Range: [0, PX_MAX_F32)
- Default: 0.0 - - @see getDamping() - */ - virtual void setDamping(PxReal damping) = 0; - - /** - \brief get the damping of the joint acceleration spring - - @see setDamping() - */ - virtual PxReal getDamping() const = 0; - - /** - \brief set the internal compliance - - Compliance determines the extent to which the joint resists acceleration. - - There are separate values for resistance to accelerations caused by external - forces such as gravity and contact forces, and internal forces generated from - other joints. - - A low compliance means that forces have little effect, a compliance of 1 means - the joint does not resist such forces at all. - - \param[in] compliance the compliance to internal forces - Range: (0, 1] - Default: 0.0 - - @see getInternalCompliance() - */ - virtual void setInternalCompliance(PxReal compliance) = 0; - - /** - \brief get the internal compliance - - \return the compliance to internal forces - - @see setInternalCompliance() - */ - virtual PxReal getInternalCompliance() const = 0; - - /** - \brief get the drive external compliance - - Compliance determines the extent to which the joint resists acceleration. - - There are separate values for resistance to accelerations caused by external - forces such as gravity and contact forces, and internal forces generated from - other joints. - - A low compliance means that forces have little effect, a compliance of 1 means - the joint does not resist such forces at all. - - \param[in] compliance the compliance to external forces - Range: (0, 1] - Default: 0.0 - - @see getExternalCompliance() - */ - virtual void setExternalCompliance(PxReal compliance) = 0; - - /** - \brief get the drive external compliance - - \return the compliance to external forces - - @see setExternalCompliance() - */ - virtual PxReal getExternalCompliance() const = 0; - - /** - \brief set the extents of the cone limit. The extents are measured in the frame - of the parent. - - Note that very small or highly elliptical limit cones may result in jitter. - - \param[in] zLimit the allowed extent of rotation around the z-axis - \param[in] yLimit the allowed extent of rotation around the y-axis - Range: ( (0, Pi), (0, Pi) ) - Default: (Pi/4, Pi/4) - - \note Please note the order of zLimit and yLimit. - */ - virtual void setSwingLimit(PxReal zLimit, PxReal yLimit) = 0; - - /** - \brief get the extents for the swing limit cone - - \param[out] zLimit the allowed extent of rotation around the z-axis - \param[out] yLimit the allowed extent of rotation around the y-axis - - \note Please note the order of zLimit and yLimit. - - @see setSwingLimit() - */ - virtual void getSwingLimit(PxReal& zLimit, PxReal& yLimit) const = 0; - - /** - \brief set the tangential spring for the limit cone - Range: ([0, PX_MAX_F32), [0, PX_MAX_F32)) - Default: (0.0, 0.0) - */ - virtual void setTangentialStiffness(PxReal spring) = 0; - - /** - \brief get the tangential spring for the swing limit cone - - \return the tangential spring - - @see setTangentialStiffness() - */ - virtual PxReal getTangentialStiffness() const = 0; - - /** - \brief set the tangential damping for the limit cone - Range: ([0, PX_MAX_F32), [0, PX_MAX_F32)) - Default: (0.0, 0.0) - */ - virtual void setTangentialDamping(PxReal damping) = 0; - - /** - \brief get the tangential damping for the swing limit cone - - \return the tangential damping - - @see setTangentialDamping() - */ - virtual PxReal getTangentialDamping() const = 0; - - /** - \brief set the contact distance for the swing limit - - The contact distance should be less than either limit angle. - - Range: [0, Pi] - Default: 0.05 radians - - @see getSwingLimitContactDistance() - */ - virtual void setSwingLimitContactDistance(PxReal contactDistance) = 0; - - /** - \brief get the contact distance for the swing limit - - \return the contact distance for the swing limit cone - - @see setSwingLimitContactDistance() - */ - virtual PxReal getSwingLimitContactDistance() const = 0; - - /** - \brief set the flag which enables the swing limit - - \param[in] enabled whether the limit is enabled - Default: false - - @see getSwingLimitEnabled() - */ - virtual void setSwingLimitEnabled(bool enabled) = 0; - - /** - \brief get the flag which enables the swing limit - - \return whether the swing limit is enabled - - @see setSwingLimitEnabled() - */ - virtual bool getSwingLimitEnabled() const = 0; - - /** - \brief set the bounds of the twistLimit - - \param[in] lower the lower extent of the twist limit - \param[in] upper the upper extent of the twist limit - Range: (-Pi, Pi) - Default: (-Pi/4, Pi/4) - - The lower limit value must be less than the upper limit if the limit is enabled - - @see getTwistLimit() - */ - virtual void setTwistLimit(PxReal lower, PxReal upper) = 0; - - /** - \brief get the bounds of the twistLimit - - \param[out] lower the lower extent of the twist limit - \param[out] upper the upper extent of the twist limit - - @see setTwistLimit() - */ - virtual void getTwistLimit(PxReal &lower, PxReal &upper) const = 0; - - /** - \brief set the flag which enables the twist limit - - \param[in] enabled whether the twist limit is enabled - Default: false - - @see getTwistLimitEnabled() - */ - virtual void setTwistLimitEnabled(bool enabled) = 0; - - /** - \brief get the twistLimitEnabled flag - - \return whether the twist limit is enabled - - @see setTwistLimitEnabled() - */ - virtual bool getTwistLimitEnabled() const = 0; - - /** - \brief set the contact distance for the swing limit - - The contact distance should be less than half the distance between the upper and lower limits. - - Range: [0, Pi) - Default: 0.05 radians - - @see getTwistLimitContactDistance() - */ - virtual void setTwistLimitContactDistance(PxReal contactDistance) = 0; - - /** - \brief get the contact distance for the swing limit - - \return the contact distance for the twist limit - - @see setTwistLimitContactDistance() - */ - virtual PxReal getTwistLimitContactDistance() const = 0; - - virtual const char* getConcreteTypeName() const { return "PxArticulationJoint"; } - -protected: - PX_INLINE PxArticulationJoint(PxType concreteType, PxBaseFlags baseFlags) : PxArticulationJointBase(concreteType, baseFlags) {} - PX_INLINE PxArticulationJoint(PxBaseFlags baseFlags) : PxArticulationJointBase(baseFlags) {} - virtual ~PxArticulationJoint() {} - virtual bool isKindOf(const char* name) const { return !::strcmp("PxArticulationJoint", name) || PxArticulationJointBase::isKindOf(name); } -}; - -#if !PX_DOXYGEN -} // namespace physx -#endif - -/** @} */ -#endif diff --git a/Source/ThirdParty/PhysX/PxArticulationJointReducedCoordinate.h b/Source/ThirdParty/PhysX/PxArticulationJointReducedCoordinate.h index bba5e3b92..4043f7464 100644 --- a/Source/ThirdParty/PhysX/PxArticulationJointReducedCoordinate.h +++ b/Source/ThirdParty/PhysX/PxArticulationJointReducedCoordinate.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,20 +22,18 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_NX_ARTICULATION_JOINT_RC -#define PX_PHYSICS_NX_ARTICULATION_JOINT_RC +#ifndef PX_ARTICULATION_JOINT_RC_H +#define PX_ARTICULATION_JOINT_RC_H /** \addtogroup physics @{ */ -#if 1 #include "PxPhysXConfig.h" #include "common/PxBase.h" -#include "PxArticulationJoint.h" +#include "solver/PxSolverDefs.h" #if !PX_DOXYGEN namespace physx @@ -44,44 +41,482 @@ namespace physx #endif /** - \brief a joint between two links in an articulation. + \brief A joint between two links in an articulation. - The joint model is very similar to a PxSphericalJoint with swing and twist limits, - and an implicit drive model. - - @see PxArticulation PxArticulationLink + @see PxArticulationReducedCoordinate, PxArticulationLink */ - - class PxArticulationJointReducedCoordinate : public PxArticulationJointBase + class PxArticulationJointReducedCoordinate : public PxBase { public: - virtual void setJointType(PxArticulationJointType::Enum jointType) = 0; - virtual PxArticulationJointType::Enum getJointType() const = 0; + /** + \brief Gets the parent articulation link of this joint. - virtual void setMotion(PxArticulationAxis::Enum axis, PxArticulationMotion::Enum motion) = 0; - virtual PxArticulationMotion::Enum getMotion(PxArticulationAxis::Enum axis) const = 0; + \return The parent link. + */ + virtual PxArticulationLink& getParentArticulationLink() const = 0; - virtual void setLimit(PxArticulationAxis::Enum axis, const PxReal lowLimit, const PxReal highLimit) = 0; - virtual void getLimit(PxArticulationAxis::Enum axis, PxReal& lowLimit, PxReal& highLimit) = 0; - virtual void setDrive(PxArticulationAxis::Enum axis, const PxReal stiffness, const PxReal damping, const PxReal maxForce, PxArticulationDriveType::Enum driveType = PxArticulationDriveType::eFORCE) = 0; - virtual void getDrive(PxArticulationAxis::Enum axis, PxReal& stiffness, PxReal& damping, PxReal& maxForce, PxArticulationDriveType::Enum& driveType) = 0; - virtual void setDriveTarget(PxArticulationAxis::Enum axis, const PxReal target) = 0; - virtual void setDriveVelocity(PxArticulationAxis::Enum axis, const PxReal targetVel) = 0; - virtual PxReal getDriveTarget(PxArticulationAxis::Enum axis) = 0; - virtual PxReal getDriveVelocity(PxArticulationAxis::Enum axis) = 0; + /** + \brief Sets the joint pose in the parent link actor frame. - virtual void setFrictionCoefficient(const PxReal coefficient) = 0; - virtual PxReal getFrictionCoefficient() const = 0; + \param[in] pose The joint pose. + Default: The identity transform. + + \note This call is not allowed while the simulation is running. + + @see getParentPose + */ + virtual void setParentPose(const PxTransform& pose) = 0; + + /** + \brief Gets the joint pose in the parent link actor frame. + + \return The joint pose. + + @see setParentPose + */ + virtual PxTransform getParentPose() const = 0; + + /** + \brief Gets the child articulation link of this joint. + + \return The child link. + */ + virtual PxArticulationLink& getChildArticulationLink() const = 0; + + /** + \brief Sets the joint pose in the child link actor frame. + + \param[in] pose The joint pose. + Default: The identity transform. + + \note This call is not allowed while the simulation is running. + + @see getChildPose + */ + virtual void setChildPose(const PxTransform& pose) = 0; + + /** + \brief Gets the joint pose in the child link actor frame. + + \return The joint pose. + + @see setChildPose + */ + virtual PxTransform getChildPose() const = 0; + + /** + \brief Sets the joint type (e.g. revolute). + + \param[in] jointType The joint type to set. + + \note Setting the joint type is not allowed while the articulation is in a scene. + In order to set the joint type, remove and then re-add the articulation to the scene. + + @see PxArticulationJointType, getJointType + */ + virtual void setJointType(PxArticulationJointType::Enum jointType) = 0; + + /** + \brief Gets the joint type. + + \return The joint type. + + @see PxArticulationJointType, setJointType + */ + virtual PxArticulationJointType::Enum getJointType() const = 0; + + /** + \brief Sets the joint motion for a given axis. + + \param[in] axis The target axis. + \param[in] motion The motion type to set. + + \note Setting the motion of joint axes is not allowed while the articulation is in a scene. + In order to set the motion, remove and then re-add the articulation to the scene. + + @see PxArticulationAxis, PxArticulationMotion, getMotion + */ + virtual void setMotion(PxArticulationAxis::Enum axis, PxArticulationMotion::Enum motion) = 0; + + /** + \brief Returns the joint motion for the given axis. + + \param[in] axis The target axis. + + \return The joint motion of the given axis. + + @see PxArticulationAxis, PxArticulationMotion, setMotion + */ + virtual PxArticulationMotion::Enum getMotion(PxArticulationAxis::Enum axis) const = 0; + + /** + \brief Sets the joint limits for a given axis. + + - The motion of the corresponding axis should be set to PxArticulationMotion::eLIMITED in order for the limits to be enforced. + - The lower limit should be strictly smaller than the higher limit. If the limits should be equal, use PxArticulationMotion::eLOCKED + and an appropriate offset in the parent/child joint frames. + + \param[in] axis The target axis. + \param[in] lowLimit The lower joint limit.
+ Range: [-PX_MAX_F32, highLimit)
+ Default: 0.0 + \param[in] highLimit The higher joint limit.
+ Range: (lowLimit, PX_MAX_F32]
+ Default: 0.0 + + \note This call is not allowed while the simulation is running. + + \deprecated Use #setLimitParams instead. Deprecated since PhysX version 5.1. + + @see setLimitParams, PxArticulationAxis + */ + PX_DEPRECATED PX_FORCE_INLINE void setLimit(PxArticulationAxis::Enum axis, const PxReal lowLimit, const PxReal highLimit) + { + setLimitParams(axis, PxArticulationLimit(lowLimit, highLimit)); + } + + /** + \brief Returns the joint limits for a given axis. + + \param[in] axis The target axis. + \param[out] lowLimit The lower joint limit. + \param[out] highLimit The higher joint limit. + + \deprecated Use #getLimitParams instead. Deprecated since PhysX version 5.1. + + @see getLimitParams, PxArticulationAxis + */ + PX_DEPRECATED PX_FORCE_INLINE void getLimit(PxArticulationAxis::Enum axis, PxReal& lowLimit, PxReal& highLimit) const + { + PxArticulationLimit pair = getLimitParams(axis); + lowLimit = pair.low; + highLimit = pair.high; + } + + /** + \brief Sets the joint limits for a given axis. + + - The motion of the corresponding axis should be set to PxArticulationMotion::eLIMITED in order for the limits to be enforced. + - The lower limit should be strictly smaller than the higher limit. If the limits should be equal, use PxArticulationMotion::eLOCKED + and an appropriate offset in the parent/child joint frames. + + \param[in] axis The target axis. + \param[in] limit The joint limits. + + \note This call is not allowed while the simulation is running. + + \note For spherical joints, limit.min and limit.max must both be in range [-Pi, Pi]. + + @see getLimitParams, PxArticulationAxis, PxArticulationLimit + */ + virtual void setLimitParams(PxArticulationAxis::Enum axis, const PxArticulationLimit& limit) = 0; + + /** + \brief Returns the joint limits for a given axis. + + \param[in] axis The target axis. + + \return The joint limits. + + @see setLimitParams, PxArticulationAxis, PxArticulationLimit + */ + virtual PxArticulationLimit getLimitParams(PxArticulationAxis::Enum axis) const = 0; + + /** + \brief Configures a joint drive for the given axis. + + See PxArticulationDrive for parameter details; and the manual for further information, and the drives' implicit spring-damper (i.e. PD control) implementation in particular. + + \param[in] axis The target axis. + \param[in] stiffness The drive stiffness, i.e. the proportional gain of the implicit PD controller.
+ Range: [0, PX_MAX_F32]
+ Default: 0.0 + \param[in] damping The drive damping, i.e. the derivative gain of the implicit PD controller.
+ Range: [0, PX_MAX_F32]
+ Default: 0.0 + \param[in] maxForce The force limit of the drive (this parameter also limits the force for an acceleration-type drive).
+ Range: [0, PX_MAX_F32]
+ Default: 0.0 + \param[in] driveType The drive type, @see PxArticulationDriveType. + + \note This call is not allowed while the simulation is running. + + \deprecated Use #setDriveParams instead. Deprecated since PhysX version 5.1. + + @see setDriveParams, PxArticulationAxis, PxArticulationDriveType, PxArticulationDrive, PxArticulationFlag::eDRIVE_LIMITS_ARE_FORCES + */ + PX_DEPRECATED PX_FORCE_INLINE void setDrive(PxArticulationAxis::Enum axis, const PxReal stiffness, const PxReal damping, const PxReal maxForce, PxArticulationDriveType::Enum driveType = PxArticulationDriveType::eFORCE) + { + setDriveParams(axis, PxArticulationDrive(stiffness, damping, maxForce, driveType)); + } + + /** + \brief Gets the joint drive configuration for the given axis. + + \param[in] axis The motion axis. + \param[out] stiffness The drive stiffness. + \param[out] damping The drive damping. + \param[out] maxForce The force limit. + \param[out] driveType The drive type. + + \deprecated Use #getDriveParams instead. Deprecated since PhysX version 5.1. + + @see getDriveParams, PxArticulationAxis, PxArticulationDriveType, PxArticulationDrive + */ + PX_DEPRECATED PX_FORCE_INLINE void getDrive(PxArticulationAxis::Enum axis, PxReal& stiffness, PxReal& damping, PxReal& maxForce, PxArticulationDriveType::Enum& driveType) const + { + PxArticulationDrive drive = getDriveParams(axis); + stiffness = drive.stiffness; + damping = drive.damping; + maxForce = drive.maxForce; + driveType = drive.driveType; + } + + /** + \brief Configures a joint drive for the given axis. + + See PxArticulationDrive for parameter details; and the manual for further information, and the drives' implicit spring-damper (i.e. PD control) implementation in particular. + + \param[in] axis The target axis. + \param[in] drive The drive parameters + + \note This call is not allowed while the simulation is running. + + @see getDriveParams, PxArticulationAxis, PxArticulationDrive + */ + virtual void setDriveParams(PxArticulationAxis::Enum axis, const PxArticulationDrive& drive) = 0; + + /** + \brief Gets the joint drive configuration for the given axis. + + \param[in] axis The target axis. + \return The drive parameters. + + @see setDriveParams, PxArticulationAxis, PxArticulationDrive + */ + virtual PxArticulationDrive getDriveParams(PxArticulationAxis::Enum axis) const = 0; + + /** + \brief Sets the joint drive position target for the given axis. + + The target units are linear units (equivalent to scene units) for a translational axis, or rad for a rotational axis. + + \param[in] axis The target axis. + \param[in] target The target position. + \param[in] autowake If true and the articulation is in a scene, the call wakes up the articulation and increases the wake counter + to #PxSceneDesc::wakeCounterResetValue if the counter value is below the reset value. + + \note This call is not allowed while the simulation is running. + + \note For spherical joints, target must be in range [-Pi, Pi]. + + \note The target is specified in the parent frame of the joint. If Gp, Gc are the parent and child actor poses in the world frame and Lp, Lc are the parent and child joint frames expressed in the parent and child actor frames then the joint will drive the parent and child links to poses that obey Gp * Lp * J = Gc * Lc. For joints restricted to angular motion, J has the form PxTranfsorm(PxVec3(PxZero), PxExp(PxVec3(twistTarget, swing1Target, swing2Target))). For joints restricted to linear motion, J has the form PxTransform(PxVec3(XTarget, YTarget, ZTarget), PxQuat(PxIdentity)). + + \note For spherical joints with more than 1 degree of freedom, the joint target angles taken together can collectively represent a rotation of greater than Pi around a vector. When this happens the rotation that matches the joint drive target is not the shortest path rotation. The joint pose J that is the outcome after driving to the target pose will always be the equivalent of the shortest path rotation. + + @see PxArticulationAxis, getDriveTarget + */ + virtual void setDriveTarget(PxArticulationAxis::Enum axis, const PxReal target, bool autowake = true) = 0; + + /** + \brief Returns the joint drive position target for the given axis. + + \param[in] axis The target axis. + + \return The target position. + + @see PxArticulationAxis, setDriveTarget + */ + virtual PxReal getDriveTarget(PxArticulationAxis::Enum axis) const = 0; + + /** + \brief Sets the joint drive velocity target for the given axis. + + The target units are linear units (equivalent to scene units) per second for a translational axis, or radians per second for a rotational axis. + + \param[in] axis The target axis. + \param[in] targetVel The target velocity. + \param[in] autowake If true and the articulation is in a scene, the call wakes up the articulation and increases the wake counter + to #PxSceneDesc::wakeCounterResetValue if the counter value is below the reset value. + + \note This call is not allowed while the simulation is running. + + @see PxArticulationAxis, getDriveVelocity + */ + virtual void setDriveVelocity(PxArticulationAxis::Enum axis, const PxReal targetVel, bool autowake = true) = 0; + + /** + \brief Returns the joint drive velocity target for the given axis. + + \param[in] axis The target axis. + + \return The target velocity. + + @see PxArticulationAxis, setDriveVelocity + */ + virtual PxReal getDriveVelocity(PxArticulationAxis::Enum axis) const = 0; + + /** + \brief Sets the joint armature for the given axis. + + - The armature is directly added to the joint-space spatial inertia of the corresponding axis. + - The armature is in mass units for a prismatic (i.e. linear) joint, and in mass units * (scene linear units)^2 for a rotational joint. + + \param[in] axis The target axis. + \param[in] armature The joint axis armature. + + \note This call is not allowed while the simulation is running. + + @see PxArticulationAxis, getArmature + */ + virtual void setArmature(PxArticulationAxis::Enum axis, const PxReal armature) = 0; + + /** + \brief Gets the joint armature for the given axis. + + \param[in] axis The target axis. + \return The armature set on the given axis. + + @see PxArticulationAxis, setArmature + */ + virtual PxReal getArmature(PxArticulationAxis::Enum axis) const = 0; + + /** + \brief Sets the joint friction coefficient, which applies to all joint axes. + + - The joint friction is unitless and relates the magnitude of the spatial force [F_trans, T_trans] transmitted from parent to child link to + the maximal friction force F_resist that may be applied by the solver to resist joint motion, per axis; i.e. |F_resist| <= coefficient * (|F_trans| + |T_trans|), + where F_resist may refer to a linear force or torque depending on the joint axis. + - The simulated friction effect is therefore similar to static and Coulomb friction. In order to simulate dynamic joint friction, use a joint drive with + zero stiffness and zero velocity target, and an appropriately dimensioned damping parameter. + + \param[in] coefficient The joint friction coefficient. + + \note This call is not allowed while the simulation is running. + + @see getFrictionCoefficient + */ + virtual void setFrictionCoefficient(const PxReal coefficient) = 0; + + /** + \brief Gets the joint friction coefficient. + + \return The joint friction coefficient. + + @see setFrictionCoefficient + */ + virtual PxReal getFrictionCoefficient() const = 0; + + /** + \brief Sets the maximal joint velocity enforced for all axes. + + - The solver will apply appropriate joint-space impulses in order to enforce the per-axis joint-velocity limit. + - The velocity units are linear units (equivalent to scene units) per second for a translational axis, or radians per second for a rotational axis. + + \param[in] maxJointV The maximal per-axis joint velocity. + + \note This call is not allowed while the simulation is running. + + @see getMaxJointVelocity + */ + virtual void setMaxJointVelocity(const PxReal maxJointV) = 0; + + /** + \brief Gets the maximal joint velocity enforced for all axes. + + \return The maximal per-axis joint velocity. + + @see setMaxJointVelocity + */ + virtual PxReal getMaxJointVelocity() const = 0; + + /** + \brief Sets the joint position for the given axis. + + - For performance, prefer PxArticulationCache::jointPosition to set joint positions in a batch articulation state update. + - Use PxArticulationReducedCoordinate::updateKinematic after all state updates to the articulation via non-cache API such as this method, + in order to update link states for the next simulation frame or querying. + + \param[in] axis The target axis. + \param[in] jointPos The joint position in linear units (equivalent to scene units) for a translational axis, or radians for a rotational axis. + + \note This call is not allowed while the simulation is running. + + \note For spherical joints, jointPos must be in range [-Pi, Pi]. + + \note Joint position is specified in the parent frame of the joint. If Gp, Gc are the parent and child actor poses in the world frame and Lp, Lc are the parent and child joint frames expressed in the parent and child actor frames then the parent and child links will be given poses that obey Gp * Lp * J = Gc * Lc with J denoting the joint pose. For joints restricted to angular motion, J has the form PxTranfsorm(PxVec3(PxZero), PxExp(PxVec3(twistPos, swing1Pos, swing2Pos))). For joints restricted to linear motion, J has the form PxTransform(PxVec3(xPos, yPos, zPos), PxQuat(PxIdentity)). + + \note For spherical joints with more than 1 degree of freedom, the input joint positions taken together can collectively represent a rotation of greater than Pi around a vector. When this happens the rotation that matches the joint positions is not the shortest path rotation. The joint pose J that is the outcome of setting and applying the joint positions will always be the equivalent of the shortest path rotation. + + @see PxArticulationAxis, getJointPosition, PxArticulationCache::jointPosition, PxArticulationReducedCoordinate::updateKinematic + */ + virtual void setJointPosition(PxArticulationAxis::Enum axis, const PxReal jointPos) = 0; + + /** + \brief Gets the joint position for the given axis, i.e. joint degree of freedom (DOF). + + For performance, prefer PxArticulationCache::jointPosition to get joint positions in a batch query. + + \param[in] axis The target axis. + + \return The joint position in linear units (equivalent to scene units) for a translational axis, or radians for a rotational axis. + + \note This call is not allowed while the simulation is running except in a split simulation during #PxScene::collide() and up to #PxScene::advance(), + and in PxContactModifyCallback or in contact report callbacks. + + @see PxArticulationAxis, setJointPosition, PxArticulationCache::jointPosition + */ + virtual PxReal getJointPosition(PxArticulationAxis::Enum axis) const = 0; + + /** + \brief Sets the joint velocity for the given axis. + + - For performance, prefer PxArticulationCache::jointVelocity to set joint velocities in a batch articulation state update. + - Use PxArticulationReducedCoordinate::updateKinematic after all state updates to the articulation via non-cache API such as this method, + in order to update link states for the next simulation frame or querying. + + \param[in] axis The target axis. + \param[in] jointVel The joint velocity in linear units (equivalent to scene units) per second for a translational axis, or radians per second for a rotational axis. + + \note This call is not allowed while the simulation is running. + + @see PxArticulationAxis, getJointVelocity, PxArticulationCache::jointVelocity, PxArticulationReducedCoordinate::updateKinematic + */ + virtual void setJointVelocity(PxArticulationAxis::Enum axis, const PxReal jointVel) = 0; + + /** + \brief Gets the joint velocity for the given axis. + + For performance, prefer PxArticulationCache::jointVelocity to get joint velocities in a batch query. + + \param[in] axis The target axis. + + \return The joint velocity in linear units (equivalent to scene units) per second for a translational axis, or radians per second for a rotational axis. + + \note This call is not allowed while the simulation is running except in a split simulation during #PxScene::collide() and up to #PxScene::advance(), + and in PxContactModifyCallback or in contact report callbacks. + + @see PxArticulationAxis, setJointVelocity, PxArticulationCache::jointVelocity + */ + virtual PxReal getJointVelocity(PxArticulationAxis::Enum axis) const = 0; + + /** + \brief Returns the string name of the dynamic type. + + \return The string name. + */ virtual const char* getConcreteTypeName() const { return "PxArticulationJointReducedCoordinate"; } - virtual void setMaxJointVelocity(const PxReal maxJointV) = 0; - virtual PxReal getMaxJointVelocity() const = 0; + virtual ~PxArticulationJointReducedCoordinate() {} + + //public variables: + void* userData; //!< The user can assign this to whatever, usually to create a 1:1 relationship with a user object. protected: - PX_INLINE PxArticulationJointReducedCoordinate(PxType concreteType, PxBaseFlags baseFlags) : PxArticulationJointBase(concreteType, baseFlags) {} - PX_INLINE PxArticulationJointReducedCoordinate(PxBaseFlags baseFlags) : PxArticulationJointBase(baseFlags) {} - virtual ~PxArticulationJointReducedCoordinate() {} + PX_INLINE PxArticulationJointReducedCoordinate(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags) {} + PX_INLINE PxArticulationJointReducedCoordinate(PxBaseFlags baseFlags) : PxBase(baseFlags) {} + virtual bool isKindOf(const char* name) const { return !::strcmp("PxArticulationJointReducedCoordinate", name) || PxBase::isKindOf(name); } }; @@ -89,7 +524,5 @@ namespace physx } // namespace physx #endif -#endif - - /** @} */ +/** @} */ #endif diff --git a/Source/ThirdParty/PhysX/PxArticulationLink.h b/Source/ThirdParty/PhysX/PxArticulationLink.h index 4b9fee714..d6df1ebb6 100644 --- a/Source/ThirdParty/PhysX/PxArticulationLink.h +++ b/Source/ThirdParty/PhysX/PxArticulationLink.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,18 +22,16 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_NX_ARTICULATION_LINK -#define PX_PHYSICS_NX_ARTICULATION_LINK +#ifndef PX_ARTICULATION_LINK_H +#define PX_ARTICULATION_LINK_H /** \addtogroup physics @{ */ #include "PxPhysXConfig.h" -#include "PxArticulationJoint.h" #include "PxRigidBody.h" #if !PX_DOXYGEN @@ -42,86 +39,155 @@ namespace physx { #endif - class PxArticulationBase; - /** -\brief a component of an articulation that represents a rigid body +\brief A component of an articulation that represents a rigid body. -A limited subset of the properties of PxRigidDynamic are supported. In particular, sleep properties -are attributes of the articulation rather than each individual body, damping and velocity limits -are not supported, and links may not be kinematic. +Articulation links have a restricted subset of the functionality of a PxRigidDynamic: +- They may not be kinematic, and do not support contact-force thresholds. +- Their velocity or global pose cannot be set directly, but must be set via the articulation-root and joint positions/velocities. +- Sleep state and solver iteration counts are properties of the entire articulation rather than the individual links. -@see PxArticulation PxArticulation.createLink PxArticulationJoint PxRigidBody +@see PxArticulationReducedCoordinate, PxArticulationReducedCoordinate::createLink, PxArticulationJointReducedCoordinate, PxRigidBody */ class PxArticulationLink : public PxRigidBody { public: /** - \brief Deletes the articulation link. + \brief Releases the link from the articulation. - \note Only a leaf articulation link can be released - - Do not keep a reference to the deleted instance. + \note Only a leaf articulation link can be released. + \note Releasing a link is not allowed while the articulation link is in a scene. In order to release a link, + remove and then re-add the corresponding articulation to the scene. - @see PxArticulation::createLink() + @see PxArticulationReducedCoordinate::createLink() */ virtual void release() = 0; /** - \brief get the articulation to which this articulation link belongs. This returns the base class. The application should - establish which articulation implementation this actually is and upcast to that type to access non-common functionality + \brief Gets the articulation that the link is a part of. - \return the articulation to which this link belongs + \return The articulation. + + @see PxArticulationReducedCoordinate */ - virtual PxArticulationBase& getArticulation() const = 0; + virtual PxArticulationReducedCoordinate& getArticulation() const = 0; /** - \brief Get the joint which connects this link to its parent. + \brief Gets the joint which connects this link to its parent. \return The joint connecting the link to the parent. NULL for the root link. - @see PxArticulationJoint + @see PxArticulationJointReducedCoordinate */ - virtual PxArticulationJointBase* getInboundJoint() const = 0; + virtual PxArticulationJointReducedCoordinate* getInboundJoint() const = 0; /** - \brief Get the degree of freedom of the joint which connects this link to its parent. + \brief Gets the number of degrees of freedom of the joint which connects this link to its parent. - \return The degree of freeedom of the joint connecting the link to the parent. 0xffffffff for the root link. + - The root link DOF-count is defined to be 0 regardless of PxArticulationFlag::eFIX_BASE. + - The return value is only valid for articulations that are in a scene. - @see PxArticulationJoint + \return The number of degrees of freedom, or 0xFFFFFFFF if the articulation is not in a scene. + + @see PxArticulationJointReducedCoordinate */ virtual PxU32 getInboundJointDof() const = 0; /** - \brief Get number of child links. + \brief Gets the number of child links. - \return the number of child links + \return The number of child links. - @see getChildren() + @see getChildren */ virtual PxU32 getNbChildren() const = 0; /** - \brief Get low-level link index + \brief Gets the low-level link index that may be used to index into members of PxArticulationCache. - \return low-level index + The return value is only valid for articulations that are in a scene. + + \return The low-level index, or 0xFFFFFFFF if the articulation is not in a scene. + + @see PxArticulationCache */ virtual PxU32 getLinkIndex() const = 0; /** - \brief Retrieve all the child links. + \brief Retrieves the child links. \param[out] userBuffer The buffer to receive articulation link pointers. - \param[in] bufferSize Size of provided user buffer. - \return Number of articulation links written to the buffer. - \param[in] startIndex Index of first child pointer to be retrieved + \param[in] bufferSize The size of the provided user buffer, use getNbChildren() for sizing. + \param[in] startIndex The index of the first child pointer to be retrieved. - @see getNbChildren() + \return The number of articulation links written to the buffer. + + @see getNbChildren */ - virtual PxU32 getChildren(PxArticulationLink** userBuffer, PxU32 bufferSize, PxU32 startIndex=0) const = 0; + virtual PxU32 getChildren(PxArticulationLink** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0; + + /** + \brief Set the constraint-force-mixing scale term. + + The cfm scale term is a stabilization term that helps avoid instabilities with over-constrained + configurations. It should be a small value that is multiplied by 1/mass internally to produce + an additional bias added to the unit response term in the solver. + + \param[in] cfm The constraint-force-mixing scale term. + + Default: 0.025 + Range: [0, 1] + + \note This call is not allowed while the simulation is running. + + @see getCfmScale + */ + virtual void setCfmScale(const PxReal cfm) = 0; + + /** + \brief Get the constraint-force-mixing scale term. + \return The constraint-force-mixing scale term. + + @see setCfmScale + */ + virtual PxReal getCfmScale() const = 0; + + /** + \brief Get the linear velocity of the link. + + - The linear velocity is with respect to the link's center of mass and not the actor frame origin. + - For performance, prefer PxArticulationCache::linkVelocity to get link spatial velocities in a batch query. + - When the articulation state is updated via non-cache API, use PxArticulationReducedCoordinate::updateKinematic before querying velocity. + + \return The linear velocity of the link. + + \note This call is not allowed while the simulation is running except in a split simulation during #PxScene::collide() and up to #PxScene::advance(), + and in PxContactModifyCallback or in contact report callbacks. + + @see PxRigidBody::getCMassLocalPose + */ + virtual PxVec3 getLinearVelocity() const = 0; + + /** + \brief Get the angular velocity of the link. + + - For performance, prefer PxArticulationCache::linkVelocity to get link spatial velocities in a batch query. + - When the articulation state is updated via non-cache API, use PxArticulationReducedCoordinate::updateKinematic before querying velocity. + + \return The angular velocity of the link. + + \note This call is not allowed while the simulation is running except in a split simulation during #PxScene::collide() and up to #PxScene::advance(), + and in PxContactModifyCallback or in contact report callbacks. + */ + virtual PxVec3 getAngularVelocity() const = 0; + + /** + \brief Returns the string name of the dynamic type. + + \return The string name. + */ virtual const char* getConcreteTypeName() const { return "PxArticulationLink"; } protected: diff --git a/Source/ThirdParty/PhysX/PxArticulationReducedCoordinate.h b/Source/ThirdParty/PhysX/PxArticulationReducedCoordinate.h index a3acd8e5c..c107dbd33 100644 --- a/Source/ThirdParty/PhysX/PxArticulationReducedCoordinate.h +++ b/Source/ThirdParty/PhysX/PxArticulationReducedCoordinate.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,20 +22,23 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_NX_ARTICULATION_RC -#define PX_PHYSICS_NX_ARTICULATION_RC +#ifndef PX_ARTICULATION_RC_H +#define PX_ARTICULATION_RC_H /** \addtogroup physics @{ */ -#include "PxArticulationBase.h" +#include "PxPhysXConfig.h" +#include "common/PxBase.h" #include "foundation/PxVec3.h" #include "foundation/PxTransform.h" #include "solver/PxSolverDefs.h" +#include "PxArticulationFlag.h" +#include "PxArticulationTendon.h" +#include "PxArticulationFlag.h" #if !PX_DOXYGEN namespace physx @@ -44,6 +46,9 @@ namespace physx #endif PX_ALIGN_PREFIX(16) + /** + \brief Data structure to represent spatial forces. + */ struct PxSpatialForce { PxVec3 force; @@ -54,6 +59,9 @@ namespace physx PX_ALIGN_SUFFIX(16); PX_ALIGN_PREFIX(16) + /** + \brief Data structure to represent spatial velocities. + */ struct PxSpatialVelocity { PxVec3 linear; @@ -63,31 +71,33 @@ namespace physx } PX_ALIGN_SUFFIX(16); - class PxJoint; + class PxConstraint; + class PxScene; + /** + \brief Data structure used to access the root link state and acceleration. + + @see PxArticulationCache + */ struct PxArticulationRootLinkData { - PxTransform transform; - PxVec3 worldLinVel; - PxVec3 worldAngVel; - PxVec3 worldLinAccel; - PxVec3 worldAngAccel; + PxTransform transform; //!< Actor transform + // The velocities and accelerations below are with respect to the center of mass (COM) of the root link. The COM and actor frame origin may not coincide. + PxVec3 worldLinVel; //!< Link linear velocity + PxVec3 worldAngVel; //!< Link angular velocity + PxVec3 worldLinAccel; //!< Link classical linear acceleration + PxVec3 worldAngAccel; //!< Link angular acceleration }; + /** + \brief Data structure used to read and write internal articulation data. + + @see PxArticulationCacheFlag, PxArticulationReducedCoordinate::createCache, PxArticulationReducedCoordinate::applyCache, + PxArticulationReducedCoordinate::copyInternalStateToCache + */ class PxArticulationCache { public: - enum Enum - { - eVELOCITY = (1 << 0), //!< The joint velocities this frame. Note, this is the accumulated joint velocities, not change in joint velocity. - eACCELERATION = (1 << 1), //!< The joint accelerations this frame. Delta velocity can be computed from acceleration * dt. - ePOSITION = (1 << 2), //!< The joint positions this frame. Note, this is the accumulated joint positions over frames, not change in joint position. - eFORCE = (1 << 3), //!< The joint forces this frame. Note, the application should provide these values for the forward dynamic. If the application is using inverse dynamic, this is the joint force returned. - eLINKVELOCITY = (1 << 4), //!< The link velocities this frame. - eLINKACCELERATION = (1 << 5), //!< The link accelerations this frame. - eROOT = (1 << 6), //!< Root link transform, velocity and acceleration. Note, when the application call applyCache with eROOT flag, it won't apply root link's acceleration to the simulation - eALL = (eVELOCITY | eACCELERATION | ePOSITION| eLINKVELOCITY | eLINKACCELERATION | eROOT ) - }; PxArticulationCache() : externalForces (NULL), denseJacobian (NULL), @@ -96,7 +106,11 @@ namespace physx jointAcceleration (NULL), jointPosition (NULL), jointForce (NULL), + jointSolverForces (NULL), + linkVelocity (NULL), + linkAcceleration (NULL), rootLinkData (NULL), + sensorForces (NULL), coefficientMatrix (NULL), lambda (NULL), scratchMemory (NULL), @@ -104,310 +118,1293 @@ namespace physx version (0) {} - PxSpatialForce* externalForces; // N = getNbLinks() - PxReal* denseJacobian; // N = 6*getDofs()*NumJoints, NumJoints = getNbLinks() - 1 - PxReal* massMatrix; // N = getDofs()*getDofs() - PxReal* jointVelocity; // N = getDofs() - PxReal* jointAcceleration; // N = getDofs() - PxReal* jointPosition; // N = getDofs() - PxReal* jointForce; // N = getDofs() - PxSpatialVelocity* linkVelocity; // N = getNbLinks() - PxSpatialVelocity* linkAcceleration; // N = getNbLinks() - PxArticulationRootLinkData* rootLinkData; // root link Data + /** + \brief Releases an articulation cache. - //application need to allocate those memory and assign them to the cache - PxReal* coefficientMatrix; + @see PxArticulationReducedCoordinate::createCache, PxArticulationReducedCoordinate::applyCache, + PxArticulationReducedCoordinate::copyInternalStateToCache + */ + PX_PHYSX_CORE_API void release(); + + /** + \brief External forces acting on the articulation links for inverse dynamics computation. + + - N = getNbLinks(). + - Indexing follows the low-level link indices, see PxArticulationLink::getLinkIndex. + - The forces are with respect to the center of mass of the link. + + @see PxArticulationReducedCoordinate::computeGeneralizedExternalForce + */ + PxSpatialForce* externalForces; + + /** + \brief Dense Jacobian data. + + - N = nbRows * nbCols = (6 * getNbLinks()) * (6 + getDofs()) -> size includes possible floating-base DOFs regardless of PxArticulationFlag::eFIX_BASE flag. + - The links, i.e. rows are in order of the low-level link indices (minus one if PxArticulationFlag::eFIX_BASE is true), see PxArticulationLink::getLinkIndex. + The corresponding spatial velocities are stacked [vx; vy; vz; wx; wy; wz], where vx and wx refer to the linear and rotational velocity in world X. + - The DOFs, i.e. column indices correspond to the low-level DOF indices, see PxArticulationCache::jointVelocity. + + @see PxArticulationReducedCoordinate::computeDenseJacobian + */ + PxReal* denseJacobian; + + /** + \brief The generalized mass matrix that maps joint accelerations to joint forces. + + - N = getDofs() * getDofs(). + - The indexing follows the internal DOF index order, see PxArticulationCache::jointVelocity. + + @see PxArticulationReducedCoordinate::computeGeneralizedMassMatrix + */ + PxReal* massMatrix; + + /** + \brief The articulation joint DOF velocities. + + - N = getDofs(). + - Read/write using PxArticulationCacheFlag::eVELOCITY. + - The indexing follows the internal DOF index order. Therefore, the application should calculate the DOF data indices by summing the joint DOFs in the order of + the links' low-level indices (see the manual Section "Cache Indexing" for a snippet for this calculation): + \verbatim Low-level link index: | link 0 | link 1 | link 2 | link 3 | ... | <- PxArticulationLink::getLinkIndex() \endverbatim + \verbatim Link inbound joint DOF: | 0 | 1 | 2 | 1 | ... | <- PxArticulationLink::getInboundJointDof() \endverbatim + \verbatim Low-level DOF index: | - | 0 | 1, 2 | 3 | ... | \endverbatim + The root link always has low-level index 0 and always has zero inbound joint DOFs. The link DOF indexing follows the order in PxArticulationAxis::Enum. + For example, assume that low-level link 2 has an inbound spherical joint with two DOFs: eSWING1 and eSWING2. The corresponding low-level joint DOF indices + are therefore 1 for eSWING1 and 2 for eSWING2. + */ + PxReal* jointVelocity; + + /** + \brief The articulation joint DOF accelerations. + + - N = getDofs(). + - Read using PxArticulationCacheFlag::eACCELERATION. + - The indexing follows the internal DOF index order, see PxArticulationCache::jointVelocity. + - Delta joint DOF velocities can be computed from acceleration * dt. + */ + PxReal* jointAcceleration; + + /** + \brief The articulation joint DOF positions. + + - N = getDofs(). + - Read/write using PxArticulationCacheFlag::ePOSITION. + - The indexing follows the internal DOF index order, see PxArticulationCache::jointVelocity. + - For spherical joints, the joint position for each axis on the joint must be in range [-Pi, Pi]. + */ + PxReal* jointPosition; + + /** + \brief The articulation joint DOF forces. + + - N = getDofs(). + - Read/Write using PxArticulationCacheFlag::eFORCE. + - The indexing follows the internal DOF index order, see PxArticulationCache::jointVelocity. + - Applied joint forces persist and are applied each frame until changed. + */ + PxReal* jointForce; + + /** + \brief Solver constraint joint DOF forces. + + - N = getDofs(). + - Read using PxArticulationCacheFlag::eJOINT_SOLVER_FORCES. + - The indexing follows the internal DOF index order, see PxArticulationCache::jointVelocity. + - Raise PxArticulationFlag::eCOMPUTE_JOINT_FORCES to enable reading the solver forces. + */ + PxReal* jointSolverForces; + + /** + \brief Link spatial velocity. + + - N = getNbLinks(). + - Read using PxArticulationCacheFlag::eLINK_VELOCITY. + - The indexing follows the internal link indexing, see PxArticulationLink::getLinkIndex. + - The velocity is with respect to the link's center of mass. + + @see PxRigidBody::getCMassLocalPose + */ + PxSpatialVelocity* linkVelocity; + + /** + \brief Link classical acceleration. + + - N = getNbLinks(). + - Read using PxArticulationCacheFlag::eLINK_ACCELERATION. + - The indexing follows the internal link indexing, see PxArticulationLink::getLinkIndex. + - The acceleration is with respect to the link's center of mass. + + @see PxArticulationReducedCoordinate::getLinkAcceleration, PxRigidBody::getCMassLocalPose + */ + PxSpatialVelocity* linkAcceleration; + + /** + \brief Root link transform, velocities, and accelerations. + + - N = 1. + - Read/write using PxArticulationCacheFlag::eROOT_TRANSFORM and PxArticulationCacheFlag::eROOT_VELOCITIES (accelerations are read-only). + + @see PxArticulationRootLinkData + */ + PxArticulationRootLinkData* rootLinkData; + + /** + \brief Link sensor spatial forces. + + - N = getNbSensors(). + - Read using PxArticulationCacheFlag::eSENSOR_FORCES. + - For indexing, see PxArticulationSensor::getIndex. + + @see PxArticulationSensor + */ + PxSpatialForce* sensorForces; + + // Members and memory below here are not zeroed when zeroCache is called, and are not included in the size returned by PxArticulationReducedCoordinate::getCacheDataSize. + + /** + \brief Constraint coefficient matrix. + + - N = getCoefficentMatrixSize(). + - The user needs to allocate memory and set this member to the allocated memory. + + @see PxArticulationReducedCoordinate::computeCoefficientMatrix + */ + PxReal* coefficientMatrix; + + /** + \brief Constraint lambda values (impulses applied by the respective constraints). + + - N = getNbLoopJoints(). + - The user needs to allocate memory and set this member to the allocated memory. + + @see PxArticulationReducedCoordinate::computeLambda + */ PxReal* lambda; - //These three members won't be set to zero when zeroCache get called - void* scratchMemory; //this is used for internal calculation - void* scratchAllocator; - PxU32 version; //cache version. If the articulation configuration change, the cache is invalid + void* scratchMemory; //!< The scratch memory is used for internal calculations. + void* scratchAllocator; //!< The scratch allocator is used for internal calculations. + PxU32 version; //!< The cache version used internally to check compatibility with the articulation, i.e. detect if the articulation configuration changed after the cache was created. }; - typedef PxFlags PxArticulationCacheFlags; - PX_FLAGS_OPERATORS(PxArticulationCache::Enum, PxU8) + /** + \brief Flags to configure the forces reported by articulation link sensors. + + @see PxArticulationSensor::setFlag + */ + struct PxArticulationSensorFlag + { + enum Enum + { + eFORWARD_DYNAMICS_FORCES = 1 << 0, //!< Raise to receive forces from forward dynamics. + eCONSTRAINT_SOLVER_FORCES = 1 << 1, //!< Raise to receive forces from constraint solver. + eWORLD_FRAME = 1 << 2 //!< Raise to receive forces in the world rotation frame, otherwise they will be reported in the sensor's local frame. + }; + }; + + typedef physx::PxFlags PxArticulationSensorFlags; /** - \brief a tree structure of bodies connected by joints that is treated as a unit by the dynamics solver + \brief A force sensor that can be attached to articulation links to measure spatial force. - Articulations are more expensive to simulate than the equivalent collection of - PxRigidDynamic and PxJoint structures, but because the dynamics solver treats - each articulation as a single object, they are much less prone to separation and - have better support for actuation. An articulation may have at most 64 links. - - @see PxArticulationJoint PxArticulationLink PxPhysics.createArticulation + @see PxArticulationReducedCoordinate::createSensor */ + class PxArticulationSensor : public PxBase + { + public: + /** + \brief Releases the sensor. + + \note Releasing a sensor is not allowed while the articulation is in a scene. In order to + release a sensor, remove and then re-add the articulation to the scene. + */ + virtual void release() = 0; + + /** + \brief Returns the spatial force in the local frame of the sensor. + + \return The spatial force. + + \note This call is not allowed while the simulation is running except in a split simulation during #PxScene::collide() and up to #PxScene::advance(), + and in PxContactModifyCallback or in contact report callbacks. + + @see setRelativePose, getRelativePose + */ + virtual PxSpatialForce getForces() const = 0; + + /** + \brief Returns the relative pose between this sensor and the body frame of the link that the sensor is attached to. + + The link body frame is at the center of mass and aligned with the principal axes of inertia, see PxRigidBody::getCMassLocalPose. + + \return The transform link body frame -> sensor frame. + + @see setRelativePose + */ + virtual PxTransform getRelativePose() const = 0; + + /** + \brief Sets the relative pose between this sensor and the body frame of the link that the sensor is attached to. + + The link body frame is at the center of mass and aligned with the principal axes of inertia, see PxRigidBody::getCMassLocalPose. + + \param[in] pose The transform link body frame -> sensor frame. + + \note Setting the sensor relative pose is not allowed while the articulation is in a scene. In order to + set the pose, remove and then re-add the articulation to the scene. + + @see getRelativePose + */ + virtual void setRelativePose(const PxTransform& pose) = 0; + + /** + \brief Returns the link that this sensor is attached to. + + \return A pointer to the link. + */ + virtual PxArticulationLink* getLink() const = 0; + + /** + \brief Returns the index of this sensor inside the articulation. + + The return value is only valid for sensors attached to articulations that are in a scene. + + \return The low-level index, or 0xFFFFFFFF if the articulation is not in a scene. + */ + virtual PxU32 getIndex() const = 0; + + /** + \brief Returns the articulation that this sensor is part of. + + \return A pointer to the articulation. + */ + virtual PxArticulationReducedCoordinate* getArticulation() const = 0; + + /** + \brief Returns the sensor's flags. + + \return The current set of flags of the sensor. + + @see PxArticulationSensorFlag + */ + virtual PxArticulationSensorFlags getFlags() const = 0; + + /** + \brief Sets a flag of the sensor. + + \param[in] flag The flag to set. + \param[in] enabled The value to set the flag to. + + \note Setting the sensor flags is not allowed while the articulation is in a scene. In order to + set the flags, remove and then re-add the articulation to the scene. + + @see PxArticulationSensorFlag + */ + virtual void setFlag(PxArticulationSensorFlag::Enum flag, bool enabled) = 0; + + /** + \brief Returns the string name of the dynamic type. + + \return The string name. + */ + virtual const char* getConcreteTypeName() const { return "PxArticulationSensor"; } + + virtual ~PxArticulationSensor() {} + + void* userData; //!< user can assign this to whatever, usually to create a 1:1 relationship with a user object. + + protected: + PX_INLINE PxArticulationSensor(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags) {} + PX_INLINE PxArticulationSensor(PxBaseFlags baseFlags) : PxBase(baseFlags) {} + }; + + + /** + \brief Flag that configures articulation-state updates by PxArticulationReducedCoordinate::updateKinematic. + */ + struct PxArticulationKinematicFlag + { + enum Enum + { + ePOSITION = 1 << 0, //!< Raise after any changes to the articulation root or joint positions using non-cache API calls. Updates links' positions and velocities. + eVELOCITY = 1 << 1 //!< Raise after velocity-only changes to the articulation root or joints using non-cache API calls. Updates links' velocities. + }; + }; + + typedef physx::PxFlags PxArticulationKinematicFlags; + PX_FLAGS_OPERATORS(PxArticulationKinematicFlag::Enum, PxU8) #if PX_VC #pragma warning(push) #pragma warning(disable : 4435) #endif - class PxArticulationReducedCoordinate : public PxArticulationBase + /** + \brief A tree structure of bodies connected by joints that is treated as a unit by the dynamics solver. Parametrized in reduced (joint) coordinates. + + @see PxArticulationJointReducedCoordinate, PxArticulationLink, PxPhysics::createArticulationReducedCoordinate + */ + class PxArticulationReducedCoordinate : public PxBase { public: - virtual void release() = 0; + /** + \brief Returns the scene which this articulation belongs to. + + \return Owner Scene. NULL if not part of a scene. + + @see PxScene + */ + virtual PxScene* getScene() const = 0; /** - \brief Sets flags on the articulation + \brief Sets the solver iteration counts for the articulation. - \param[in] flags Articulation flags + The solver iteration count determines how accurately contacts, drives, and limits are resolved. + Setting a higher position iteration count may therefore help in scenarios where the articulation + is subject to many constraints; for example, a manipulator articulation with drives and joint limits + that is grasping objects, or several such articulations interacting through contacts. Other situations + where higher position iterations may improve simulation fidelity are: large mass ratios within the + articulation or between the articulation and an object in contact with it; or strong drives in the + articulation being used to manipulate a light object. + If intersecting bodies are being depenetrated too violently, increase the number of velocity + iterations. More velocity iterations will drive the relative exit velocity of the intersecting + objects closer to the correct value given the restitution. + + \param[in] minPositionIters Number of position iterations the solver should perform for this articulation. Range: [1,255] + \param[in] minVelocityIters Number of velocity iterations the solver should perform for this articulation. Range: [1,255] + + \note This call may not be made during simulation. + + @see getSolverIterationCounts() + */ + virtual void setSolverIterationCounts(PxU32 minPositionIters, PxU32 minVelocityIters = 1) = 0; + + /** + \brief Returns the solver iteration counts. + + @see setSolverIterationCounts() + */ + virtual void getSolverIterationCounts(PxU32& minPositionIters, PxU32& minVelocityIters) const = 0; + + /** + \brief Returns true if this articulation is sleeping. + + When an actor does not move for a period of time, it is no longer simulated in order to save time. This state + is called sleeping. However, because the object automatically wakes up when it is either touched by an awake object, + or a sleep-affecting property is changed by the user, the entire sleep mechanism should be transparent to the user. + + An articulation can only go to sleep if all links are ready for sleeping. An articulation is guaranteed to be awake + if at least one of the following holds: + + \li The wake counter is positive (see #setWakeCounter()). + \li The linear or angular velocity of any link is non-zero. + \li A non-zero force or torque has been applied to the articulation or any of its links. + + If an articulation is sleeping, the following state is guaranteed: + + \li The wake counter is zero. + \li The linear and angular velocity of all links is zero. + \li There is no force update pending. + + When an articulation gets inserted into a scene, it will be considered asleep if all the points above hold, else it will + be treated as awake. + + If an articulation is asleep after the call to #PxScene::fetchResults() returns, it is guaranteed that the poses of the + links were not changed. You can use this information to avoid updating the transforms of associated objects. + + \return True if the articulation is sleeping. + + \note This call may only be made on articulations that are in a scene, and may not be made during simulation, + except in a split simulation in-between #PxScene::fetchCollision and #PxScene::advance. + + @see wakeUp() putToSleep() getSleepThreshold() + */ + virtual bool isSleeping() const = 0; + + /** + \brief Sets the mass-normalized energy threshold below which the articulation may go to sleep. + + The articulation will sleep if the energy of each link is below this threshold. + + \param[in] threshold Energy below which the articulation may go to sleep. Range: [0, PX_MAX_F32) + + \note This call may not be made during simulation. + + @see isSleeping() getSleepThreshold() wakeUp() putToSleep() + */ + virtual void setSleepThreshold(PxReal threshold) = 0; + + /** + \brief Returns the mass-normalized energy below which the articulation may go to sleep. + + \return The energy threshold for sleeping. + + @see isSleeping() wakeUp() putToSleep() setSleepThreshold() + */ + virtual PxReal getSleepThreshold() const = 0; + + /** + \brief Sets the mass-normalized kinetic energy threshold below which the articulation may participate in stabilization. + + Articulations whose kinetic energy divided by their mass is above this threshold will not participate in stabilization. + + This value has no effect if PxSceneFlag::eENABLE_STABILIZATION was not enabled on the PxSceneDesc. + + Default: 0.01 * PxTolerancesScale::speed * PxTolerancesScale::speed + + \param[in] threshold Energy below which the articulation may participate in stabilization. Range: [0,inf) + + \note This call may not be made during simulation. + + @see getStabilizationThreshold() PxSceneFlag::eENABLE_STABILIZATION + */ + virtual void setStabilizationThreshold(PxReal threshold) = 0; + + /** + \brief Returns the mass-normalized kinetic energy below which the articulation may participate in stabilization. + + Articulations whose kinetic energy divided by their mass is above this threshold will not participate in stabilization. + + \return The energy threshold for participating in stabilization. + + @see setStabilizationThreshold() PxSceneFlag::eENABLE_STABILIZATION + */ + virtual PxReal getStabilizationThreshold() const = 0; + + /** + \brief Sets the wake counter for the articulation in seconds. + + - The wake counter value determines the minimum amount of time until the articulation can be put to sleep. + - An articulation will not be put to sleep if the energy is above the specified threshold (see #setSleepThreshold()) + or if other awake objects are touching it. + - Passing in a positive value will wake up the articulation automatically. + + Default: 0.4s (which corresponds to 20 frames for a time step of 0.02s) + + \param[in] wakeCounterValue Wake counter value in seconds. Range: [0, PX_MAX_F32) + + \note This call may not be made during simulation, except in a split simulation in-between #PxScene::fetchCollision and #PxScene::advance. + + @see isSleeping() getWakeCounter() + */ + virtual void setWakeCounter(PxReal wakeCounterValue) = 0; + + /** + \brief Returns the wake counter of the articulation in seconds. + + \return The wake counter of the articulation in seconds. + + \note This call may not be made during simulation, except in a split simulation in-between #PxScene::fetchCollision and #PxScene::advance. + + @see isSleeping() setWakeCounter() + */ + virtual PxReal getWakeCounter() const = 0; + + /** + \brief Wakes up the articulation if it is sleeping. + + - The articulation will get woken up and might cause other touching objects to wake up as well during the next simulation step. + - This will set the wake counter of the articulation to the value specified in #PxSceneDesc::wakeCounterResetValue. + + \note This call may only be made on articulations that are in a scene, and may not be made during simulation, + except in a split simulation in-between #PxScene::fetchCollision and #PxScene::advance. + + @see isSleeping() putToSleep() + */ + virtual void wakeUp() = 0; + + /** + \brief Forces the articulation to sleep. + + - The articulation will stay asleep during the next simulation step if not touched by another non-sleeping actor. + - This will set any applied force, the velocity, and the wake counter of all bodies in the articulation to zero. + + \note This call may not be made during simulation, and may only be made on articulations that are in a scene. + + @see isSleeping() wakeUp() + */ + virtual void putToSleep() = 0; + + /** + \brief Sets the limit on the magnitude of the linear velocity of the articulation's center of mass. + + - The limit acts on the linear velocity of the entire articulation. The velocity is calculated from the total momentum + and the spatial inertia of the articulation. + - The limit only applies to floating-base articulations. + - A benefit of the COM velocity limit is that it is evenly applied to the whole articulation, which results in fewer visual + artifacts compared to link rigid-body damping or joint-velocity limits. However, these per-link or per-degree-of-freedom + limits may still help avoid numerical issues. + + \note This call may not be made during simulation. + + \param[in] maxLinearVelocity The maximal linear velocity magnitude. Range: [0, PX_MAX_F32); Default: PX_MAX_F32. + + @see setMaxCOMAngularVelocity, PxRigidBody::setLinearDamping, PxRigidBody::setAngularDamping, PxArticulationJointReducedCoordinate::setMaxJointVelocity + */ + virtual void setMaxCOMLinearVelocity(const PxReal maxLinearVelocity) = 0; + + /** + \brief Gets the limit on the magnitude of the linear velocity of the articulation's center of mass. + + \return The maximal linear velocity magnitude. + + @see setMaxCOMLinearVelocity + */ + virtual PxReal getMaxCOMLinearVelocity() const = 0; + + /** + \brief Sets the limit on the magnitude of the angular velocity at the articulation's center of mass. + + - The limit acts on the angular velocity of the entire articulation. The velocity is calculated from the total momentum + and the spatial inertia of the articulation. + - The limit only applies to floating-base articulations. + - A benefit of the COM velocity limit is that it is evenly applied to the whole articulation, which results in fewer visual + artifacts compared to link rigid-body damping or joint-velocity limits. However, these per-link or per-degree-of-freedom + limits may still help avoid numerical issues. + + \note This call may not be made during simulation. + + \param[in] maxAngularVelocity The maximal angular velocity magnitude. Range: [0, PX_MAX_F32); Default: PX_MAX_F32. + + @see setMaxCOMLinearVelocity, PxRigidBody::setLinearDamping, PxRigidBody::setAngularDamping, PxArticulationJointReducedCoordinate::setMaxJointVelocity + */ + virtual void setMaxCOMAngularVelocity(const PxReal maxAngularVelocity) = 0; + + /** + \brief Gets the limit on the magnitude of the angular velocity at the articulation's center of mass. + + \return The maximal angular velocity magnitude. + + @see setMaxCOMAngularVelocity + */ + virtual PxReal getMaxCOMAngularVelocity() const = 0; + + /** + \brief Adds a link to the articulation with default attribute values. + + \param[in] parent The parent link in the articulation. Must be NULL if (and only if) this is the root link. + \param[in] pose The initial pose of the new link. Must be a valid transform. + + \return The new link, or NULL if the link cannot be created. + + \note Creating a link is not allowed while the articulation is in a scene. In order to add a link, + remove and then re-add the articulation to the scene. + + @see PxArticulationLink + */ + virtual PxArticulationLink* createLink(PxArticulationLink* parent, const PxTransform& pose) = 0; + + /** + \brief Releases the articulation, and all its links and corresponding joints. + + Attached sensors and tendons are released automatically when the articulation is released. + + \note This call may not be made during simulation. + */ + virtual void release() = 0; + + /** + \brief Returns the number of links in the articulation. + + \return The number of links. + */ + virtual PxU32 getNbLinks() const = 0; + + /** + \brief Returns the set of links in the articulation in the order that they were added to the articulation using createLink. + + \param[in] userBuffer Buffer into which to write the array of articulation link pointers. + \param[in] bufferSize The size of the buffer. If the buffer is not large enough to contain all the pointers to links, + only as many as will fit are written. + \param[in] startIndex Index of first link pointer to be retrieved. + + \return The number of links written into the buffer. + + @see PxArticulationLink + */ + virtual PxU32 getLinks(PxArticulationLink** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0; + + /** + \brief Returns the number of shapes in the articulation. + + \return The number of shapes. + */ + virtual PxU32 getNbShapes() const = 0; + + /** + \brief Sets a name string for the articulation that can be retrieved with getName(). + + This is for debugging and is not used by the SDK. The string is not copied by the SDK, + only the pointer is stored. + + \param[in] name String to set the articulation's name to. + + @see getName() + */ + virtual void setName(const char* name) = 0; + + /** + \brief Returns the name string set with setName(). + + \return Name string associated with the articulation. + + @see setName() + */ + virtual const char* getName() const = 0; + + /** + \brief Returns the axis-aligned bounding box enclosing the articulation. + + \param[in] inflation Scale factor for computed world bounds. Box extents are multiplied by this value. + + \return The articulation's bounding box. + + \note It is not allowed to use this method while the simulation is running, except in a split simulation + during #PxScene::collide() and up to #PxScene::advance(), and in PxContactModifyCallback or in contact report callbacks. + + @see PxBounds3 + */ + virtual PxBounds3 getWorldBounds(float inflation = 1.01f) const = 0; + + /** + \brief Returns the aggregate the articulation might be a part of. + + \return The aggregate the articulation is a part of, or NULL if the articulation does not belong to an aggregate. + + @see PxAggregate + */ + virtual PxAggregate* getAggregate() const = 0; + + /** + \brief Sets flags on the articulation. + + \param[in] flags The articulation flags. + + \note This call may not be made during simulation. + + @see PxArticulationFlag */ virtual void setArticulationFlags(PxArticulationFlags flags) = 0; /** - \brief Raises or clears a flag on the articulation + \brief Raises or clears a flag on the articulation. - \param[in] flag The articulation flag - \param[in] value true/false indicating whether to raise or clear the flag + \param[in] flag The articulation flag. + \param[in] value The value to set the flag to. + \note This call may not be made during simulation. + + @see PxArticulationFlag */ virtual void setArticulationFlag(PxArticulationFlag::Enum flag, bool value) = 0; /** - \brief return PxArticulationFlags + \brief Returns the articulation's flags. + + \return The flags. + + @see PxArticulationFlag */ virtual PxArticulationFlags getArticulationFlags() const = 0; /** - \brief returns the total Dofs of the articulation + \brief Returns the total number of joint degrees-of-freedom (DOFs) of the articulation. + + - The six DOFs of the base of a floating-base articulation are not included in this count. + - Example: Both a fixed-base and a floating-base double-pendulum with two revolute joints will have getDofs() == 2. + - The return value is only valid for articulations that are in a scene. + + \return The number of joint DOFs, or 0xFFFFFFFF if the articulation is not in a scene. + */ virtual PxU32 getDofs() const = 0; /** - \brief create an articulation cache + \brief Creates an articulation cache that can be used to read and write internal articulation data. - \note this call may only be made on articulations that are in a scene, and may not be made during simulation + - When the structure of the articulation changes (e.g. adding a link or sensor) after the cache was created, + the cache needs to be released and recreated. + - Free the memory allocated for the cache by calling the release() method on the cache. + - Caches can only be created by articulations that are in a scene. + + \return The cache, or NULL if the articulation is not in a scene. + + @see applyCache, copyInternalStateToCache */ virtual PxArticulationCache* createCache() const = 0; /** - \brief Get the size of the articulation cache + \brief Returns the size of the articulation cache in bytes. - \note this call may only be made on articulations that are in a scene, and may not be made during simulation + - The size does not include: the user-allocated memory for the coefficient matrix or lambda values; + the scratch-related memory/members; and the cache version. See comment in #PxArticulationCache. + - The return value is only valid for articulations that are in a scene. + + \return The byte size of the cache, or 0xFFFFFFFF if the articulation is not in a scene. + + @see PxArticulationCache */ virtual PxU32 getCacheDataSize() const = 0; /** - \brief zero all data in the articulation cache beside the cache version + \brief Zeroes all data in the articulation cache, except user-provided and scratch memory, and cache version. - \note this call may only be made on articulations that are in a scene, and may not be made during simulation + \note This call may only be made on articulations that are in a scene. + + @see PxArticulationCache */ - virtual void zeroCache(PxArticulationCache& cache) = 0; + virtual void zeroCache(PxArticulationCache& cache) const = 0; /** - \brief apply the user defined data in the cache to the articulation system + \brief Applies the data in the cache to the articulation. - \param[in] cache articulation data. - \param[in] flag The mode to use when determine which value in the cache will be applied to the articulation - \param[in] autowake Specify if the call should wake up the articulation if it is currently asleep. If true and the current wake counter value is smaller than #PxSceneDesc::wakeCounterResetValue it will get increased to the reset value. + This call wakes the articulation if it is sleeping, and the autowake parameter is true (default) or: + - a nonzero joint velocity is applied or + - a nonzero joint force is applied or + - a nonzero root velocity is applied - @see createCache copyInternalStateToCache + \param[in] cache The articulation data. + \param[in] flags Indicate which data in the cache to apply to the articulation. + \param[in] autowake If true, the call wakes up the articulation and increases the wake counter to #PxSceneDesc::wakeCounterResetValue + if the counter value is below the reset value. + + \note This call may only be made on articulations that are in a scene, and may not be made during simulation. + + @see PxArticulationCache, PxArticulationCacheFlags, createCache, copyInternalStateToCache, PxScene::applyArticulationData */ - virtual void applyCache(PxArticulationCache& cache, const PxArticulationCacheFlags flag, bool autowake = true) = 0; + virtual void applyCache(PxArticulationCache& cache, const PxArticulationCacheFlags flags, bool autowake = true) = 0; /** - \brief copy the internal data of the articulation to the cache + \brief Copies internal data of the articulation to the cache. - \param[in] cache articulation data - \param[in] flag this indicates what kind of data the articulation system need to copy to the cache + \param[in] cache The articulation data. + \param[in] flags Indicate which data to copy from the articulation to the cache. - @see createCache applyCache + \note This call may only be made on articulations that are in a scene, and may not be made during simulation. + + @see PxArticulationCache, PxArticulationCacheFlags, createCache, applyCache */ - virtual void copyInternalStateToCache(PxArticulationCache& cache, const PxArticulationCacheFlags flag) const = 0; + virtual void copyInternalStateToCache(PxArticulationCache& cache, const PxArticulationCacheFlags flags) const = 0; + /** - \brief release an articulation cache + \brief Converts maximal-coordinate joint DOF data to reduced coordinates. - \param[in] cache the cache to release + - Indexing into the maximal joint DOF data is via the link's low-level index minus 1 (the root link is not included). + - The reduced-coordinate data follows the cache indexing convention, see PxArticulationCache::jointVelocity. - @see createCache applyCache copyInternalStateToCache - */ - virtual void releaseCache(PxArticulationCache& cache) const = 0; + \param[in] maximum The maximal-coordinate joint DOF data, N = (getNbLinks() - 1) * 6 + \param[out] reduced The reduced-coordinate joint DOF data, N = getDofs() - /** - \brief reduce the maximum data format to the reduced internal data - \param[in] maximum joint data format - \param[out] reduced joint data format + \note The articulation must be in a scene. + + @see unpackJointData */ virtual void packJointData(const PxReal* maximum, PxReal* reduced) const = 0; /** - \brief turn the reduced internal data to maximum joint data format - \param[in] reduced joint data format - \param[out] maximum joint data format + \brief Converts reduced-coordinate joint DOF data to maximal coordinates. + + - Indexing into the maximal joint DOF data is via the link's low-level index minus 1 (the root link is not included). + - The reduced-coordinate data follows the cache indexing convention, see PxArticulationCache::jointVelocity. + + \param[in] reduced The reduced-coordinate joint DOF data, N = getDofs(). + \param[out] maximum The maximal-coordinate joint DOF data, N = (getNbLinks() - 1) * 6. + + \note The articulation must be in a scene. + + @see packJointData */ virtual void unpackJointData(const PxReal* reduced, PxReal* maximum) const = 0; /** - \brief initialize all the common data for inverse dynamics + \brief Prepares common articulation data based on articulation pose for inverse dynamics calculations. + + Usage: + -# Set articulation pose (joint positions and base transform) via articulation cache and applyCache(). + -# Call commonInit. + -# Call inverse dynamics computation method. + + \note This call may only be made on articulations that are in a scene, and may not be made during simulation. + + @see computeGeneralizedGravityForce, computeCoriolisAndCentrifugalForce */ virtual void commonInit() const = 0; /** - \brief determine the statically balance of the joint force of gravity for entire articulation. External force, joint velocity and joint acceleration - are set to zero, the joint force returned will be purely determined by gravity. + \brief Computes the joint DOF forces required to counteract gravitational forces for the given articulation pose. + + - Inputs: Articulation pose (joint positions + base transform). + - Outputs: Joint forces to counteract gravity (in cache). + + - The joint forces returned are determined purely by gravity for the articulation in the current joint and base pose, and joints at rest; + i.e. external forces, joint velocities, and joint accelerations are set to zero. Joint drives are also not considered in the computation. + - commonInit() must be called before the computation, and after setting the articulation pose via applyCache(). + + \param[out] cache Out: PxArticulationCache::jointForce. + + \note This call may only be made on articulations that are in a scene, and may not be made during simulation. - \param[out] cache return joint forces which can counteract gravity force - @see commonInit */ virtual void computeGeneralizedGravityForce(PxArticulationCache& cache) const = 0; /** - \brief determine coriolise and centrifugal force. External force, gravity and joint acceleration - are set to zero, the joint force return will be coriolise and centrifugal force for each joint. + \brief Computes the joint DOF forces required to counteract Coriolis and centrifugal forces for the given articulation state. + + - Inputs: Articulation state (joint positions and velocities (in cache), and base transform and spatial velocity). + - Outputs: Joint forces to counteract Coriolis and centrifugal forces (in cache). + + - The joint forces returned are determined purely by the articulation's state; i.e. external forces, gravity, and joint accelerations are set to zero. + Joint drives and potential damping terms, such as link angular or linear damping, or joint friction, are also not considered in the computation. + - Prior to the computation, update/set the base spatial velocity with PxArticulationCache::rootLinkData and applyCache(). + - commonInit() must be called before the computation, and after setting the articulation pose via applyCache(). + + \param[in,out] cache In: PxArticulationCache::jointVelocity; Out: PxArticulationCache::jointForce. + + \note This call may only be made on articulations that are in a scene, and may not be made during simulation. - \param[in] cache data - @see commonInit */ virtual void computeCoriolisAndCentrifugalForce(PxArticulationCache& cache) const = 0; /** - \brief determine joint force change caused by external force. Gravity, joint acceleration and joint velocity - are all set to zero. + \brief Computes the joint DOF forces required to counteract external spatial forces applied to articulation links. - \param[in] cache data + - Inputs: External forces on links (in cache), articulation pose (joint positions + base transform). + - Outputs: Joint forces to counteract the external forces (in cache). + + - Only the external spatial forces provided in the cache and the articulation pose are considered in the computation. + - The external spatial forces are with respect to the links' centers of mass, and not the actor's origin. + - commonInit() must be called before the computation, and after setting the articulation pose via applyCache(). + + \param[in,out] cache In: PxArticulationCache::externalForces; Out: PxArticulationCache::jointForce. + + \note This call may only be made on articulations that are in a scene, and may not be made during simulation. @see commonInit */ virtual void computeGeneralizedExternalForce(PxArticulationCache& cache) const = 0; /** - \brief determine the joint acceleration for each joint - This is purely calculates the change in joint acceleration due to change in the joint force + \brief Computes the joint accelerations for the given articulation state and joint forces. + + - Inputs: Joint forces (in cache) and articulation state (joint positions and velocities (in cache), and base transform and spatial velocity). + - Outputs: Joint accelerations (in cache). + + - The computation includes Coriolis terms and gravity. However, joint drives and potential damping terms are not considered in the computation + (for example, linear link damping or joint friction). + - Prior to the computation, update/set the base spatial velocity with PxArticulationCache::rootLinkData and applyCache(). + - commonInit() must be called before the computation, and after setting the articulation pose via applyCache(). + + \param[in,out] cache In: PxArticulationCache::jointForce and PxArticulationCache::jointVelocity; Out: PxArticulationCache::jointAcceleration. + + \note This call may only be made on articulations that are in a scene, and may not be made during simulation. - \param[in] cache articulation data - @see commonInit */ virtual void computeJointAcceleration(PxArticulationCache& cache) const = 0; /** - \brief determine the joint force - This is purely calculates the change in joint force due to change in the joint acceleration - This means gravity and joint velocity will be zero + \brief Computes the joint forces for the given articulation state and joint accelerations, not considering gravity. + + - Inputs: Joint accelerations (in cache) and articulation state (joint positions and velocities (in cache), and base transform and spatial velocity). + - Outputs: Joint forces (in cache). + + - The computation includes Coriolis terms. However, joint drives and potential damping terms are not considered in the computation + (for example, linear link damping or joint friction). + - Prior to the computation, update/set the base spatial velocity with PxArticulationCache::rootLinkData and applyCache(). + - commonInit() must be called before the computation, and after setting the articulation pose via applyCache(). + + \param[in,out] cache In: PxArticulationCache::jointAcceleration and PxArticulationCache::jointVelocity; Out: PxArticulationCache::jointForce. + + \note This call may only be made on articulations that are in a scene, and may not be made during simulation. - \param[in] cache return joint force - @see commonInit */ virtual void computeJointForce(PxArticulationCache& cache) const = 0; /** - \brief compute the dense Jacobian for the entire articulation in world space - \param[out] cache sets cache.denseJacobian matrix. The matrix is indexed [nCols * row + column]. - \param[out] nRows set to number of rows in matrix, which corresponds to the number of articulation links times 6. - \param[out] nCols set to number of columns in matrix, which corresponds to the number of joint DOFs, plus 6 in the case eFIX_BASE is false. + \brief Compute the dense Jacobian for the articulation in world space, including the DOFs of a potentially floating base. - Note that this computes the dense representation of an inherently sparse matrix. Multiplication with this matrix maps - joint space velocities to 6DOF world space linear and angular velocities. + This computes the dense representation of an inherently sparse matrix. Multiplication with this matrix maps + joint space velocities to world-space linear and angular (i.e. spatial) velocities of the centers of mass of the links. + + \param[out] cache Sets cache.denseJacobian matrix. The matrix is indexed [nCols * row + column]. + \param[out] nRows Set to number of rows in matrix, which corresponds to nbLinks() * 6, minus 6 if PxArticulationFlag::eFIX_BASE is true. + \param[out] nCols Set to number of columns in matrix, which corresponds to the number of joint DOFs, plus 6 in the case PxArticulationFlag::eFIX_BASE is false. + + \note This call may only be made on articulations that are in a scene, and may not be made during simulation. */ virtual void computeDenseJacobian(PxArticulationCache& cache, PxU32& nRows, PxU32& nCols) const = 0; - /** - \brief compute the coefficient matrix for contact force. - \param[out] cache returns the coefficient matrix. Each column is the joint force effected by a contact based on impulse strength 1 - @see commonInit + \brief Computes the coefficient matrix for contact forces. + + - The matrix dimension is getCoefficientMatrixSize() = getDofs() * getNbLoopJoints(), and the DOF (column) indexing follows the internal DOF order, see PxArticulationCache::jointVelocity. + - Each column in the matrix is the joint forces effected by a contact based on impulse strength 1. + - The user must allocate memory for PxArticulationCache::coefficientMatrix where the required size of the PxReal array is equal to getCoefficientMatrixSize(). + - commonInit() must be called before the computation, and after setting the articulation pose via applyCache(). + + \param[out] cache Out: PxArticulationCache::coefficientMatrix. + + \note This call may only be made on articulations that are in a scene, and may not be made during simulation. + + @see commonInit, getCoefficientMatrixSize */ virtual void computeCoefficientMatrix(PxArticulationCache& cache) const = 0; - + /** - \brief compute the lambda value when the test impulse is 1 - \param[in] initialState the initial state of the articulation system - \param[in] jointTorque M(q)*qddot + C(q,qdot) + g(q) - \param[in] maxIter maximum number of solver iterations to run. If the system converges, fewer iterations may be used. - \param[out] cache returns the coefficient matrix. Each column is the joint force effected by a contact based on impulse strength 1 - @see commonInit + \brief Computes the lambda values when the test impulse is 1. + + - The user must allocate memory for PxArticulationCache::lambda where the required size of the PxReal array is equal to getNbLoopJoints(). + - commonInit() must be called before the computation, and after setting the articulation pose via applyCache(). + + \param[out] cache Out: PxArticulationCache::lambda. + \param[in] initialState The initial state of the articulation system. + \param[in] jointTorque M(q)*qddot + C(q,qdot) + g(q) <- calculate by summing joint forces obtained with computeJointForce and computeGeneralizedGravityForce. + \param[in] maxIter Maximum number of solver iterations to run. If the system converges, fewer iterations may be used. + + \return True if convergence was achieved within maxIter; False if convergence was not achieved or the operation failed otherwise. + + \note This call may only be made on articulations that are in a scene, and may not be made during simulation. + + @see commonInit, getNbLoopJoints */ virtual bool computeLambda(PxArticulationCache& cache, PxArticulationCache& initialState, const PxReal* const jointTorque, const PxU32 maxIter) const = 0; - + /** - \brief compute the joint-space inertia matrix - \param[in] cache articulation data + \brief Compute the joint-space inertia matrix that maps joint accelerations to joint forces: forces = M * accelerations. + + - Inputs: Articulation pose (joint positions and base transform). + - Outputs: Mass matrix (in cache). + + commonInit() must be called before the computation, and after setting the articulation pose via applyCache(). + + \param[out] cache Out: PxArticulationCache::massMatrix. + + \note This call may only be made on articulations that are in a scene, and may not be made during simulation. @see commonInit */ virtual void computeGeneralizedMassMatrix(PxArticulationCache& cache) const = 0; - - /** - \brief add loop joint to the articulation system for inverse dynamic - \param[in] joint required to add loop joint - @see commonInit + /** + \brief Adds a loop joint to the articulation system for inverse dynamics. + + \param[in] joint The joint to add. + + \note This call may not be made during simulation. + + @see PxContactJoint, PxFixedJoint, PxSphericalJoint, PxRevoluteJoint, PxPrismaticJoint, PxDistanceJoint, PxD6Joint */ - virtual void addLoopJoint(PxJoint* joint) = 0; + virtual void addLoopJoint(PxConstraint* joint) = 0; /** - \brief remove loop joint from the articulation system - \param[in] joint required to remove loop joint + \brief Removes a loop joint from the articulation for inverse dynamics. - @see commonInit + \note This call may not be made during simulation. + + \param[in] joint The joint to remove. */ - virtual void removeLoopJoint(PxJoint* joint) = 0; + virtual void removeLoopJoint(PxConstraint* joint) = 0; /** - \brief returns the number of loop joints in the articulation - \return number of loop joints + \brief Returns the number of loop joints in the articulation for inverse dynamics. + + \return The number of loop joints. */ virtual PxU32 getNbLoopJoints() const = 0; /** - \brief returns the set of loop constraints in the articulation + \brief Returns the set of loop constraints (i.e. joints) in the articulation. - \param[in] userBuffer buffer into which to write an array of constraints pointers - \param[in] bufferSize the size of the buffer. If this is not large enough to contain all the pointers to links, - only as many as will fit are written. - \param[in] startIndex Index of first link pointer to be retrieved + \param[in] userBuffer Target buffer for the constraint pointers. + \param[in] bufferSize The size of the buffer. If this is not large enough to contain all the pointers to the constraints, + only as many as will fit are written. Use getNbLoopJoints() to size the buffer for retrieving all constraints. + \param[in] startIndex Index of first constraint pointer to be retrieved. - \return the number of links written into the buffer. - - @see ArticulationLink + \return The number of constraints written into the buffer. */ - virtual PxU32 getLoopJoints(PxJoint** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0; + virtual PxU32 getLoopJoints(PxConstraint** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0; /** - \brief returns the required size of coeffient matrix in the articulation. The coefficient matrix is number of constraint(loop joints) by total dofs. Constraint Torque = transpose(K) * lambda(). Lambda is a vector of number of constraints - \return bite size of the coefficient matrix(nc * n) + \brief Returns the required size of the coefficient matrix in the articulation. + + \return Size of the coefficient matrix (equal to getDofs() * getNbLoopJoints()). + + \note This call may only be made on articulations that are in a scene. + + @see computeCoefficientMatrix */ virtual PxU32 getCoefficientMatrixSize() const = 0; /** - \brief teleport root link to a new location - \param[in] pose the new location of the root link - \param[in] autowake wake up the articulation system - - @see commonInit - */ - virtual void teleportRootLink(const PxTransform& pose, bool autowake) = 0; + \brief Sets the root link transform (world to actor frame). + - For performance, prefer PxArticulationCache::rootLinkData to set the root link transform in a batch articulation state update. + - Use updateKinematic() after all state updates to the articulation via non-cache API such as this method, + in order to update link states for the next simulation frame or querying. + + \param[in] pose The new root link transform. + \param[in] autowake If true and the articulation is in a scene, the call wakes up the articulation and increases the wake counter + to #PxSceneDesc::wakeCounterResetValue if the counter value is below the reset value. + + \note This call may not be made during simulation. + + @see getRootGlobalPose, updateKinematic, PxArticulationCache, applyCache + */ + virtual void setRootGlobalPose(const PxTransform& pose, bool autowake = true) = 0; /** - \brief return the link velocity in world space with the associated low-level link index(getLinkIndex()). - \param[in] linkId low-level link index + \brief Returns the root link transform (world to actor frame). - @see getLinkIndex() in PxArticulationLink + For performance, prefer PxArticulationCache::rootLinkData to get the root link transform in a batch query. + + \return The root link transform. + + \note This call is not allowed while the simulation is running except in a split simulation during #PxScene::collide() and up to #PxScene::advance(), + and in PxContactModifyCallback or in contact report callbacks. + + @see setRootGlobalPose, PxArticulationCache, copyInternalStateToCache */ - virtual PxSpatialVelocity getLinkVelocity(const PxU32 linkId) = 0; - + virtual PxTransform getRootGlobalPose() const = 0; /** - \brief return the link acceleration in world space with the associated low-level link index(getLinkIndex()) - \param[in] linkId low-level link index + \brief Sets the root link linear center-of-mass velocity. - @see getLinkIndex() in PxArticulationLink + - The linear velocity is with respect to the link's center of mass and not the actor frame origin. + - For performance, prefer PxArticulationCache::rootLinkData to set the root link velocity in a batch articulation state update. + - The articulation is woken up if the input velocity is nonzero (ignoring autowake) and the articulation is in a scene. + - Use updateKinematic() after all state updates to the articulation via non-cache API such as this method, + in order to update link states for the next simulation frame or querying. + + \param[in] linearVelocity The new root link center-of-mass linear velocity. + \param[in] autowake If true and the articulation is in a scene, the call wakes up the articulation and increases the wake counter + to #PxSceneDesc::wakeCounterResetValue if the counter value is below the reset value. + + \note This call may not be made during simulation, except in a split simulation in-between #PxScene::fetchCollision and #PxScene::advance. + + @see updateKinematic, getRootLinearVelocity, setRootAngularVelocity, getRootAngularVelocity, PxRigidBody::getCMassLocalPose, PxArticulationCache, applyCache + */ + virtual void setRootLinearVelocity(const PxVec3& linearVelocity, bool autowake = true) = 0; + + /** + \brief Gets the root link center-of-mass linear velocity. + + - The linear velocity is with respect to the link's center of mass and not the actor frame origin. + - For performance, prefer PxArticulationCache::rootLinkData to get the root link velocity in a batch query. + + \return The root link center-of-mass linear velocity. + + \note This call is not allowed while the simulation is running except in a split simulation during #PxScene::collide() and up to #PxScene::advance(), + and in PxContactModifyCallback or in contact report callbacks. + + @see setRootLinearVelocity, setRootAngularVelocity, getRootAngularVelocity, PxRigidBody::getCMassLocalPose, PxArticulationCache, applyCache + */ + virtual PxVec3 getRootLinearVelocity(void) const = 0; + + /** + \brief Sets the root link angular velocity. + + - For performance, prefer PxArticulationCache::rootLinkData to set the root link velocity in a batch articulation state update. + - The articulation is woken up if the input velocity is nonzero (ignoring autowake) and the articulation is in a scene. + - Use updateKinematic() after all state updates to the articulation via non-cache API such as this method, + in order to update link states for the next simulation frame or querying. + + \param[in] angularVelocity The new root link angular velocity. + \param[in] autowake If true and the articulation is in a scene, the call wakes up the articulation and increases the wake counter + to #PxSceneDesc::wakeCounterResetValue if the counter value is below the reset value. + + \note This call may not be made during simulation, except in a split simulation in-between #PxScene::fetchCollision and #PxScene::advance. + + @see updateKinematic, getRootAngularVelocity, setRootLinearVelocity, getRootLinearVelocity, PxArticulationCache, applyCache + */ + virtual void setRootAngularVelocity(const PxVec3& angularVelocity, bool autowake = true) = 0; + + /** + \brief Gets the root link angular velocity. + + For performance, prefer PxArticulationCache::rootLinkData to get the root link velocity in a batch query. + + \return The root link angular velocity. + + \note This call is not allowed while the simulation is running except in a split simulation during #PxScene::collide() and up to #PxScene::advance(), + and in PxContactModifyCallback or in contact report callbacks. + + @see setRootAngularVelocity, setRootLinearVelocity, getRootLinearVelocity, PxArticulationCache, applyCache + */ + virtual PxVec3 getRootAngularVelocity(void) const = 0; + + /** + \brief Returns the (classical) link acceleration in world space for the given low-level link index. + + - The returned acceleration is not a spatial, but a classical, i.e. body-fixed acceleration (https://en.wikipedia.org/wiki/Spatial_acceleration). + - The (linear) acceleration is with respect to the link's center of mass and not the actor frame origin. + + \param[in] linkId The low-level link index, see PxArticulationLink::getLinkIndex. + + \return The link's center-of-mass classical acceleration, or 0 if the call is made before the articulation participated in a first simulation step. + + \note This call may only be made on articulations that are in a scene, and it is not allowed to use this method while the simulation + is running except in a split simulation during #PxScene::collide() and up to #PxScene::advance(), and in PxContactModifyCallback or in contact report callbacks. + + @see PxArticulationLink::getLinkIndex, PxRigidBody::getCMassLocalPose */ virtual PxSpatialVelocity getLinkAcceleration(const PxU32 linkId) = 0; - protected: - PX_INLINE PxArticulationReducedCoordinate(PxType concreteType, PxBaseFlags baseFlags) : PxArticulationBase(concreteType, baseFlags) {} - PX_INLINE PxArticulationReducedCoordinate(PxBaseFlags baseFlags) : PxArticulationBase(baseFlags) {} + /** + \brief Returns the GPU articulation index. + + \return The GPU index, or 0xFFFFFFFF if the articulation is not in a scene or PxSceneFlag::eSUPPRESS_READBACK is not set. + */ + virtual PxU32 getGpuArticulationIndex() = 0; + + /** + \brief Creates a spatial tendon to attach to the articulation with default attribute values. + + \return The new spatial tendon. + + \note Creating a spatial tendon is not allowed while the articulation is in a scene. In order to + add the tendon, remove and then re-add the articulation to the scene. + + @see PxArticulationSpatialTendon + */ + virtual PxArticulationSpatialTendon* createSpatialTendon() = 0; + + /** + \brief Creates a fixed tendon to attach to the articulation with default attribute values. + + \return The new fixed tendon. + + \note Creating a fixed tendon is not allowed while the articulation is in a scene. In order to + add the tendon, remove and then re-add the articulation to the scene. + + @see PxArticulationFixedTendon + */ + virtual PxArticulationFixedTendon* createFixedTendon() = 0; + + /** + \brief Creates a force sensor attached to a link of the articulation. + + \param[in] link The link to attach the sensor to. + \param[in] relativePose The sensor frame's relative pose to the link's body frame, i.e. the transform body frame -> sensor frame. + The link body frame is at the center of mass and aligned with the principal axes of inertia, see PxRigidBody::getCMassLocalPose. + + \return The new sensor. + + \note Creating a sensor is not allowed while the articulation is in a scene. In order to + add the sensor, remove and then re-add the articulation to the scene. + + @see PxArticulationSensor + */ + virtual PxArticulationSensor* createSensor(PxArticulationLink* link, const PxTransform& relativePose) = 0; + + + /** + \brief Returns the spatial tendons attached to the articulation. + + The order of the tendons in the buffer is not necessarily identical to the order in which the tendons were added to the articulation. + + \param[in] userBuffer The buffer into which to write the array of pointers to the tendons. + \param[in] bufferSize The size of the buffer. If this is not large enough to contain all the pointers to tendons, + only as many as will fit are written. Use getNbSpatialTendons to size for all attached tendons. + \param[in] startIndex Index of first tendon pointer to be retrieved. + + \return The number of tendons written into the buffer. + + @see PxArticulationSpatialTendon, getNbSpatialTendons + */ + virtual PxU32 getSpatialTendons(PxArticulationSpatialTendon** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0; + + /** + \brief Returns the number of spatial tendons in the articulation. + + \return The number of tendons. + */ + virtual PxU32 getNbSpatialTendons() = 0; + + /** + \brief Returns the fixed tendons attached to the articulation. + + The order of the tendons in the buffer is not necessarily identical to the order in which the tendons were added to the articulation. + + \param[in] userBuffer The buffer into which to write the array of pointers to the tendons. + \param[in] bufferSize The size of the buffer. If this is not large enough to contain all the pointers to tendons, + only as many as will fit are written. Use getNbFixedTendons to size for all attached tendons. + \param[in] startIndex Index of first tendon pointer to be retrieved. + + \return The number of tendons written into the buffer. + + @see PxArticulationFixedTendon, getNbFixedTendons + */ + virtual PxU32 getFixedTendons(PxArticulationFixedTendon** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0; + + /** + \brief Returns the number of fixed tendons in the articulation. + + \return The number of tendons. + */ + virtual PxU32 getNbFixedTendons() = 0; + + /** + \brief Returns the sensors attached to the articulation. + + The order of the sensors in the buffer is not necessarily identical to the order in which the sensors were added to the articulation. + + \param[in] userBuffer The buffer into which to write the array of pointers to the sensors. + \param[in] bufferSize The size of the buffer. If this is not large enough to contain all the pointers to sensors, + only as many as will fit are written. Use getNbSensors to size for all attached sensors. + \param[in] startIndex Index of first sensor pointer to be retrieved. + + \return The number of sensors written into the buffer. + + @see PxArticulationSensor, getNbSensors + */ + + virtual PxU32 getSensors(PxArticulationSensor** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0; + + /** + \brief Returns the number of sensors in the articulation. + + \return The number of sensors. + */ + virtual PxU32 getNbSensors() = 0; + + /** + \brief Update link velocities and/or positions in the articulation. + + For performance, prefer the PxArticulationCache API that performs batch articulation state updates. + + If the application updates the root state (position and velocity) or joint state via any combination of + the non-cache API calls + + - setRootGlobalPose(), setRootLinearVelocity(), setRootAngularVelocity() + - PxArticulationJointReducedCoordinate::setJointPosition(), PxArticulationJointReducedCoordinate::setJointVelocity() + + the application needs to call this method after the state setting in order to update the link states for + the next simulation frame or querying. + + Use + - PxArticulationKinematicFlag::ePOSITION after any changes to the articulation root or joint positions using non-cache API calls. Updates links' positions and velocities. + - PxArticulationKinematicFlag::eVELOCITY after velocity-only changes to the articulation root or joints using non-cache API calls. Updates links' velocities only. + + \note This call may only be made on articulations that are in a scene, and may not be made during simulation. + + @see PxArticulationKinematicFlags, PxArticulationCache, applyCache + */ + virtual void updateKinematic(PxArticulationKinematicFlags flags) = 0; + virtual ~PxArticulationReducedCoordinate() {} + + void* userData; //!< user can assign this to whatever, usually to create a 1:1 relationship with a user object. + + protected: + PX_INLINE PxArticulationReducedCoordinate(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags) {} + PX_INLINE PxArticulationReducedCoordinate(PxBaseFlags baseFlags) : PxBase(baseFlags) {} + }; #if PX_VC diff --git a/Source/ThirdParty/PhysX/PxArticulationTendon.h b/Source/ThirdParty/PhysX/PxArticulationTendon.h new file mode 100644 index 000000000..6f47d0f3c --- /dev/null +++ b/Source/ThirdParty/PhysX/PxArticulationTendon.h @@ -0,0 +1,589 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + + +#ifndef PX_ARTICULATION_TENDON_H +#define PX_ARTICULATION_TENDON_H +/** \addtogroup physics +@{ */ + +#include "PxPhysXConfig.h" +#include "common/PxBase.h" +#include "solver/PxSolverDefs.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + class PxArticulationSpatialTendon; + class PxArticulationFixedTendon; + class PxArticulationLink; + /** + \brief Defines the low/high limits of the length of a tendon. + */ + class PxArticulationTendonLimit + { + public: + PxReal lowLimit; + PxReal highLimit; + }; + + /** + \brief Defines a spatial tendon attachment point on a link. + */ + class PxArticulationAttachment : public PxBase + { + + public: + + virtual ~PxArticulationAttachment() {} + /** + \brief Sets the spring rest length for the sub-tendon from the root to this leaf attachment. + + Setting this on non-leaf attachments has no effect. + + \param[in] restLength The rest length of the spring. + Default: 0 + + @see getRestLength(), isLeaf() + */ + virtual void setRestLength(const PxReal restLength) = 0; + + /** + \brief Gets the spring rest length for the sub-tendon from the root to this leaf attachment. + + \return The rest length. + + @see setRestLength() + */ + virtual PxReal getRestLength() const = 0; + + /** + \brief Sets the low and high limit on the length of the sub-tendon from the root to this leaf attachment. + + Setting this on non-leaf attachments has no effect. + + \param[in] parameters Struct with the low and high limit. + Default: (PX_MAX_F32, -PX_MAX_F32) (i.e. an invalid configuration that can only work if stiffness is zero) + + @see PxArticulationTendonLimit, getLimitParameters(), isLeaf() + */ + virtual void setLimitParameters(const PxArticulationTendonLimit& parameters) = 0; + + /** + \brief Gets the low and high limit on the length of the sub-tendon from the root to this leaf attachment. + + \return Struct with the low and high limit. + + @see PxArticulationTendonLimit, setLimitParameters() + */ + virtual PxArticulationTendonLimit getLimitParameters() const = 0; + + /** + \brief Sets the attachment's relative offset in the link actor frame. + + \param[in] offset The relative offset in the link actor frame. + + @see getRelativeOffset() + */ + virtual void setRelativeOffset(const PxVec3& offset) = 0; + + /** + \brief Gets the attachment's relative offset in the link actor frame. + + \return The relative offset in the link actor frame. + + @see setRelativeOffset() + */ + virtual PxVec3 getRelativeOffset() const = 0; + + /** + \brief Sets the attachment coefficient. + + \param[in] coefficient The scale that the distance between this attachment and its parent is multiplied by when summing up the spatial tendon's length. + + @see getCoefficient() + */ + virtual void setCoefficient(const PxReal coefficient) = 0; + + /** + \brief Gets the attachment coefficient. + + \return The scale that the distance between this attachment and its parent is multiplied by when summing up the spatial tendon's length. + + @see setCoefficient() + */ + virtual PxReal getCoefficient() const = 0; + + /** + \brief Gets the articulation link. + + \return The articulation link that this attachment is attached to. + */ + virtual PxArticulationLink* getLink() const = 0; + + /** + \brief Gets the parent attachment. + + \return The parent attachment. + */ + virtual PxArticulationAttachment* getParent() const = 0; + + /** + \brief Indicates that this attachment is a leaf, and thus defines a sub-tendon from the root to this attachment. + + \return True: This attachment is a leaf and has zero children; False: Not a leaf. + */ + virtual bool isLeaf() const = 0; + + /** + \brief Gets the spatial tendon that the attachment is a part of. + + \return The tendon. + + @see PxArticulationSpatialTendon + */ + virtual PxArticulationSpatialTendon* getTendon() const = 0; + + /** + \brief Releases the attachment. + + \note Releasing the attachment is not allowed while the articulation is in a scene. In order to + release the attachment, remove and then re-add the articulation to the scene. + + @see PxArticulationSpatialTendon::createAttachment() + */ + virtual void release() = 0; + + void* userData; //!< user can assign this to whatever, usually to create a 1:1 relationship with a user object. + + /** + \brief Returns the string name of the dynamic type. + + \return The string name. + */ + virtual const char* getConcreteTypeName() const { return "PxArticulationAttachment"; } + + protected: + + PX_INLINE PxArticulationAttachment(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags) {} + PX_INLINE PxArticulationAttachment(PxBaseFlags baseFlags) : PxBase(baseFlags) {} + }; + + + /** + \brief Defines a fixed-tendon joint on an articulation joint degree of freedom. + */ + class PxArticulationTendonJoint : public PxBase + { + + public: + + virtual ~PxArticulationTendonJoint() {} + + /** + \brief Sets the tendon joint coefficient. + + \param[in] axis The degree of freedom that the tendon joint operates on (must correspond to a degree of freedom of the associated link's incoming joint). + \param[in] coefficient The scale that the axis' joint position is multiplied by when summing up the fixed tendon's length. + \param[in] recipCoefficient The scale that the tendon's response is multiplied by when applying to this tendon joint. + + \note RecipCoefficient is commonly expected to be 1/coefficient, but it can be set to different values to tune behavior; for example, zero can be used to + have a joint axis only participate in the length computation of the tendon, but not have any tendon force applied to it. + + @see getCoefficient() + */ + virtual void setCoefficient(const PxArticulationAxis::Enum axis, const PxReal coefficient, const PxReal recipCoefficient) = 0; + + /** + \brief Gets the tendon joint coefficient. + + \param[out] axis The degree of freedom that the tendon joint operates on. + \param[out] coefficient The scale that the axis' joint position is multiplied by when summing up the fixed tendon's length. + \param[in] recipCoefficient The scale that the tendon's response is multiplied by when applying to this tendon joint. + + @see setCoefficient() + */ + virtual void getCoefficient(PxArticulationAxis::Enum& axis, PxReal& coefficient, PxReal& recipCoefficient) const = 0; + + /** + \brief Gets the articulation link. + + \return The articulation link (and its incoming joint in particular) that this tendon joint is associated with. + */ + virtual PxArticulationLink* getLink() const = 0; + + /** + \brief Gets the parent tendon joint. + + \return The parent tendon joint. + */ + virtual PxArticulationTendonJoint* getParent() const = 0; + + /** + \brief Gets the tendon that the joint is a part of. + + \return The tendon. + + @see PxArticulationFixedTendon + */ + virtual PxArticulationFixedTendon* getTendon() const = 0; + + /** + \brief Releases a tendon joint. + + \note Releasing a tendon joint is not allowed while the articulation is in a scene. In order to + release the joint, remove and then re-add the articulation to the scene. + + @see PxArticulationFixedTendon::createTendonJoint() + */ + virtual void release() = 0; + + void* userData; //!< user can assign this to whatever, usually to create a 1:1 relationship with a user object. + + /** + \brief Returns the string name of the dynamic type. + + \return The string name. + */ + virtual const char* getConcreteTypeName() const { return "PxArticulationTendonJoint"; } + + protected: + + PX_INLINE PxArticulationTendonJoint(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags) {} + PX_INLINE PxArticulationTendonJoint(PxBaseFlags baseFlags) : PxBase(baseFlags) {} + }; + + + /** + \brief Common API base class shared by PxArticulationSpatialTendon and PxArticulationFixedTendon. + */ + class PxArticulationTendon : public PxBase + { + public: + /** + \brief Sets the spring stiffness term acting on the tendon length. + + \param[in] stiffness The spring stiffness. + Default: 0 + + @see getStiffness() + */ + virtual void setStiffness(const PxReal stiffness) = 0; + + /** + \brief Gets the spring stiffness of the tendon. + + \return The spring stiffness. + + @see setStiffness() + */ + virtual PxReal getStiffness() const = 0; + + /** + \brief Sets the damping term acting both on the tendon length and tendon-length limits. + + \param[in] damping The damping term. + Default: 0 + + @see getDamping() + */ + virtual void setDamping(const PxReal damping) = 0; + + /** + \brief Gets the damping term acting both on the tendon length and tendon-length limits. + + \return The damping term. + + @see setDamping() + */ + virtual PxReal getDamping() const = 0; + + /** + \brief Sets the limit stiffness term acting on the tendon's length limits. + + For spatial tendons, this parameter applies to all its leaf attachments / sub-tendons. + + \param[in] stiffness The limit stiffness term. + Default: 0 + + @see getLimitStiffness() + */ + virtual void setLimitStiffness(const PxReal stiffness) = 0; + + /** + \brief Gets the limit stiffness term acting on the tendon's length limits. + + For spatial tendons, this parameter applies to all its leaf attachments / sub-tendons. + + \return The limit stiffness term. + + @see setLimitStiffness() + */ + virtual PxReal getLimitStiffness() const = 0; + + /** + \brief Sets the length offset term for the tendon. + + An offset defines an amount to be added to the accumulated length computed for the tendon. It allows the + application to actuate the tendon by shortening or lengthening it. + + \param[in] offset The offset term. Default: 0 + \param[in] autowake If true and the articulation is in a scene, the call wakes up the articulation and increases the wake counter + to #PxSceneDesc::wakeCounterResetValue if the counter value is below the reset value. + + @see getOffset() + */ + virtual void setOffset(const PxReal offset, bool autowake = true) = 0; + + /** + \brief Gets the length offset term for the tendon. + + \return The offset term. + + @see setOffset() + */ + virtual PxReal getOffset() const = 0; + + /** + \brief Gets the articulation that the tendon is a part of. + + \return The articulation. + + @see PxArticulationReducedCoordinate + */ + virtual PxArticulationReducedCoordinate* getArticulation() const = 0; + + /** + \brief Releases a tendon to remove it from the articulation and free its associated memory. + + When an articulation is released, its attached tendons are automatically released. + + \note Releasing a tendon is not allowed while the articulation is in a scene. In order to + release the tendon, remove and then re-add the articulation to the scene. + */ + + virtual void release() = 0; + + virtual ~PxArticulationTendon() {} + + void* userData; //!< user can assign this to whatever, usually to create a 1:1 relationship with a user object. + + protected: + PX_INLINE PxArticulationTendon(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags) {} + PX_INLINE PxArticulationTendon(PxBaseFlags baseFlags) : PxBase(baseFlags) {} + }; + + /** + \brief A spatial tendon that attaches to an articulation. + + A spatial tendon attaches to multiple links in an articulation using a set of PxArticulationAttachments. + The tendon is defined as a tree of attachment points, where each attachment can have an arbitrary number of children. + Each leaf of the attachment tree defines a subtendon between itself and the root attachment. The subtendon then + applies forces at the leaf, and an equal but opposing force at the root, in order to satisfy the spring-damper and limit + constraints that the user sets up. Attachments in between the root and leaf do not exert any force on the articulation, + but define the geometry of the tendon from which the length is computed together with the attachment coefficients. + */ + class PxArticulationSpatialTendon : public PxArticulationTendon + { + public: + /** + \brief Creates an articulation attachment and adds it to the list of children in the parent attachment. + + Creating an attachment is not allowed while the articulation is in a scene. In order to + add the attachment, remove and then re-add the articulation to the scene. + + \param[in] parent The parent attachment. Can be NULL for the root attachment of a tendon. + \param[in] coefficient A user-defined scale that the accumulated length is scaled by. + \param[in] relativeOffset An offset vector in the link's actor frame to the point where the tendon attachment is attached to the link. + \param[in] link The link that this attachment is associated with. + + \return The newly-created attachment if creation was successful, otherwise a null pointer. + + @see releaseAttachment() + */ + virtual PxArticulationAttachment* createAttachment(PxArticulationAttachment* parent, const PxReal coefficient, const PxVec3 relativeOffset, PxArticulationLink* link) = 0; + + /** + \brief Fills a user-provided buffer of attachment pointers with the set of attachments. + + \param[in] userBuffer The user-provided buffer. + \param[in] bufferSize The size of the buffer. If this is not large enough to contain all the pointers to attachments, + only as many as can fit are written. Use getNbAttachments to size for all attachments. + \param[in] startIndex Index of first attachment pointer to be retrieved. + + \return The number of attachments that were filled into the user buffer. + + @see getNbAttachments + */ + virtual PxU32 getAttachments(PxArticulationAttachment** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0; + + /** + \brief Returns the number of attachments in the tendon. + + \return The number of attachments. + */ + virtual PxU32 getNbAttachments() const = 0; + + /** + \brief Returns the string name of the dynamic type. + + \return The string name. + */ + virtual const char* getConcreteTypeName() const { return "PxArticulationSpatialTendon"; } + + virtual ~PxArticulationSpatialTendon() {} + + protected: + PX_INLINE PxArticulationSpatialTendon(PxType concreteType, PxBaseFlags baseFlags) : PxArticulationTendon(concreteType, baseFlags) {} + PX_INLINE PxArticulationSpatialTendon(PxBaseFlags baseFlags) : PxArticulationTendon(baseFlags) {} + + }; + + /** + \brief A fixed tendon that can be used to link multiple degrees of freedom of multiple articulation joints via length and limit constraints. + + Fixed tendons allow the simulation of coupled relationships between joint degrees of freedom in an articulation. Fixed tendons do not allow + linking arbitrary joint axes of the articulation: The respective joints must all be directly connected to each other in the articulation structure, + i.e. each of the joints in the tendon must be connected by a single articulation link to another joint in the same tendon. This implies both that + 1) fixed tendons can branch along a branching articulation; and 2) they cannot be used to create relationships between axes in a spherical joint with + more than one degree of freedom. Locked joint axes or fixed joints are currently not supported. + */ + class PxArticulationFixedTendon : public PxArticulationTendon + { + public: + /** + \brief Creates an articulation tendon joint and adds it to the list of children in the parent tendon joint. + + Creating a tendon joint is not allowed while the articulation is in a scene. In order to + add the joint, remove and then re-add the articulation to the scene. + + \param[in] parent The parent tendon joint. Can be NULL for the root tendon joint of a tendon. + \param[in] axis The degree of freedom that this tendon joint is associated with. + \param[in] coefficient A user-defined scale that the accumulated tendon length is scaled by. + \param[in] recipCoefficient The scale that the tendon's response is multiplied by when applying to this tendon joint. + \param[in] link The link (and the link's incoming joint in particular) that this tendon joint is associated with. + + \return The newly-created tendon joint if creation was successful, otherwise a null pointer. + + \note + - The axis motion must not be configured as PxArticulationMotion::eLOCKED. + - The axis cannot be part of a fixed joint, i.e. joint configured as PxArticulationJointType::eFIX. + + @see PxArticulationTendonJoint PxArticulationAxis + */ + virtual PxArticulationTendonJoint* createTendonJoint(PxArticulationTendonJoint* parent, PxArticulationAxis::Enum axis, const PxReal coefficient, const PxReal recipCoefficient, PxArticulationLink* link) = 0; + + /** + \brief Fills a user-provided buffer of tendon-joint pointers with the set of tendon joints. + + \param[in] userBuffer The user-provided buffer. + \param[in] bufferSize The size of the buffer. If this is not large enough to contain all the pointers to tendon joints, + only as many as can fit are written. Use getNbTendonJoints to size for all tendon joints. + \param[in] startIndex Index of first tendon joint pointer to be retrieved. + + \return The number of tendon joints filled into the user buffer. + + @see getNbTendonJoints + */ + virtual PxU32 getTendonJoints(PxArticulationTendonJoint** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0; + + /** + \brief Returns the number of tendon joints in the tendon. + + \return The number of tendon joints. + */ + virtual PxU32 getNbTendonJoints() const = 0; + + /** + \brief Sets the spring rest length of the tendon. + + The accumulated "length" of a fixed tendon is a linear combination of the joint axis positions that the tendon is + associated with, scaled by the respective tendon joints' coefficients. As such, when the joint positions of all + joints are zero, the accumulated length of a fixed tendon is zero. + + The spring of the tendon is not exerting any force on the articulation when the rest length is equal to the + tendon's accumulated length plus the tendon offset. + + \param[in] restLength The spring rest length of the tendon. + + @see getRestLength() + */ + virtual void setRestLength(const PxReal restLength) = 0; + + /** + \brief Gets the spring rest length of the tendon. + + \return The spring rest length of the tendon. + + @see setRestLength() + */ + virtual PxReal getRestLength() const = 0; + + /** + \brief Sets the low and high limit on the length of the tendon. + + \param[in] parameter Struct with the low and high limit. + + The limits, together with the damping and limit stiffness parameters, act on the accumulated length of the tendon. + + @see PxArticulationTendonLimit getLimitParameters() setRestLength() + */ + virtual void setLimitParameters(const PxArticulationTendonLimit& parameter) = 0; + + + /** + \brief Gets the low and high limit on the length of the tendon. + + \return Struct with the low and high limit. + + @see PxArticulationTendonLimit setLimitParameters() + */ + virtual PxArticulationTendonLimit getLimitParameters() const = 0; + + /** + \brief Returns the string name of the dynamic type. + + \return The string name. + */ + virtual const char* getConcreteTypeName() const { return "PxArticulationFixedTendon"; } + + virtual ~PxArticulationFixedTendon() {} + + protected: + PX_INLINE PxArticulationFixedTendon(PxType concreteType, PxBaseFlags baseFlags) : PxArticulationTendon(concreteType, baseFlags) {} + PX_INLINE PxArticulationFixedTendon(PxBaseFlags baseFlags) : PxArticulationTendon(baseFlags) {} + }; + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** @} */ +#endif + diff --git a/Source/ThirdParty/PhysX/PxArticulationTendonData.h b/Source/ThirdParty/PhysX/PxArticulationTendonData.h new file mode 100644 index 000000000..8a4155a8c --- /dev/null +++ b/Source/ThirdParty/PhysX/PxArticulationTendonData.h @@ -0,0 +1,120 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + + +#ifndef PX_ARTICULATION_TENDON_DATA_H +#define PX_ARTICULATION_TENDON_DATA_H + +#include "foundation/PxSimpleTypes.h" +#include "foundation/PxVec3.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +/** +\brief PxGpuSpatialTendonData + +This data structure is to be used by the direct GPU API for spatial tendon data updates. + +@see PxArticulationSpatialTendon PxScene::copyArticulationData PxScene::applyArticulationData +*/ +PX_ALIGN_PREFIX(16) +class PxGpuSpatialTendonData +{ +public: + PxReal stiffness; + PxReal damping; + PxReal limitStiffness; + PxReal offset; +} +PX_ALIGN_SUFFIX(16); + +/** +\brief PxGpuFixedTendonData + +This data structure is to be used by the direct GPU API for fixed tendon data updates. + +@see PxArticulationFixedTendon PxScene::copyArticulationData PxScene::applyArticulationData +*/ +PX_ALIGN_PREFIX(16) +class PxGpuFixedTendonData : public PxGpuSpatialTendonData +{ +public: + PxReal lowLimit; + PxReal highLimit; + PxReal restLength; + PxReal padding; +} +PX_ALIGN_SUFFIX(16); + +/** +\brief PxGpuTendonJointCoefficientData + +This data structure is to be used by the direct GPU API for fixed tendon joint data updates. + +@see PxArticulationTendonJoint PxScene::copyArticulationData PxScene::applyArticulationData +*/ +PX_ALIGN_PREFIX(16) +class PxGpuTendonJointCoefficientData +{ +public: + PxReal coefficient; + PxReal recipCoefficient; + PxU32 axis; + PxU32 pad; +} +PX_ALIGN_SUFFIX(16); + +/** +\brief PxGpuTendonAttachmentData + +This data structure is to be used by the direct GPU API for spatial tendon attachment data updates. + +@see PxArticulationAttachment PxScene::copyArticulationData PxScene::applyArticulationData +*/ +PX_ALIGN_PREFIX(16) +class PxGpuTendonAttachmentData +{ +public: + PxVec3 relativeOffset; + PxReal restLength; + + PxReal coefficient; + PxReal lowLimit; + PxReal highLimit; + PxReal padding; +} +PX_ALIGN_SUFFIX(16); + +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif diff --git a/Source/ThirdParty/PhysX/PxAttachment.h b/Source/ThirdParty/PhysX/PxAttachment.h new file mode 100644 index 000000000..32d0a17c7 --- /dev/null +++ b/Source/ThirdParty/PhysX/PxAttachment.h @@ -0,0 +1,60 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_ATTACHMENT_H +#define PX_ATTACHMENT_H + +#include "PxConeLimitedConstraint.h" +#include "PxFiltering.h" +#include "foundation/PxVec4.h" + +/** \addtogroup physics +@{ +*/ + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +/** +\brief Struct to specify attachment between a particle/vertex and a rigid +*/ +struct PxParticleRigidAttachment : public PxParticleRigidFilterPair +{ + PX_ALIGN(16, PxVec4 mLocalPose0); //!< local pose in body frame - except for statics, these are using world positions. + + PxConeLimitParams mParams; //!< Parameters to specify cone constraints +}; + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/PxBaseMaterial.h b/Source/ThirdParty/PhysX/PxBaseMaterial.h new file mode 100644 index 000000000..7f5f8c788 --- /dev/null +++ b/Source/ThirdParty/PhysX/PxBaseMaterial.h @@ -0,0 +1,64 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_BASE_MATERIAL_H +#define PX_BASE_MATERIAL_H +/** \addtogroup physics +@{ +*/ + +#include "PxPhysXConfig.h" +#include "common/PxBase.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + /** + \brief Base material class. + + @see PxPhysics.createMaterial PxPhysics.createFEMClothMaterial PxPhysics.createFEMSoftBodyMaterial PxPhysics.createFLIPMaterial PxPhysics.createMPMMaterial PxPhysics.createPBDMaterial + */ + class PxBaseMaterial : public PxRefCounted + { + public: + PX_INLINE PxBaseMaterial(PxType concreteType, PxBaseFlags baseFlags) : PxRefCounted(concreteType, baseFlags), userData(NULL) {} + PX_INLINE PxBaseMaterial(PxBaseFlags baseFlags) : PxRefCounted(baseFlags) {} + virtual ~PxBaseMaterial() {} + virtual bool isKindOf(const char* name) const { return !::strcmp("PxBaseMaterial", name) || PxRefCounted::isKindOf(name); } + + void* userData; //!< user can assign this to whatever, usually to create a 1:1 relationship with a user object. + }; + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/PxBatchQuery.h b/Source/ThirdParty/PhysX/PxBatchQuery.h deleted file mode 100644 index 6dc4eaa26..000000000 --- a/Source/ThirdParty/PhysX/PxBatchQuery.h +++ /dev/null @@ -1,224 +0,0 @@ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of NVIDIA CORPORATION nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. -// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. -// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - - -#ifndef PX_PHYSICS_NX_SCENEQUERY -#define PX_PHYSICS_NX_SCENEQUERY -/** \addtogroup scenequery -@{ */ - -#include "PxPhysXConfig.h" -#include "PxShape.h" -#include "PxBatchQueryDesc.h" -#include "PxQueryFiltering.h" - -#if !PX_DOXYGEN -namespace physx -{ -#endif - -class PxBoxGeometry; -class PxSphereGeometry; -struct PxQueryCache; - -/** -\brief Batched queries object. This is used to perform several queries at the same time. - -\deprecated The batched query feature has been deprecated in PhysX version 3.4 - -@see PxScene, PxScene.createBatchQuery -*/ -class PX_DEPRECATED PxBatchQuery -{ - public: - - /** - \brief Executes batched queries. - */ - virtual void execute() = 0; - - /** - \brief Gets the prefilter shader in use for this scene query. - - \return Prefilter shader. - - @see PxBatchQueryDesc.preFilterShade PxBatchQueryPreFilterShader - */ - virtual PxBatchQueryPreFilterShader getPreFilterShader() const = 0; - - /** - \brief Gets the postfilter shader in use for this scene query. - - \return Postfilter shader. - - @see PxBatchQueryDesc.preFilterShade PxBatchQueryPostFilterShader - */ - virtual PxBatchQueryPostFilterShader getPostFilterShader() const = 0; - - - /** - \brief Gets the shared global filter data in use for this scene query. - - \return Shared filter data for filter shader. - - @see getFilterShaderDataSize() PxBatchQueryDesc.filterShaderData PxBatchQueryPreFilterShader, PxBatchQueryPostFilterShader - */ - virtual const void* getFilterShaderData() const = 0; - - /** - \brief Gets the size of the shared global filter data (#PxSceneDesc.filterShaderData) - - \return Size of shared filter data [bytes]. - - @see getFilterShaderData() PxBatchQueryDesc.filterShaderDataSize PxBatchQueryPreFilterShader, PxBatchQueryPostFilterShader - */ - virtual PxU32 getFilterShaderDataSize() const = 0; - - /** - \brief Sets new user memory pointers. - - It is not possible to change the memory during query execute. - - @see PxBatchQueryDesc - */ - virtual void setUserMemory(const PxBatchQueryMemory&) = 0; - - /** - \brief Gets the user memory pointers. - - @see PxBatchQueryDesc - */ - virtual const PxBatchQueryMemory& getUserMemory() = 0; - - /** - \brief Releases PxBatchQuery from PxScene - - @see PxScene, PxScene.createBatchQuery - */ - virtual void release() = 0; - - /** - \brief Performs a raycast against objects in the scene, returns results in PxBatchQueryMemory::userRaycastResultBuffer - specified at PxBatchQuery creation time or via PxBatchQuery::setUserMemory call. - - \note Touching hits are not ordered. - \note Shooting a ray from within an object leads to different results depending on the shape type. Please check the details in article SceneQuery. User can ignore such objects by using one of the provided filter mechanisms. - - \param[in] origin Origin of the ray. - \param[in] unitDir Normalized direction of the ray. - \param[in] distance Length of the ray. Needs to be larger than 0. - \param[in] maxTouchHits Maximum number of hits to record in the touch buffer for this query. Default=0 reports a single blocking hit. If maxTouchHits is set to 0 all hits are treated as blocking by default. - \param[in] hitFlags Specifies which properties per hit should be computed and returned in hit array and blocking hit. - \param[in] filterData Filtering data passed to the filter shader. See #PxQueryFilterData #PxBatchQueryPreFilterShader, #PxBatchQueryPostFilterShader - \param[in] userData User can pass any value in this argument, usually to identify this particular query - \param[in] cache Cached hit shape (optional). Query is tested against cached shape first. If no hit is found the ray gets queried against the scene. - Note: Filtering is not executed for a cached shape if supplied; instead, if a hit is found, it is assumed to be a blocking hit. - Note: Using past touching hits as cache will produce incorrect behavior since the cached hit will always be treated as blocking. - - \note This query call writes to a list associated with the query object and is NOT thread safe (for performance reasons there is no lock - and overlapping writes from different threads may result in undefined behavior). - - @see PxQueryFilterData PxBatchQueryPreFilterShader PxBatchQueryPostFilterShader PxRaycastHit PxScene::raycast - */ - virtual void raycast( - const PxVec3& origin, const PxVec3& unitDir, PxReal distance = PX_MAX_F32, PxU16 maxTouchHits = 0, - PxHitFlags hitFlags = PxHitFlag::eDEFAULT, - const PxQueryFilterData& filterData = PxQueryFilterData(), - void* userData = NULL, const PxQueryCache* cache = NULL) = 0; - - - /** - \brief Performs an overlap test of a given geometry against objects in the scene, returns results in PxBatchQueryMemory::userOverlapResultBuffer - specified at PxBatchQuery creation time or via PxBatchQuery::setUserMemory call. - - \note Filtering: returning eBLOCK from user filter for overlap queries will cause a warning (see #PxQueryHitType). - - \param[in] geometry Geometry of object to check for overlap (supported types are: box, sphere, capsule, convex). - \param[in] pose Pose of the object. - \param[in] maxTouchHits Maximum number of hits to record in the touch buffer for this query. Default=0 reports a single blocking hit. If maxTouchHits is set to 0 all hits are treated as blocking by default. - \param[in] filterData Filtering data and simple logic. See #PxQueryFilterData #PxBatchQueryPreFilterShader, #PxBatchQueryPostFilterShader - \param[in] userData User can pass any value in this argument, usually to identify this particular query - \param[in] cache Cached hit shape (optional). Query is tested against cached shape first. If no hit is found the ray gets queried against the scene. - Note: Filtering is not executed for a cached shape if supplied; instead, if a hit is found, it is assumed to be a blocking hit. - Note: Using past touching hits as cache will produce incorrect behavior since the cached hit will always be treated as blocking. - - \note eBLOCK should not be returned from user filters for overlap(). Doing so will result in undefined behavior, and a warning will be issued. - \note If the PxQueryFlag::eNO_BLOCK flag is set, the eBLOCK will instead be automatically converted to an eTOUCH and the warning suppressed. - \note This query call writes to a list associated with the query object and is NOT thread safe (for performance reasons there is no lock - and overlapping writes from different threads may result in undefined behavior). - - @see PxQueryFilterData PxBatchQueryPreFilterShader PxBatchQueryPostFilterShader - */ - virtual void overlap( - const PxGeometry& geometry, const PxTransform& pose, PxU16 maxTouchHits = 0, - const PxQueryFilterData& filterData = PxQueryFilterData(), void* userData=NULL, const PxQueryCache* cache = NULL) = 0; - - /** - \brief Performs a sweep test against objects in the scene, returns results in PxBatchQueryMemory::userSweepResultBuffer - specified at PxBatchQuery creation time or via PxBatchQuery::setUserMemory call. - - \note Touching hits are not ordered. - \note If a shape from the scene is already overlapping with the query shape in its starting position, - the hit is returned unless eASSUME_NO_INITIAL_OVERLAP was specified. - - \param[in] geometry Geometry of object to sweep (supported types are: box, sphere, capsule, convex). - \param[in] pose Pose of the sweep object. - \param[in] unitDir Normalized direction of the sweep. - \param[in] distance Sweep distance. Needs to be larger than 0. Will be clamped to PX_MAX_SWEEP_DISTANCE. - \param[in] maxTouchHits Maximum number of hits to record in the touch buffer for this query. Default=0 reports a single blocking hit. If maxTouchHits is set to 0 all hits are treated as blocking by default. - \param[in] hitFlags Specifies which properties per hit should be computed and returned in hit array and blocking hit. - \param[in] filterData Filtering data and simple logic. See #PxQueryFilterData #PxBatchQueryPreFilterShader, #PxBatchQueryPostFilterShader - \param[in] userData User can pass any value in this argument, usually to identify this particular query - \param[in] cache Cached hit shape (optional). Query is tested against cached shape first. If no hit is found the ray gets queried against the scene. - Note: Filtering is not executed for a cached shape if supplied; instead, if a hit is found, it is assumed to be a blocking hit. - Note: Using past touching hits as cache will produce incorrect behavior since the cached hit will always be treated as blocking. - \param[in] inflation This parameter creates a skin around the swept geometry which increases its extents for sweeping. The sweep will register a hit as soon as the skin touches a shape, and will return the corresponding distance and normal. - Note: ePRECISE_SWEEP doesn't support inflation. Therefore the sweep will be performed with zero inflation. - - \note This query call writes to a list associated with the query object and is NOT thread safe (for performance reasons there is no lock - and overlapping writes from different threads may result in undefined behavior). - - @see PxHitFlags PxQueryFilterData PxBatchQueryPreFilterShader PxBatchQueryPostFilterShader PxSweepHit - */ - virtual void sweep( - const PxGeometry& geometry, const PxTransform& pose, const PxVec3& unitDir, const PxReal distance, - PxU16 maxTouchHits = 0, PxHitFlags hitFlags = PxHitFlag::eDEFAULT, - const PxQueryFilterData& filterData = PxQueryFilterData(), void* userData=NULL, const PxQueryCache* cache = NULL, - const PxReal inflation = 0.f) = 0; - -protected: - virtual ~PxBatchQuery() {} -}; - -#if !PX_DOXYGEN -} // namespace physx -#endif - -/** @} */ -#endif diff --git a/Source/ThirdParty/PhysX/PxBatchQueryDesc.h b/Source/ThirdParty/PhysX/PxBatchQueryDesc.h deleted file mode 100644 index 338db6fbc..000000000 --- a/Source/ThirdParty/PhysX/PxBatchQueryDesc.h +++ /dev/null @@ -1,303 +0,0 @@ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of NVIDIA CORPORATION nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. -// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. -// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - - -#ifndef PX_PHYSICS_NX_SCENEQUERYDESC -#define PX_PHYSICS_NX_SCENEQUERYDESC -/** \addtogroup physics -@{ */ - -#include "PxPhysXConfig.h" -#include "PxClient.h" -#include "PxFiltering.h" -#include "PxQueryFiltering.h" -#include "foundation/PxAssert.h" - -#if !PX_DOXYGEN -namespace physx -{ -#endif - -struct PxSweepHit; -struct PxRaycastHit; - -/** -\brief Batched query status. - -\deprecated The batched query feature has been deprecated in PhysX version 3.4 -*/ -struct PX_DEPRECATED PxBatchQueryStatus -{ - enum Enum - { - /** - \brief This is the initial state before a query starts. - */ - ePENDING = 0, - - /** - \brief The query is finished; results have been written into the result and hit buffers. - */ - eSUCCESS, - - /** - \brief The query results were incomplete due to touch hit buffer overflow. Blocking hit is still correct. - */ - eOVERFLOW - }; -}; - -/** -\brief Generic struct for receiving results of single query in a batch. Gets templated on hit type PxRaycastHit, PxSweepHit or PxOverlapHit. - -\deprecated The batched query feature has been deprecated in PhysX version 3.4 -*/ -template -struct PX_DEPRECATED PxBatchQueryResult -{ - HitType block; //!< Holds the closest blocking hit for a single query in a batch. Only valid if hasBlock is true. - HitType* touches; //!< This pointer will either be set to NULL for 0 nbTouches or will point - //!< into the user provided batch query results buffer specified in PxBatchQueryDesc. - PxU32 nbTouches; //!< Number of touching hits returned by this query, works in tandem with touches pointer. - void* userData; //!< Copy of the userData pointer specified in the corresponding query. - PxU8 queryStatus; //!< Takes on values from PxBatchQueryStatus::Enum. - bool hasBlock; //!< True if there was a blocking hit. - PxU16 pad; //!< pads the struct to 16 bytes. - - /** \brief Computes the number of any hits in this result, blocking or touching. */ - PX_INLINE PxU32 getNbAnyHits() const { return nbTouches + (hasBlock ? 1 : 0); } - - /** \brief Convenience iterator used to access any hits in this result, blocking or touching. */ - PX_INLINE const HitType& getAnyHit(const PxU32 index) const { PX_ASSERT(index < nbTouches + (hasBlock ? 1 : 0)); - return index < nbTouches ? touches[index] : block; } -}; - -/** \brief Convenience typedef for the result of a batched raycast query. */ -typedef PX_DEPRECATED PxBatchQueryResult PxRaycastQueryResult; - -/** \brief Convenience typedef for the result of a batched sweep query. */ -typedef PX_DEPRECATED PxBatchQueryResult PxSweepQueryResult; - -/** \brief Convenience typedef for the result of a batched overlap query. */ -typedef PX_DEPRECATED PxBatchQueryResult PxOverlapQueryResult; - -/** -\brief Struct for #PxBatchQuery memory pointers. - -\deprecated The batched query feature has been deprecated in PhysX version 3.4 - -@see PxBatchQuery PxBatchQueryDesc -*/ -struct PX_DEPRECATED PxBatchQueryMemory - { - /** - \brief The pointer to the user-allocated buffer for results of raycast queries in corresponding order of issue - - \note The size should be large enough to fit the number of expected raycast queries. - - @see PxRaycastQueryResult - */ - PxRaycastQueryResult* userRaycastResultBuffer; - - /** - \brief The pointer to the user-allocated buffer for raycast touch hits. - \note The size of this buffer should be large enough to store PxRaycastHit. - If the buffer is too small to store hits, the related PxRaycastQueryResult.queryStatus will be set to eOVERFLOW - - */ - PxRaycastHit* userRaycastTouchBuffer; - - /** - \brief The pointer to the user-allocated buffer for results of sweep queries in corresponding order of issue - - \note The size should be large enough to fit the number of expected sweep queries. - - @see PxRaycastQueryResult - */ - PxSweepQueryResult* userSweepResultBuffer; - - /** - \brief The pointer to the user-allocated buffer for sweep hits. - \note The size of this buffer should be large enough to store PxSweepHit. - If the buffer is too small to store hits, the related PxSweepQueryResult.queryStatus will be set to eOVERFLOW - - */ - PxSweepHit* userSweepTouchBuffer; - - /** - \brief The pointer to the user-allocated buffer for results of overlap queries in corresponding order of issue - - \note The size should be large enough to fit the number of expected overlap queries. - - @see PxRaycastQueryResult - */ - PxOverlapQueryResult* userOverlapResultBuffer; - - /** - \brief The pointer to the user-allocated buffer for overlap hits. - \note The size of this buffer should be large enough to store the hits returned. - If the buffer is too small to store hits, the related PxOverlapQueryResult.queryStatus will be set to eABORTED - - */ - PxOverlapHit* userOverlapTouchBuffer; - - /** \brief Capacity of the user-allocated userRaycastTouchBuffer in elements */ - PxU32 raycastTouchBufferSize; - - /** \brief Capacity of the user-allocated userSweepTouchBuffer in elements */ - PxU32 sweepTouchBufferSize; - - /** \brief Capacity of the user-allocated userOverlapTouchBuffer in elements */ - PxU32 overlapTouchBufferSize; - - /** \return Capacity of the user-allocated userRaycastResultBuffer in elements (max number of raycast() calls before execute() call) */ - PX_FORCE_INLINE PxU32 getMaxRaycastsPerExecute() const { return raycastResultBufferSize; } - - /** \return Capacity of the user-allocated userSweepResultBuffer in elements (max number of sweep() calls before execute() call) */ - PX_FORCE_INLINE PxU32 getMaxSweepsPerExecute() const { return sweepResultBufferSize; } - - /** \return Capacity of the user-allocated userOverlapResultBuffer in elements (max number of overlap() calls before execute() call) */ - PX_FORCE_INLINE PxU32 getMaxOverlapsPerExecute() const { return overlapResultBufferSize; } - - PxBatchQueryMemory(PxU32 raycastResultBufferSize_, PxU32 sweepResultBufferSize_, PxU32 overlapResultBufferSize_) : - userRaycastResultBuffer (NULL), - userRaycastTouchBuffer (NULL), - userSweepResultBuffer (NULL), - userSweepTouchBuffer (NULL), - userOverlapResultBuffer (NULL), - userOverlapTouchBuffer (NULL), - raycastTouchBufferSize (0), - sweepTouchBufferSize (0), - overlapTouchBufferSize (0), - raycastResultBufferSize (raycastResultBufferSize_), - sweepResultBufferSize (sweepResultBufferSize_), - overlapResultBufferSize (overlapResultBufferSize_) - { - } - -protected: - PxU32 raycastResultBufferSize; - PxU32 sweepResultBufferSize; - PxU32 overlapResultBufferSize; -}; - -/** -\brief Descriptor class for #PxBatchQuery. - -\deprecated The batched query feature has been deprecated in PhysX version 3.4 - -@see PxBatchQuery PxSceneQueryExecuteMode -*/ -class PX_DEPRECATED PxBatchQueryDesc -{ -public: - - /** - \brief Shared global filter data which will get passed into the filter shader. - - \note The provided data will get copied to internal buffers and this copy will be used for filtering calls. - - Default: NULL - - @see PxSimulationFilterShader - */ - void* filterShaderData; - - /** - \brief Size (in bytes) of the shared global filter data #filterShaderData. - - Default: 0 - - @see PxSimulationFilterShader filterShaderData - */ - PxU32 filterShaderDataSize; - - /** - \brief The custom preFilter shader to use for filtering. - - @see PxBatchQueryPreFilterShader PxDefaultPreFilterShader - */ - PxBatchQueryPreFilterShader preFilterShader; - - /** - \brief The custom postFilter shader to use for filtering. - - @see PxBatchQueryPostFilterShader PxDefaultPostFilterShader - */ - PxBatchQueryPostFilterShader postFilterShader; - - /** - \brief User memory buffers for the query. - - @see PxBatchQueryMemory - */ - PxBatchQueryMemory queryMemory; - - /** - \brief Construct a batch query with specified maximum number of queries per batch. - - If the number of raycasts/sweeps/overlaps per execute exceeds the limit, the query will be discarded with a warning. - - \param maxRaycastsPerExecute Maximum number of raycast() calls allowed before execute() call. - This has to match the amount of memory allocated for PxBatchQueryMemory::userRaycastResultBuffer. - \param maxSweepsPerExecute Maximum number of sweep() calls allowed before execute() call. - This has to match the amount of memory allocated for PxBatchQueryMemory::userSweepResultBuffer. - \param maxOverlapsPerExecute Maximum number of overlap() calls allowed before execute() call. - This has to match the amount of memory allocated for PxBatchQueryMemory::userOverlapResultBuffer. - */ - PX_INLINE PxBatchQueryDesc(PxU32 maxRaycastsPerExecute, PxU32 maxSweepsPerExecute, PxU32 maxOverlapsPerExecute); - PX_INLINE bool isValid() const; -}; - - -PX_INLINE PxBatchQueryDesc::PxBatchQueryDesc(PxU32 maxRaycastsPerExecute, PxU32 maxSweepsPerExecute, PxU32 maxOverlapsPerExecute) : - filterShaderData (NULL), - filterShaderDataSize (0), - preFilterShader (NULL), - postFilterShader (NULL), - queryMemory (maxRaycastsPerExecute, maxSweepsPerExecute, maxOverlapsPerExecute) -{ -} - - -PX_INLINE bool PxBatchQueryDesc::isValid() const -{ - if ( ((filterShaderDataSize == 0) && (filterShaderData != NULL)) || - ((filterShaderDataSize > 0) && (filterShaderData == NULL)) ) - return false; - - return true; -} - -#if !PX_DOXYGEN -} // namespace physx -#endif - -/** @} */ -#endif diff --git a/Source/ThirdParty/PhysX/PxBroadPhase.h b/Source/ThirdParty/PhysX/PxBroadPhase.h index 91fd5deb4..cb8fab6b9 100644 --- a/Source/ThirdParty/PhysX/PxBroadPhase.h +++ b/Source/ThirdParty/PhysX/PxBroadPhase.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_BROAD_PHASE_H -#define PX_PHYSICS_BROAD_PHASE_H +#ifndef PX_BROAD_PHASE_H +#define PX_BROAD_PHASE_H /** \addtogroup physics @{ */ @@ -42,7 +40,8 @@ namespace physx { #endif - class PxActor; + class PxBaseTask; + class PxCudaContextManager; /** \brief Broad phase algorithm used in the simulation @@ -62,62 +61,31 @@ namespace physx of eMBP when a lot of objects are moving. While eSAP can remain faster when most objects are sleeping and eMBP can remain faster when it uses a large number of properly-defined regions, eABP often gives the best performance on average and the best memory usage. + + ePABP is a parallel implementation of ABP. It can often be the fastest (CPU) broadphase, but it + can use more memory than ABP. + + eGPU is a GPU implementation of the incremental sweep and prune approach. Additionally, it uses a ABP-style + initial pair generation approach to avoid large spikes when inserting shapes. It not only has the advantage + of traditional SAP approch which is good for when many objects are sleeping, but due to being fully parallel, + it also is great when lots of shapes are moving or for runtime pair insertion and removal. It can become a + performance bottleneck if there are a very large number of shapes roughly projecting to the same values + on a given axis. If the scene has a very large number of shapes in an actor, e.g. a humanoid, it is recommended + to use an aggregate to represent multi-shape or multi-body actors to minimize stress placed on the broad phase. */ struct PxBroadPhaseType { enum Enum { - eSAP, //!< 3-axes sweep-and-prune - eMBP, //!< Multi box pruning - eABP, //!< Automatic box pruning - eGPU, - + eSAP, //!< 3-axes sweep-and-prune + eMBP, //!< Multi box pruning + eABP, //!< Automatic box pruning + ePABP, //!< Parallel automatic box pruning + eGPU, //!< GPU broad phase eLAST }; }; - /** - \brief Broad-phase callback to receive broad-phase related events. - - Each broadphase callback object is associated with a PxClientID. It is possible to register different - callbacks for different clients. The callback functions are called this way: - - for shapes/actors, the callback assigned to the actors' clients are used - - for aggregates, the callbacks assigned to clients from aggregated actors are used - - \note SDK state should not be modified from within the callbacks. In particular objects should not - be created or destroyed. If state modification is needed then the changes should be stored to a buffer - and performed after the simulation step. - - Threading: It is not necessary to make this class thread safe as it will only be called in the context of the - user thread. - - @see PxSceneDesc PxScene.setBroadPhaseCallback() PxScene.getBroadPhaseCallback() - */ - class PxBroadPhaseCallback - { - public: - virtual ~PxBroadPhaseCallback() {} - - /** - \brief Out-of-bounds notification. - - This function is called when an object leaves the broad-phase. - - \param[in] shape Shape that left the broad-phase bounds - \param[in] actor Owner actor - */ - virtual void onObjectOutOfBounds(PxShape& shape, PxActor& actor) = 0; - - /** - \brief Out-of-bounds notification. - - This function is called when an aggregate leaves the broad-phase. - - \param[in] aggregate Aggregate that left the broad-phase bounds - */ - virtual void onObjectOutOfBounds(PxAggregate& aggregate) = 0; - }; - /** \brief "Region of interest" for the broad-phase. @@ -129,7 +97,7 @@ namespace physx thus collisions will be disabled for them. A PxBroadPhaseCallback out-of-bounds notification will be sent for each one of those objects. - The total number of regions is limited by PxBroadPhaseCaps::maxNbRegions. + The total number of regions is limited by PxBroadPhaseCaps::mMaxNbRegions. The number of regions has a direct impact on performance and memory usage, so it is recommended to experiment with various settings to find the best combination for your game. A good default setup is to start with global bounds @@ -140,8 +108,8 @@ namespace physx */ struct PxBroadPhaseRegion { - PxBounds3 bounds; //!< Region's bounds - void* userData; //!< Region's user-provided data + PxBounds3 mBounds; //!< Region's bounds + void* mUserData; //!< Region's user-provided data }; /** @@ -149,11 +117,11 @@ namespace physx */ struct PxBroadPhaseRegionInfo { - PxBroadPhaseRegion region; //!< User-provided region data - PxU32 nbStaticObjects; //!< Number of static objects in the region - PxU32 nbDynamicObjects; //!< Number of dynamic objects in the region - bool active; //!< True if region is currently used, i.e. it has not been removed - bool overlap; //!< True if region overlaps other regions (regions that are just touching are not considering overlapping) + PxBroadPhaseRegion mRegion; //!< User-provided region data + PxU32 mNbStaticObjects; //!< Number of static objects in the region + PxU32 mNbDynamicObjects; //!< Number of dynamic objects in the region + bool mActive; //!< True if region is currently used, i.e. it has not been removed + bool mOverlap; //!< True if region overlaps other regions (regions that are just touching are not considering overlapping) }; /** @@ -161,11 +129,574 @@ namespace physx */ struct PxBroadPhaseCaps { - PxU32 maxNbRegions; //!< Max number of regions supported by the broad-phase - PxU32 maxNbObjects; //!< Max number of objects supported by the broad-phase - bool needsPredefinedBounds; //!< If true, broad-phase needs 'regions' to work + PxU32 mMaxNbRegions; //!< Max number of regions supported by the broad-phase (0 = explicit regions not needed) }; + /** + \brief Broadphase descriptor. + + This structure is used to create a standalone broadphase. It captures all the parameters needed to + initialize a broadphase. + + For the GPU broadphase (PxBroadPhaseType::eGPU) it is necessary to provide a CUDA context manager. + + The kinematic filtering flags are currently not supported by the GPU broadphase. They are used to + dismiss pairs that involve kinematic objects directly within the broadphase. + + \see PxCreateBroadPhase + */ + class PxBroadPhaseDesc + { + public: + PxBroadPhaseDesc(PxBroadPhaseType::Enum type = PxBroadPhaseType::eLAST) : + mType (type), + mContextID (0), + mContextManager (NULL), + mFoundLostPairsCapacity (256 * 1024), + mDiscardStaticVsKinematic (false), + mDiscardKinematicVsKinematic(false) + {} + + PxBroadPhaseType::Enum mType; //!< Desired broadphase implementation + PxU64 mContextID; //!< Context ID for profiler. See PxProfilerCallback. + + PxCudaContextManager* mContextManager; //!< (GPU) CUDA context manager, must be provided for PxBroadPhaseType::eGPU. + PxU32 mFoundLostPairsCapacity; //!< (GPU) Capacity of found and lost buffers allocated in GPU global memory. This is used for the found/lost pair reports in the BP. + + bool mDiscardStaticVsKinematic; //!< Static-vs-kinematic filtering flag. Not supported by PxBroadPhaseType::eGPU. + bool mDiscardKinematicVsKinematic; //!< kinematic-vs-kinematic filtering flag. Not supported by PxBroadPhaseType::eGPU. + + PX_INLINE bool isValid() const + { + if(PxU32(mType)>=PxBroadPhaseType::eLAST) + return false; + + if(mType==PxBroadPhaseType::eGPU && !mContextManager) + return false; + + return true; + } + }; + + typedef PxU32 PxBpIndex; //!< Broadphase index. Indexes bounds, groups and distance arrays. + typedef PxU32 PxBpFilterGroup; //!< Broadphase filter group. + #define PX_INVALID_BP_FILTER_GROUP 0xffffffff //!< Invalid broadphase filter group + + /** + \brief Retrieves the filter group for static objects. + + Mark static objects with this group when adding them to the broadphase. + Overlaps between static objects will not be detected. All static objects + should have the same group. + + \return Filter group for static objects. + \see PxBpFilterGroup + */ + PX_C_EXPORT PX_PHYSX_CORE_API PxBpFilterGroup PxGetBroadPhaseStaticFilterGroup(); + + /** + \brief Retrieves a filter group for dynamic objects. + + Mark dynamic objects with this group when adding them to the broadphase. + Each dynamic object must have an ID, and overlaps between dynamic objects that have + the same ID will not be detected. This is useful to dismiss overlaps between shapes + of the same (compound) actor directly within the broadphase. + + \param id [in] ID/Index of dynamic object + \return Filter group for the object. + \see PxBpFilterGroup + */ + PX_C_EXPORT PX_PHYSX_CORE_API PxBpFilterGroup PxGetBroadPhaseDynamicFilterGroup(PxU32 id); + + /** + \brief Retrieves a filter group for kinematic objects. + + Mark kinematic objects with this group when adding them to the broadphase. + Each kinematic object must have an ID, and overlaps between kinematic objects that have + the same ID will not be detected. + + \param id [in] ID/Index of kinematic object + \return Filter group for the object. + \see PxBpFilterGroup + */ + PX_C_EXPORT PX_PHYSX_CORE_API PxBpFilterGroup PxGetBroadPhaseKinematicFilterGroup(PxU32 id); + + /** + \brief Broadphase data update structure. + + This structure is used to update the low-level broadphase (PxBroadPhase). All added, updated and removed objects + must be batched and submitted at once to the broadphase. + + Broadphase objects have bounds, a filtering group, and a distance. With the low-level broadphase the data must be + externally managed by the clients of the broadphase API, and passed to the update function. + + The provided bounds are non-inflated "base" bounds that can be further extended by the broadphase using the passed + distance value. These can be contact offsets, or dynamically updated distance values for e.g. speculative contacts. + Either way they are optional and can be left to zero. The broadphase implementations efficiently combine the base + bounds with the per-object distance values at runtime. + + The per-object filtering groups are used to discard some pairs directly within the broadphase, which is more + efficient than reporting the pairs and culling them in a second pass. + + \see PxBpFilterGroup PxBpIndex PxBounds3 PxBroadPhase::update + */ + class PxBroadPhaseUpdateData + { + public: + + PxBroadPhaseUpdateData( const PxBpIndex* created, PxU32 nbCreated, + const PxBpIndex* updated, PxU32 nbUpdated, + const PxBpIndex* removed, PxU32 nbRemoved, + const PxBounds3* bounds, const PxBpFilterGroup* groups, const float* distances, + PxU32 capacity) : + mCreated (created), mNbCreated (nbCreated), + mUpdated (updated), mNbUpdated (nbUpdated), + mRemoved (removed), mNbRemoved (nbRemoved), + mBounds (bounds), mGroups (groups), mDistances (distances), + mCapacity (capacity) + { + } + + PxBroadPhaseUpdateData(const PxBroadPhaseUpdateData& other) : + mCreated (other.mCreated), mNbCreated (other.mNbCreated), + mUpdated (other.mUpdated), mNbUpdated (other.mNbUpdated), + mRemoved (other.mRemoved), mNbRemoved (other.mNbRemoved), + mBounds (other.mBounds), mGroups (other.mGroups), mDistances (other.mDistances), + mCapacity (other.mCapacity) + { + } + + PxBroadPhaseUpdateData& operator=(const PxBroadPhaseUpdateData& other); + + const PxBpIndex* mCreated; //!< Indices of created objects. + const PxU32 mNbCreated; //!< Number of created objects. + + const PxBpIndex* mUpdated; //!< Indices of updated objects. + const PxU32 mNbUpdated; //!< Number of updated objects. + + const PxBpIndex* mRemoved; //!< Indices of removed objects. + const PxU32 mNbRemoved; //!< Number of removed objects. + + const PxBounds3* mBounds; //!< (Persistent) array of bounds. + const PxBpFilterGroup* mGroups; //!< (Persistent) array of groups. + const float* mDistances; //!< (Persistent) array of distances. + const PxU32 mCapacity; //!< Capacity of bounds / groups / distance buffers. + }; + + /** + \brief Broadphase pair. + + A pair of indices returned by the broadphase for found or lost pairs. + + \see PxBroadPhaseResults + */ + struct PxBroadPhasePair + { + PxBpIndex mID0; //!< Index of first object + PxBpIndex mID1; //!< Index of second object + }; + + /** + \brief Broadphase results. + + Set of found and lost pairs after a broadphase update. + + \see PxBroadPhasePair PxBroadPhase::fetchResults PxAABBManager::fetchResults + */ + struct PxBroadPhaseResults + { + PxBroadPhaseResults() : mNbCreatedPairs(0), mCreatedPairs(NULL), mNbDeletedPairs(0), mDeletedPairs(NULL) {} + + PxU32 mNbCreatedPairs; //!< Number of new/found/created pairs. + const PxBroadPhasePair* mCreatedPairs; //!< Array of new/found/created pairs. + + PxU32 mNbDeletedPairs; //!< Number of lost/deleted pairs. + const PxBroadPhasePair* mDeletedPairs; //!< Array of lost/deleted pairs. + }; + + /** + \brief Broadphase regions. + + An API to manage broadphase regions. Only needed for the MBP broadphase (PxBroadPhaseType::eMBP). + + \see PxBroadPhase::getRegions() + */ + class PxBroadPhaseRegions + { + protected: + PxBroadPhaseRegions() {} + virtual ~PxBroadPhaseRegions() {} + public: + + /** + \brief Returns number of regions currently registered in the broad-phase. + + \return Number of regions + */ + virtual PxU32 getNbRegions() const = 0; + + /** + \brief Gets broad-phase regions. + + \param userBuffer [out] Returned broad-phase regions + \param bufferSize [in] Size of provided userBuffer. + \param startIndex [in] Index of first desired region, in [0 ; getNbRegions()[ + \return Number of written out regions. + \see PxBroadPhaseRegionInfo + */ + virtual PxU32 getRegions(PxBroadPhaseRegionInfo* userBuffer, PxU32 bufferSize, PxU32 startIndex=0) const = 0; + + /** + \brief Adds a new broad-phase region. + + The total number of regions is limited to PxBroadPhaseCaps::mMaxNbRegions. If that number is exceeded, the call is ignored. + + The newly added region will be automatically populated with already existing objects that touch it, if the + 'populateRegion' parameter is set to true. Otherwise the newly added region will be empty, and it will only be + populated with objects when those objects are added to the simulation, or updated if they already exist. + + Using 'populateRegion=true' has a cost, so it is best to avoid it if possible. In particular it is more efficient + to create the empty regions first (with populateRegion=false) and then add the objects afterwards (rather than + the opposite). + + Objects automatically move from one region to another during their lifetime. The system keeps tracks of what + regions a given object is in. It is legal for an object to be in an arbitrary number of regions. However if an + object leaves all regions, or is created outside of all regions, several things happen: + - collisions get disabled for this object + - the object appears in the getOutOfBoundsObjects() array + + If an out-of-bounds object, whose collisions are disabled, re-enters a valid broadphase region, then collisions + are re-enabled for that object. + + \param region [in] User-provided region data + \param populateRegion [in] True to automatically populate the newly added region with existing objects touching it + \param bounds [in] User-managed array of bounds + \param distances [in] User-managed array of distances + + \return Handle for newly created region, or 0xffffffff in case of failure. + \see PxBroadPhaseRegion getOutOfBoundsObjects() + */ + virtual PxU32 addRegion(const PxBroadPhaseRegion& region, bool populateRegion, const PxBounds3* bounds, const float* distances) = 0; + + /** + \brief Removes a broad-phase region. + + If the region still contains objects, and if those objects do not overlap any region any more, they are not + automatically removed from the simulation. Instead, the PxBroadPhaseCallback::onObjectOutOfBounds notification + is used for each object. Users are responsible for removing the objects from the simulation if this is the + desired behavior. + + If the handle is invalid, or if a valid handle is removed twice, an error message is sent to the error stream. + + \param handle [in] Region's handle, as returned by addRegion + \return True if success + */ + virtual bool removeRegion(PxU32 handle) = 0; + + /* + \brief Return the number of objects that are not in any region. + */ + virtual PxU32 getNbOutOfBoundsObjects() const = 0; + + /* + \brief Return an array of objects that are not in any region. + */ + virtual const PxU32* getOutOfBoundsObjects() const = 0; + }; + + /** + \brief Low-level broadphase API. + + This low-level API only supports batched updates and leaves most of the data management to its clients. + + This is useful if you want to use the broadphase with your own memory buffers. Note however that the GPU broadphase + works best with buffers allocated in CUDA memory. The getAllocator() function returns an allocator that is compatible + with the selected broadphase. It is recommended to allocate and deallocate the broadphase data (bounds, groups, distances) + using this allocator. + + Important note: it must be safe to load 4 bytes past the end of the provided bounds array. + + The high-level broadphase API (PxAABBManager) is an easier-to-use interface that automatically deals with these requirements. + + \see PxCreateBroadPhase + */ + class PxBroadPhase + { + protected: + PxBroadPhase() {} + virtual ~PxBroadPhase() {} + public: + + /* + \brief Releases the broadphase. + */ + virtual void release() = 0; + + /** + \brief Gets the broadphase type. + + \return Broadphase type. + \see PxBroadPhaseType::Enum + */ + virtual PxBroadPhaseType::Enum getType() const = 0; + + /** + \brief Gets broad-phase caps. + + \param caps [out] Broad-phase caps + \see PxBroadPhaseCaps + */ + virtual void getCaps(PxBroadPhaseCaps& caps) const = 0; + + /** + \brief Retrieves the regions API if applicable. + + For broadphases that do not use explicit user-defined regions, this call returns NULL. + + \return Region API, or NULL. + \see PxBroadPhaseRegions + */ + virtual PxBroadPhaseRegions* getRegions() = 0; + + /** + \brief Retrieves the broadphase allocator. + + User-provided buffers should ideally be allocated with this allocator, for best performance. + This is especially true for the GPU broadphases, whose buffers need to be allocated in CUDA + host memory. + + \return The broadphase allocator. + \see PxAllocatorCallback + */ + virtual PxAllocatorCallback* getAllocator() = 0; + + /** + \brief Retrieves the profiler's context ID. + + \return The context ID. + \see PxBroadPhaseDesc + */ + virtual PxU64 getContextID() const = 0; + + /** + \brief Sets a scratch buffer + + Some broadphases might take advantage of a scratch buffer to limit runtime allocations. + + All broadphases still work without providing a scratch buffer, this is an optional function + that can potentially reduce runtime allocations. + + \param scratchBlock [in] The scratch buffer + \param size [in] Size of the scratch buffer in bytes + */ + virtual void setScratchBlock(void* scratchBlock, PxU32 size) = 0; + + /** + \brief Updates the broadphase and computes the lists of created/deleted pairs. + + The provided update data describes changes to objects since the last broadphase update. + + To benefit from potentially multithreaded implementations, it is necessary to provide a continuation + task to the function. It is legal to pass NULL there, but the underlying (CPU) implementations will + then run single-threaded. + + \param updateData [in] The update data + \param continuation [in] Continuation task to enable multi-threaded implementations, or NULL. + \see PxBroadPhaseUpdateData PxBaseTask + */ + virtual void update(const PxBroadPhaseUpdateData& updateData, PxBaseTask* continuation=NULL) = 0; + + /** + \brief Retrieves the broadphase results after an update. + + This should be called once after each update call to retrieve the results of the broadphase. The + results are incremental, i.e. the system only returns new and lost pairs, not all current pairs. + + \param results [out] The broadphase results + \see PxBroadPhaseResults + */ + virtual void fetchResults(PxBroadPhaseResults& results) = 0; + + /** + \brief Helper for single-threaded updates. + + This short helper function performs a single-theaded update and reports the results in a single call. + + \param results [out] The broadphase results + \param updateData [in] The update data + \see PxBroadPhaseUpdateData PxBroadPhaseResults + */ + PX_FORCE_INLINE void update(PxBroadPhaseResults& results, const PxBroadPhaseUpdateData& updateData) + { + update(updateData); + fetchResults(results); + } + }; + + /** + \brief Broadphase factory function. + + Use this function to create a new standalone broadphase. + + \param desc [in] Broadphase descriptor + \return Newly created broadphase, or NULL + \see PxBroadPhase PxBroadPhaseDesc + */ + PX_C_EXPORT PX_PHYSX_CORE_API PxBroadPhase* PxCreateBroadPhase(const PxBroadPhaseDesc& desc); + + /** + \brief High-level broadphase API. + + The low-level broadphase API (PxBroadPhase) only supports batched updates and has a few non-trivial + requirements for managing the bounds data. + + The high-level broadphase API (PxAABBManager) is an easier-to-use one-object-at-a-time API that + automatically deals with the quirks of the PxBroadPhase data management. + + \see PxCreateAABBManager + */ + class PxAABBManager + { + protected: + PxAABBManager() {} + virtual ~PxAABBManager() {} + public: + + /* + \brief Releases the AABB manager. + */ + virtual void release() = 0; + + /** + \brief Retrieves the underlying broadphase. + + \return The managed broadphase. + \see PxBroadPhase + */ + virtual PxBroadPhase& getBroadPhase() = 0; + + /** + \brief Retrieves the managed bounds. + + This is needed as input parameters to functions like PxBroadPhaseRegions::addRegion. + + \return The managed object bounds. + \see PxBounds3 + */ + virtual const PxBounds3* getBounds() const = 0; + + /** + \brief Retrieves the managed distances. + + This is needed as input parameters to functions like PxBroadPhaseRegions::addRegion. + + \return The managed object distances. + */ + virtual const float* getDistances() const = 0; + + /** + \brief Retrieves the managed filter groups. + + \return The managed object groups. + */ + virtual const PxBpFilterGroup* getGroups() const = 0; + + /** + \brief Retrieves the managed buffers' capacity. + + Bounds, distances and groups buffers have the same capacity. + + \return The managed buffers' capacity. + */ + virtual PxU32 getCapacity() const = 0; + + /** + \brief Adds an object to the manager. + + Objects' indices are externally managed, i.e. they must be provided by users (as opposed to handles + that could be returned by this manager). The design allows users to identify an object by a single ID, + and use the same ID in multiple sub-systems. + + \param index [in] The object's index + \param bounds [in] The object's bounds + \param group [in] The object's filter group + \param distance [in] The object's distance (optional) + \see PxBpIndex PxBounds3 PxBpFilterGroup + */ + virtual void addObject(PxBpIndex index, const PxBounds3& bounds, PxBpFilterGroup group, float distance=0.0f) = 0; + + /** + \brief Removes an object from the manager. + + \param index [in] The object's index + \see PxBpIndex + */ + virtual void removeObject(PxBpIndex index) = 0; + + /** + \brief Updates an object in the manager. + + This call can update an object's bounds, distance, or both. + It is not possible to update an object's filter group. + + \param index [in] The object's index + \param bounds [in] The object's updated bounds, or NULL + \param distance [in] The object's updated distance, or NULL + \see PxBpIndex PxBounds3 + */ + virtual void updateObject(PxBpIndex index, const PxBounds3* bounds=NULL, const float* distance=NULL) = 0; + + /** + \brief Updates the broadphase and computes the lists of created/deleted pairs. + + The data necessary for updating the broadphase is internally computed by the AABB manager. + + To benefit from potentially multithreaded implementations, it is necessary to provide a continuation + task to the function. It is legal to pass NULL there, but the underlying (CPU) implementations will + then run single-threaded. + + \param continuation [in] Continuation task to enable multi-threaded implementations, or NULL. + \see PxBaseTask + */ + virtual void update(PxBaseTask* continuation=NULL) = 0; + + /** + \brief Retrieves the broadphase results after an update. + + This should be called once after each update call to retrieve the results of the broadphase. The + results are incremental, i.e. the system only returns new and lost pairs, not all current pairs. + + \param results [out] The broadphase results + \see PxBroadPhaseResults + */ + virtual void fetchResults(PxBroadPhaseResults& results) = 0; + + /** + \brief Helper for single-threaded updates. + + This short helper function performs a single-theaded update and reports the results in a single call. + + \param results [out] The broadphase results + \see PxBroadPhaseResults + */ + PX_FORCE_INLINE void update(PxBroadPhaseResults& results) + { + update(); + fetchResults(results); + } + }; + + /** + \brief AABB manager factory function. + + Use this function to create a new standalone high-level broadphase. + + \param broadphase [in] The broadphase that will be managed by the AABB manager + \return Newly created AABB manager, or NULL + \see PxAABBManager PxBroadPhase + */ + PX_C_EXPORT PX_PHYSX_CORE_API PxAABBManager* PxCreateAABBManager(PxBroadPhase& broadphase); + #if !PX_DOXYGEN } // namespace physx #endif diff --git a/Source/ThirdParty/PhysX/PxBuffer.h b/Source/ThirdParty/PhysX/PxBuffer.h new file mode 100644 index 000000000..bfb5bf2fb --- /dev/null +++ b/Source/ThirdParty/PhysX/PxBuffer.h @@ -0,0 +1,136 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. + +#ifndef PX_BUFFER_H +#define PX_BUFFER_H +/** \addtogroup physics +@{ */ + +#include "foundation/PxFlags.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +#if PX_VC +#pragma warning(push) +#pragma warning(disable : 4435) +#endif + +class PxCudaContextManager; + +/** +\brief Specifies memory space for a PxBuffer instance. + +@see PxBuffer +*/ +struct PxBufferType +{ + enum Enum + { + eHOST, + eDEVICE + }; +}; + +/** +\brief Buffer for delayed bulk read and write operations supporting host and GPU device memory spaces. + +@see PxPhysics::createBuffer(), PxParticleSystem +*/ +class PxBuffer +{ +public: + + /** + \brief Deletes the buffer. + + Do not keep a reference to the deleted instance. + Unfinished operations will be flushed and synchronized on. + */ + virtual void release() = 0; + + /** + \brief Provides access to internal memory (either device or pinned host memory depending on PxBufferType). + + Unfinished operations will be flushed and synchronized on before returning. + */ + virtual void* map() = 0; + + /** + \brief Releases access to internal memory (either device or pinned host memory depending on PxBufferType). + + \param[in] event Optional pointer to CUevent. Used to synchronize on application side work that needs to be completed before + buffer can be accessed again. + */ + virtual void unmap(void* event = NULL) = 0; + + /** + \brief Buffer memory space type. + + @see PxBufferType + */ + virtual PxBufferType::Enum getBufferType() const = 0; + + /** + \brief Size of buffer in bytes. + */ + virtual PxU64 getByteSize() const = 0; + + /** + \brief Get the associated PxCudaContextManager. + + @see PxCudaContextManager. + */ + virtual PxCudaContextManager* getCudaContextManager() const = 0; + + /** + \brief Helper function to synchronize on all pending operations. + + @see PxCudaContextManager. + */ + PX_INLINE void sync() { map(); unmap(); } + + virtual void resize(PxU64 size) = 0; + +protected: + + virtual ~PxBuffer() {} + PX_INLINE PxBuffer() {} +}; + +#if PX_VC +#pragma warning(pop) +#endif + + +#if !PX_DOXYGEN +} // namespace physx +#endif + + /** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/PxClient.h b/Source/ThirdParty/PhysX/PxClient.h index ce540e030..71d39488b 100644 --- a/Source/ThirdParty/PhysX/PxClient.h +++ b/Source/ThirdParty/PhysX/PxClient.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_NX_CLIENT -#define PX_PHYSICS_NX_CLIENT +#ifndef PX_CLIENT_H +#define PX_CLIENT_H #include "foundation/PxFlags.h" @@ -52,13 +50,6 @@ typedef PxU8 PxClientID; */ static const PxClientID PX_DEFAULT_CLIENT = 0; -/** -\brief The maximum number of clients we support. - -@see PxClientID PxScene::createClient() -*/ -static const PxClientID PX_MAX_CLIENTS = 128; - #if !PX_DOXYGEN } // namespace physx #endif diff --git a/Source/ThirdParty/PhysX/PxConeLimitedConstraint.h b/Source/ThirdParty/PhysX/PxConeLimitedConstraint.h new file mode 100644 index 000000000..e8e931f99 --- /dev/null +++ b/Source/ThirdParty/PhysX/PxConeLimitedConstraint.h @@ -0,0 +1,79 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_CONE_LIMITED_CONSTRAINT_H +#define PX_CONE_LIMITED_CONSTRAINT_H + +/** \addtogroup physics +@{ +*/ + +#include "foundation/PxVec3.h" +#include "foundation/PxVec4.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +/** +\brief A constraint descriptor for limiting movement to a conical region. +*/ +struct PxConeLimitedConstraint +{ + PxConeLimitedConstraint() + { + mAxis = PxVec3(0.f, 0.f, 0.f); + mAngle = 0.f; + mLowLimit = 0.f; + mHighLimit = 0.f; + } + + PxVec3 mAxis; //!< Axis of the cone in the actor space of the rigid body + PxReal mAngle; //!< Opening angle in radians + PxReal mLowLimit; //!< Minimum distance + PxReal mHighLimit; //!< Maximum distance +}; + +/** +\brief Compressed form of cone limit parameters +@see PxConeLimitedConstraint +*/ +PX_ALIGN_PREFIX(16) +struct PxConeLimitParams +{ + PxVec4 lowHighLimits; // [lowLimit, highLimit, unused, unused] + PxVec4 axisAngle; // [axis.x, axis.y, axis.z, angle] +}PX_ALIGN_SUFFIX(16); + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/PxConfig.h b/Source/ThirdParty/PhysX/PxConfig.h index aec243fb8..b99a59a03 100644 --- a/Source/ThirdParty/PhysX/PxConfig.h +++ b/Source/ThirdParty/PhysX/PxConfig.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,8 +22,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. - +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. #ifndef PX_CONFIG #define PX_CONFIG diff --git a/Source/ThirdParty/PhysX/PxConstraint.h b/Source/ThirdParty/PhysX/PxConstraint.h index 0e64ff238..c8aa6c231 100644 --- a/Source/ThirdParty/PhysX/PxConstraint.h +++ b/Source/ThirdParty/PhysX/PxConstraint.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PX_PHYSICS_NX_CONSTRAINT -#define PX_PHYSICS_NX_CONSTRAINT +#ifndef PX_CONSTRAINT_H +#define PX_CONSTRAINT_H /** \addtogroup physics @{ @@ -47,33 +46,28 @@ class PxRigidActor; class PxScene; class PxConstraintConnector; -/** -\brief a table of function pointers for a constraint - -@see PxConstraint -*/ - /** \brief constraint flags \note eBROKEN is a read only flag */ - struct PxConstraintFlag { enum Enum { - eBROKEN = 1<<0, //!< whether the constraint is broken - ePROJECT_TO_ACTOR0 = 1<<1, //!< whether actor1 should get projected to actor0 for this constraint (note: projection of a static/kinematic actor to a dynamic actor will be ignored) - ePROJECT_TO_ACTOR1 = 1<<2, //!< whether actor0 should get projected to actor1 for this constraint (note: projection of a static/kinematic actor to a dynamic actor will be ignored) - ePROJECTION = ePROJECT_TO_ACTOR0 | ePROJECT_TO_ACTOR1, //!< whether the actors should get projected for this constraint (the direction will be chosen by PhysX) - eCOLLISION_ENABLED = 1<<3, //!< whether contacts should be generated between the objects this constraint constrains - eVISUALIZATION = 1<<4, //!< whether this constraint should be visualized, if constraint visualization is turned on - eDRIVE_LIMITS_ARE_FORCES = 1<<5, //!< limits for drive strength are forces rather than impulses - eIMPROVED_SLERP = 1<<7, //!< perform preprocessing for improved accuracy on D6 Slerp Drive (this flag will be removed in a future release when preprocessing is no longer required) - eDISABLE_PREPROCESSING = 1<<8, //!< suppress constraint preprocessing, intended for use with rowResponseThreshold. May result in worse solver accuracy for ill-conditioned constraints. - eENABLE_EXTENDED_LIMITS = 1<<9, //!< enables extended limit ranges for angular limits (e.g. limit values > PxPi or < -PxPi) - eGPU_COMPATIBLE = 1<<10 //!< the constraint type is supported by gpu dynamic + eBROKEN = 1<<0, //!< whether the constraint is broken + ePROJECT_TO_ACTOR0 = 1<<1, //!< @deprecated whether actor1 should get projected to actor0 for this constraint (note: projection of a static/kinematic actor to a dynamic actor will be ignored) + ePROJECT_TO_ACTOR1 = 1<<2, //!< @deprecated whether actor0 should get projected to actor1 for this constraint (note: projection of a static/kinematic actor to a dynamic actor will be ignored) + ePROJECTION = ePROJECT_TO_ACTOR0 | ePROJECT_TO_ACTOR1, //!< @deprecated whether the actors should get projected for this constraint (the direction will be chosen by PhysX) + eCOLLISION_ENABLED = 1<<3, //!< whether contacts should be generated between the objects this constraint constrains + eVISUALIZATION = 1<<4, //!< whether this constraint should be visualized, if constraint visualization is turned on + eDRIVE_LIMITS_ARE_FORCES = 1<<5, //!< limits for drive strength are forces rather than impulses + eIMPROVED_SLERP = 1<<7, //!< perform preprocessing for improved accuracy on D6 Slerp Drive (this flag will be removed in a future release when preprocessing is no longer required) + eDISABLE_PREPROCESSING = 1<<8, //!< suppress constraint preprocessing, intended for use with rowResponseThreshold. May result in worse solver accuracy for ill-conditioned constraints. + eENABLE_EXTENDED_LIMITS = 1<<9, //!< enables extended limit ranges for angular limits (e.g., limit values > PxPi or < -PxPi) + eGPU_COMPATIBLE = 1<<10, //!< the constraint type is supported by gpu dynamics + eALWAYS_UPDATE = 1<<11, //!< updates the constraint each frame + eDISABLE_CONSTRAINT = 1<<12 //!< disables the constraint. SolverPrep functions won't be called for this constraint. }; }; @@ -81,30 +75,27 @@ struct PxConstraintFlag \brief constraint flags @see PxConstraintFlag */ - typedef PxFlags PxConstraintFlags; PX_FLAGS_OPERATORS(PxConstraintFlag::Enum, PxU16) +/** +\brief a table of function pointers for a constraint + +@see PxConstraint +*/ struct PxConstraintShaderTable { - enum - { - eMAX_SOLVERPRPEP_DATASIZE=400 - }; - - PxConstraintSolverPrep solverPrep; //!< solver constraint generation function - PxConstraintProject project; //!< constraint projection function - PxConstraintVisualize visualize; //!< constraint visualization function - PxConstraintFlag::Enum flag; //!< gpu constraint + PxConstraintSolverPrep solverPrep; //!< solver constraint generation function + PxConstraintProject project; //!< @deprecated constraint projection function + PxConstraintVisualize visualize; //!< constraint visualization function + PxConstraintFlag::Enum flag; //!< constraint flags }; - /** \brief A plugin class for implementing constraints @see PxPhysics.createConstraint */ - class PxConstraint : public PxBase { public: @@ -152,6 +143,14 @@ public: */ virtual void markDirty() = 0; + /** + \brief Retrieve the flags for this constraint + + \return the constraint flags + @see PxConstraintFlags + */ + virtual PxConstraintFlags getFlags() const = 0; + /** \brief Set the flags for this constraint @@ -163,14 +162,6 @@ public: */ virtual void setFlags(PxConstraintFlags flags) = 0; - /** - \brief Retrieve the flags for this constraint - - \return the constraint flags - @see PxConstraintFlags - */ - virtual PxConstraintFlags getFlags() const = 0; - /** \brief Set a flag for this constraint @@ -183,6 +174,9 @@ public: /** \brief Retrieve the constraint force most recently applied to maintain this constraint. + + \note It is not allowed to use this method while the simulation is running (except during PxScene::collide(), + in PxContactModifyCallback or in contact report callbacks). \param[out] linear the constraint force \param[out] angular the constraint torque @@ -259,17 +253,17 @@ public: @see PxConstraintConnector PxConstraintSolverPrep PxConstraintProject PxConstraintVisualize */ - virtual void setConstraintFunctions(PxConstraintConnector& connector, - const PxConstraintShaderTable& shaders) = 0; + virtual void setConstraintFunctions(PxConstraintConnector& connector, const PxConstraintShaderTable& shaders) = 0; - virtual const char* getConcreteTypeName() const { return "PxConstraint"; } + virtual const char* getConcreteTypeName() const PX_OVERRIDE { return "PxConstraint"; } + + void* userData; //!< user can assign this to whatever, usually to create a 1:1 relationship with a user object. protected: - PX_INLINE PxConstraint(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags) {} - PX_INLINE PxConstraint(PxBaseFlags baseFlags) : PxBase(baseFlags) {} + PX_INLINE PxConstraint(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags), userData(NULL) {} + PX_INLINE PxConstraint(PxBaseFlags baseFlags) : PxBase(baseFlags), userData(NULL) {} virtual ~PxConstraint() {} - virtual bool isKindOf(const char* name) const { return !::strcmp("PxConstraint", name) || PxBase::isKindOf(name); } - + virtual bool isKindOf(const char* name) const PX_OVERRIDE { return !::strcmp("PxConstraint", name) || PxBase::isKindOf(name); } }; #if !PX_DOXYGEN diff --git a/Source/ThirdParty/PhysX/PxConstraintDesc.h b/Source/ThirdParty/PhysX/PxConstraintDesc.h index 785f5879f..12aa7559d 100644 --- a/Source/ThirdParty/PhysX/PxConstraintDesc.h +++ b/Source/ThirdParty/PhysX/PxConstraintDesc.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PX_PHYSICS_NX_CONSTRAINTDESC -#define PX_PHYSICS_NX_CONSTRAINTDESC +#ifndef PX_CONSTRAINT_DESC_H +#define PX_CONSTRAINT_DESC_H /** \addtogroup physics @{ @@ -52,15 +51,8 @@ namespace physx { #endif -class PxConstraintConnector; -class PxRigidActor; -class PxScene; -class PxConstraintConnector; -class PxRenderBuffer; -class PxDeletionListener; - /** - \brief constraint row flags + \brief Constraint row flags These flags configure the post-processing of constraint rows and the behavior of the solver while solving constraints */ @@ -76,8 +68,8 @@ struct Px1DConstraintFlag eKEEPBIAS = 1<<3, //!< whether to keep the error term when solving for velocity. Ignored if restitution generates bounce, or eSPRING is set. eOUTPUT_FORCE = 1<<4, //!< whether to accumulate the force value from this constraint in the force total that is reported for the constraint and tested for breakage eHAS_DRIVE_LIMIT = 1<<5, //!< whether the constraint has a drive force limit (which will be scaled by dt unless PxConstraintFlag::eLIMITS_ARE_FORCES is set) - eANGULAR_CONSTRAINT = 1 << 6,//!< Whether this is an angular or linear constraint - eDRIVE_ROW = 1 << 7 + eANGULAR_CONSTRAINT = 1<<6, //!< whether this is an angular or linear constraint + eDRIVE_ROW = 1<<7 //!< whether the constraint's geometric error should drive the target velocity }; }; @@ -85,7 +77,7 @@ typedef PxFlags Px1DConstraintFlags; PX_FLAGS_OPERATORS(Px1DConstraintFlag::Type, PxU16) /** -\brief constraint type hints which the solver uses to optimize constraint handling +\brief Constraint type hints which the solver uses to optimize constraint handling */ struct PxConstraintSolveHint { @@ -104,7 +96,7 @@ struct PxConstraintSolveHint }; /** -\brief A constraint +\brief A one-dimensional constraint A constraint is expressed as a set of 1-dimensional constraint rows which define the required constraint on the objects' velocities. @@ -140,37 +132,36 @@ All constraints support limits on the minimum or maximum impulse applied. PX_ALIGN_PREFIX(16) struct Px1DConstraint { - PxVec3 linear0; //!< linear component of velocity jacobian in world space - PxReal geometricError; //!< geometric error of the constraint along this axis - PxVec3 angular0; //!< angular component of velocity jacobian in world space - PxReal velocityTarget; //!< velocity target for the constraint along this axis + PxVec3 linear0; //!< linear component of velocity jacobian in world space + PxReal geometricError; //!< geometric error of the constraint along this axis + PxVec3 angular0; //!< angular component of velocity jacobian in world space + PxReal velocityTarget; //!< velocity target for the constraint along this axis - PxVec3 linear1; //!< linear component of velocity jacobian in world space - PxReal minImpulse; //!< minimum impulse the solver may apply to enforce this constraint - PxVec3 angular1; //!< angular component of velocity jacobian in world space - PxReal maxImpulse; //!< maximum impulse the solver may apply to enforce this constraint + PxVec3 linear1; //!< linear component of velocity jacobian in world space + PxReal minImpulse; //!< minimum impulse the solver may apply to enforce this constraint + PxVec3 angular1; //!< angular component of velocity jacobian in world space + PxReal maxImpulse; //!< maximum impulse the solver may apply to enforce this constraint union { struct SpringModifiers { - PxReal stiffness; //!< spring parameter, for spring constraints - PxReal damping; //!< damping parameter, for spring constraints + PxReal stiffness; //!< spring parameter, for spring constraints + PxReal damping; //!< damping parameter, for spring constraints } spring; struct RestitutionModifiers { - PxReal restitution; //!< restitution parameter for determining additional "bounce" - PxReal velocityThreshold; //!< minimum impact velocity for bounce + PxReal restitution; //!< restitution parameter for determining additional "bounce" + PxReal velocityThreshold; //!< minimum impact velocity for bounce } bounce; } mods; - PxReal forInternalUse; //!< for internal use only - PxU16 flags; //!< a set of Px1DConstraintFlags - PxU16 solveHint; //!< constraint optimization hint, should be an element of PxConstraintSolveHint -} + PxReal forInternalUse; //!< for internal use only + PxU16 flags; //!< a set of Px1DConstraintFlags + PxU16 solveHint; //!< constraint optimization hint, should be an element of PxConstraintSolveHint +} PX_ALIGN_SUFFIX(16); - /** \brief Flags for determining which components of the constraint should be visualized. @@ -185,6 +176,9 @@ struct PxConstraintVisualizationFlag }; }; +/** +\brief Struct for specifying mass scaling for a pair of rigids +*/ PX_ALIGN_PREFIX(16) struct PxConstraintInvMassScale { @@ -205,7 +199,8 @@ struct PxConstraintInvMassScale } PX_ALIGN_SUFFIX(16); -/** solver constraint generation shader +/** +\brief Solver constraint generation shader This function is called by the constraint solver framework. The function must be reentrant, since it may be called simultaneously from multiple threads, and should access only the arguments passed into it. @@ -226,17 +221,18 @@ Developers writing custom constraints are encouraged to read the documentation i \return the number of constraint rows written. */ typedef PxU32 (*PxConstraintSolverPrep)(Px1DConstraint* constraints, - PxVec3& bodyAWorldOffset, + PxVec3p& bodyAWorldOffset, PxU32 maxConstraints, PxConstraintInvMassScale& invMassScale, const void* constantBlock, const PxTransform& bodyAToWorld, const PxTransform& bodyBToWorld, bool useExtendedLimits, - PxVec3& cAtW, - PxVec3& cBtW); + PxVec3p& cAtW, + PxVec3p& cBtW); -/** solver constraint projection shader +/** +\brief Solver constraint projection shader This function is called by the constraint post-solver framework. The function must be reentrant, since it may be called simultaneously from multiple threads and should access only the arguments passed into it. @@ -245,28 +241,30 @@ from multiple threads and should access only the arguments passed into it. \param[out] bodyAToWorld The center of mass frame of the first constrained body (the identity if the actor is static or a NULL pointer was provided for it) \param[out] bodyBToWorld The center of mass frame of the second constrained body (the identity if the actor is static or a NULL pointer was provided for it) \param[in] projectToA True if the constraint should be projected by moving the second body towards the first, false if the converse + +@deprecated */ -typedef void (*PxConstraintProject)(const void* constantBlock, +typedef PX_DEPRECATED void (*PxConstraintProject)(const void* constantBlock, PxTransform& bodyAToWorld, PxTransform& bodyBToWorld, bool projectToA); /** - API used to visualize details about a constraint. +\brief API used to visualize details about a constraint. */ class PxConstraintVisualizer { protected: virtual ~PxConstraintVisualizer(){} public: - /** Visualize joint frames + /** \brief Visualize joint frames \param[in] parent Parent transformation \param[in] child Child transformation */ virtual void visualizeJointFrames(const PxTransform& parent, const PxTransform& child) = 0; - /** Visualize joint linear limit + /** \brief Visualize joint linear limit \param[in] t0 Base transformation \param[in] t1 End transformation @@ -275,7 +273,7 @@ public: */ virtual void visualizeLinearLimit(const PxTransform& t0, const PxTransform& t1, PxReal value, bool active) = 0; - /** Visualize joint angular limit + /** \brief Visualize joint angular limit \param[in] t0 Transformation for the visualization \param[in] lower Lower limit angle @@ -284,7 +282,7 @@ public: */ virtual void visualizeAngularLimit(const PxTransform& t0, PxReal lower, PxReal upper, bool active) = 0; - /** Visualize limit cone + /** \brief Visualize limit cone \param[in] t Transformation for the visualization \param[in] tanQSwingY Tangent of the quarter Y angle @@ -293,7 +291,7 @@ public: */ virtual void visualizeLimitCone(const PxTransform& t, PxReal tanQSwingY, PxReal tanQSwingZ, bool active) = 0; - /** Visualize joint double cone + /** \brief Visualize joint double cone \param[in] t Transformation for the visualization \param[in] angle Limit angle @@ -301,7 +299,7 @@ public: */ virtual void visualizeDoubleCone(const PxTransform& t, PxReal angle, bool active) = 0; - /** Visualize line + /** \brief Visualize line \param[in] p0 Start position \param[in] p1 End postion @@ -310,7 +308,7 @@ public: virtual void visualizeLine(const PxVec3& p0, const PxVec3& p1, PxU32 color) = 0; }; -/** solver constraint visualization function +/** \brief Solver constraint visualization function This function is called by the constraint post-solver framework to visualize the constraint @@ -328,20 +326,23 @@ typedef void (*PxConstraintVisualize)(PxConstraintVisualizer& visualizer, const PxTransform& body1Transform, PxU32 flags); +/** +\brief Flags for determining how PVD should serialize a constraint update +@see PxConstraintConnector::updatePvdProperties, PvdSceneClient::updateConstraint +*/ struct PxPvdUpdateType { enum Enum { - CREATE_INSTANCE, - RELEASE_INSTANCE, - UPDATE_ALL_PROPERTIES, - UPDATE_SIM_PROPERTIES + CREATE_INSTANCE, //!< triggers createPvdInstance call, creates an instance of a constraint + RELEASE_INSTANCE, //!< triggers releasePvdInstance call, releases an instance of a constraint + UPDATE_ALL_PROPERTIES, //!< triggers updatePvdProperties call, updates all properties of a constraint + UPDATE_SIM_PROPERTIES //!< triggers simUpdate call, updates all simulation properties of a constraint }; }; -/** - +/** \brief This class connects a custom constraint to the SDK This class connects a custom constraint to the SDK, and functions are called by the SDK @@ -352,40 +353,50 @@ the custom constraint's internal implementation class PxConstraintConnector { public: - /** + /** \brief Pre-simulation data preparation when the constraint is marked dirty, this function is called at the start of the simulation step for the SDK to copy the constraint data block. */ - virtual void* prepareData() = 0; + virtual void* prepareData() = 0; /** - this function is called by the SDK to update PVD's view of it + \brief this function is called by the SDK to update PVD's view of it */ - virtual bool updatePvdProperties(physx::pvdsdk::PvdDataStream& pvdConnection, - const PxConstraint* c, - PxPvdUpdateType::Enum updateType) const = 0; + virtual bool updatePvdProperties(physx::pvdsdk::PvdDataStream& pvdConnection, + const PxConstraint* c, + PxPvdUpdateType::Enum updateType) const = 0; + + /** + \brief this function is called by the SDK to update OmniPVD's view of it + */ + virtual void updateOmniPvdProperties() const = 0; + + /** + \brief Constraint release callback - /** When the SDK deletes a PxConstraint object this function is called by the SDK. In general custom constraints should not be deleted directly by applications: rather, the constraint should respond to a release() request by calling PxConstraint::release(), then wait for - this call to release its own resources, so that even if the release() call occurs during - a simulation step, the deletion of the constraint is buffered until that step completes. + this call to release its own resources. This function is also called when a PxConstraint object is deleted on cleanup due to destruction of the PxPhysics object. */ - virtual void onConstraintRelease() = 0; + virtual void onConstraintRelease() = 0; + + /** + \brief Center-of-mass shift callback - /** This function is called by the SDK when the CoM of one of the actors is moved. Since the API specifies constraint positions relative to actors, and the constraint shader functions are supplied with coordinates relative to bodies, some synchronization is usually required when the application moves an object's center of mass. */ - virtual void onComShift(PxU32 actor) = 0; + virtual void onComShift(PxU32 actor) = 0; /** + \brief Origin shift callback + This function is called by the SDK when the scene origin gets shifted and allows to adjust custom data which contains world space transforms. @@ -396,7 +407,7 @@ public: @see PxScene.shiftOrigin() */ - virtual void onOriginShift(const PxVec3& shift) = 0; + virtual void onOriginShift(const PxVec3& shift) = 0; /** \brief Fetches external data for a constraint. @@ -410,29 +421,34 @@ public: @see PxConstraintInfo PxSimulationEventCallback.onConstraintBreak() */ - virtual void* getExternalReference(PxU32& typeID) = 0; + virtual void* getExternalReference(PxU32& typeID) = 0; /** \brief Obtain a reference to a PxBase interface if the constraint has one. If the constraint does not implement the PxBase interface, it should return NULL. */ - virtual PxBase* getSerializable() = 0; + virtual PxBase* getSerializable() = 0; /** \brief Obtain the shader function pointer used to prep rows for this constraint */ - virtual PxConstraintSolverPrep getPrep() const = 0; + virtual PxConstraintSolverPrep getPrep() const = 0; /** \brief Obtain the pointer to the constraint's constant data */ - virtual const void* getConstantBlock() const = 0; + virtual const void* getConstantBlock() const = 0; + + /** + \brief Let the connector know it has been connected to a constraint. + */ + virtual void connectToConstraint(PxConstraint*) {} /** \brief virtual destructor */ - virtual ~PxConstraintConnector() {} + virtual ~PxConstraintConnector() {} }; #if !PX_DOXYGEN diff --git a/Source/ThirdParty/PhysX/PxContact.h b/Source/ThirdParty/PhysX/PxContact.h index 4d85f59a5..f10112bc1 100644 --- a/Source/ThirdParty/PhysX/PxContact.h +++ b/Source/ThirdParty/PhysX/PxContact.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,16 +22,20 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - #ifndef PX_CONTACT_H #define PX_CONTACT_H +/** \addtogroup physics + @{ +*/ + #include "foundation/PxVec3.h" #include "foundation/PxAssert.h" +#include "PxNodeIndex.h" #if !PX_DOXYGEN namespace physx @@ -46,8 +49,14 @@ namespace physx #define PXC_CONTACT_NO_FACE_INDEX 0xffffffff +class PxActor; + +/** +\brief Struct for specifying mass modification for a pair of rigids +\deprecated Use #PxConstraintInvMassScale instead. Deprecated since PhysX version 5.1. +*/ PX_ALIGN_PREFIX(16) -struct PxMassModificationProps +struct PX_DEPRECATED PxMassModificationProps { PxReal mInvMassScale0; PxReal mInvInertiaScale0; @@ -57,9 +66,8 @@ struct PxMassModificationProps PX_ALIGN_SUFFIX(16); /** -\brief Header for contact patch where all points share same material and normal +\brief Header for a contact patch where all points share same material and normal */ - PX_ALIGN_PREFIX(16) struct PxContactPatch { @@ -71,39 +79,78 @@ struct PxContactPatch eHAS_MODIFIED_MASS_RATIOS = 8, //!< Indicates this contact stream has modified mass ratios eHAS_TARGET_VELOCITY = 16, //!< Indicates this contact stream has target velocities set eHAS_MAX_IMPULSE = 32, //!< Indicates this contact stream has max impulses set - eREGENERATE_PATCHES = 64, //!< Indicates this contact stream needs patches re-generated. - //!< This is required if the application modified either the contact normal or the material properties + eREGENERATE_PATCHES = 64, //!< Indicates this contact stream needs patches re-generated. This is required if the application modified either the contact normal or the material properties eCOMPRESSED_MODIFIED_CONTACT = 128 }; + /** + \brief Modifiers for scaling the inertia of the involved bodies + */ PX_ALIGN(16, PxMassModificationProps mMassModification); //16 + /** \brief Contact normal */ PX_ALIGN(16, PxVec3 normal); //28 + /** \brief Restitution coefficient */ PxReal restitution; //32 + /** + \brief Dynamic friction coefficient + */ PxReal dynamicFriction; //36 - PxReal staticFriction; //40 - PxU8 startContactIndex; //41 - PxU8 nbContacts; //42 //Can be a U8 - PxU8 materialFlags; //43 //Can be a U16 - PxU8 internalFlags; //44 //Can be a U16 - PxU16 materialIndex0; //46 //Can be a U16 - PxU16 materialIndex1; //48 //Can be a U16 - + /** + \brief Static friction coefficient + */ + PxReal staticFriction; //40 + + /** + \brief Damping coefficient (for compliant contacts) + */ + PxReal damping; //44 + + /** + \brief Index of the first contact in the patch + */ + PxU16 startContactIndex; //46 + /** + \brief The number of contacts in this patch + */ + PxU8 nbContacts; //47 //Can be a U8 + + /** + \brief The combined material flag of two actors that come in contact + @see PxMaterialFlag, PxCombineMode + */ + PxU8 materialFlags; //48 //Can be a U16 + + /** + \brief The PxContactPatchFlags for this patch + */ + PxU16 internalFlags; //50 //Can be a U16 + + /** + \brief Material index of first body + */ + PxU16 materialIndex0; //52 //Can be a U16 + + /** + \brief Material index of second body + */ + PxU16 materialIndex1; //54 //Can be a U16 + + PxU16 pad[5]; //64 } PX_ALIGN_SUFFIX(16); /** -\brief Contact point data including face (feature) indices +\brief Contact point data */ - PX_ALIGN_PREFIX(16) struct PxContact { @@ -118,6 +165,9 @@ struct PxContact } PX_ALIGN_SUFFIX(16); +/** +\brief Contact point data with additional target and max impulse values +*/ PX_ALIGN_PREFIX(16) struct PxExtendedContact : public PxContact { @@ -189,6 +239,7 @@ struct PxContactStreamIterator cause performance issues on certain platforms. */ PxVec3 zero; + /** \brief The patch headers. */ @@ -204,7 +255,6 @@ struct PxContactStreamIterator */ const PxU32* faceIndice; - /** \brief The total number of patches in this contact stream */ @@ -225,27 +275,37 @@ struct PxContactStreamIterator */ PxU32 nextPatchIndex; - /* + /** \brief Size of contact patch header \note This varies whether the patch is modifiable or not. */ PxU32 contactPatchHeaderSize; + /** \brief Contact point size \note This varies whether the patch has feature indices or is modifiable. */ PxU32 contactPointSize; + /** \brief The stream format */ StreamFormat mStreamFormat; + /** \brief Indicates whether this stream is notify-only or not. */ PxU32 forceNoResponse; + /** + \brief Internal helper for stepping the contact stream iterator + */ bool pointStepped; + /** + \brief Specifies if this contactPatch has face indices (handled as bool) + @see faceIndice + */ PxU32 hasFaceIndices; /** @@ -314,6 +374,10 @@ struct PxContactStreamIterator return totalContacts; } + /** + \brief Returns the total patch count. + \return Total patch count. + */ PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 getTotalPatchCount() const { return totalPatches; @@ -362,7 +426,6 @@ struct PxContactStreamIterator pointStepped = true; } - /** \brief Gets the current contact's normal \return The current contact's normal. @@ -472,8 +535,8 @@ struct PxContactStreamIterator } /** - \brief Gets the contact's static dynamic coefficient. - \return The contact's static dynamic coefficient. + \brief Gets the contact's dynamic friction coefficient. + \return The contact's dynamic friction coefficient. */ PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getDynamicFriction() const { @@ -489,6 +552,15 @@ struct PxContactStreamIterator return getContactPatch().restitution; } + /** + \brief Gets the contact's damping value. + \return The contact's damping value. + */ + PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal getDamping() const + { + return getContactPatch().damping; + } + /** \brief Gets the contact's material flags. \return The contact's material flags. @@ -518,6 +590,7 @@ struct PxContactStreamIterator /** \brief Advances the contact stream iterator to a specific contact index. + \return True if advancing was possible */ bool advanceToIndex(const PxU32 initialIndex) { @@ -571,6 +644,25 @@ private: }; +/** +\brief Contains contact information for a contact reported by the direct-GPU contact report API. See PxScene::copyContactData(). +*/ +struct PxGpuContactPair +{ + PxU8* contactPatches; //!< Ptr to contact patches. Type: PxContactPatch*, size: nbPatches. + PxU8* contactPoints; //!< Ptr to contact points. Type: PxContact*, size: nbContacts. + PxReal* contactForces; //!< Ptr to contact forces. Size: nbContacts. + PxU32 transformCacheRef0; //!< Ref to shape0's transform in transform cache. + PxU32 transformCacheRef1; //!< Ref to shape1's transform in transform cache. + PxNodeIndex nodeIndex0; //!< Unique Id for actor0 if the actor is dynamic. + PxNodeIndex nodeIndex1; //!< Unique Id for actor1 if the actor is dynamic. + PxActor* actor0; //!< Ptr to PxActor for actor0. + PxActor* actor1; //!< Ptr to PxActor for actor1. + + PxU16 nbContacts; //!< Num contacts. + PxU16 nbPatches; //!< Num patches. +}; + #if PX_VC #pragma warning(pop) @@ -580,4 +672,5 @@ private: } // namespace physx #endif +/** @} */ #endif diff --git a/Source/ThirdParty/PhysX/PxContactModifyCallback.h b/Source/ThirdParty/PhysX/PxContactModifyCallback.h index bb3bb58fd..6087d08f8 100644 --- a/Source/ThirdParty/PhysX/PxContactModifyCallback.h +++ b/Source/ThirdParty/PhysX/PxContactModifyCallback.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_CONTACT_MODIFY_CALLBACK -#define PX_CONTACT_MODIFY_CALLBACK +#ifndef PX_CONTACT_MODIFY_CALLBACK_H +#define PX_CONTACT_MODIFY_CALLBACK_H /** \addtogroup physics @{ */ @@ -63,6 +61,8 @@ class PxContactSet public: /** \brief Get the position of a specific contact point in the set. + \param[in] i Index of the point in the set + \return Position to the requested point in world space @see PxModifiableContact.point */ @@ -70,6 +70,8 @@ public: /** \brief Alter the position of a specific contact point in the set. + \param[in] i Index of the point in the set + \param[in] p The new position in world space @see PxModifiableContact.point */ @@ -77,6 +79,8 @@ public: /** \brief Get the contact normal of a specific contact point in the set. + \param[in] i Index of the point in the set + \return The requested normal in world space @see PxModifiableContact.normal */ @@ -84,6 +88,8 @@ public: /** \brief Alter the contact normal of a specific contact point in the set. + \param[in] i Index of the point in the set + \param[in] n The new normal in world space \note Changing the normal can cause contact points to be ignored. @@ -97,7 +103,9 @@ public: } /** - \brief Get the separation of a specific contact point in the set. + \brief Get the separation distance of a specific contact point in the set. + \param[in] i Index of the point in the set + \return The separation. Negative implies penetration. @see PxModifiableContact.separation */ @@ -105,6 +113,8 @@ public: /** \brief Alter the separation of a specific contact point in the set. + \param[in] i Index of the point in the set + \param[in] s The new separation @see PxModifiableContact.separation */ @@ -112,6 +122,8 @@ public: /** \brief Get the target velocity of a specific contact point in the set. + \param[in] i Index of the point in the set + \return The target velocity in world frame @see PxModifiableContact.targetVelocity @@ -120,6 +132,8 @@ public: /** \brief Alter the target velocity of a specific contact point in the set. + \param[in] i Index of the point in the set + \param[in] v The new velocity in world frame @see PxModifiableContact.targetVelocity */ @@ -132,17 +146,22 @@ public: /** \brief Get the face index with respect to the first shape of the pair for a specific contact point in the set. + \param[in] i Index of the point in the set + \return The face index of the first shape + \note At the moment, the first shape is never a tri-mesh, therefore this function always returns PXC_CONTACT_NO_FACE_INDEX @see PxModifiableContact.internalFaceIndex0 */ - PX_FORCE_INLINE PxU32 getInternalFaceIndex0(PxU32 i) { PX_UNUSED(i); return PXC_CONTACT_NO_FACE_INDEX; } + PX_FORCE_INLINE PxU32 getInternalFaceIndex0(PxU32 i) const { PX_UNUSED(i); return PXC_CONTACT_NO_FACE_INDEX; } /** \brief Get the face index with respect to the second shape of the pair for a specific contact point in the set. + \param[in] i Index of the point in the set + \return The face index of the second shape @see PxModifiableContact.internalFaceIndex1 */ - PX_FORCE_INLINE PxU32 getInternalFaceIndex1(PxU32 i) + PX_FORCE_INLINE PxU32 getInternalFaceIndex1(PxU32 i) const { PxContactPatch* patch = getPatch(); if (patch->internalFlags & PxContactPatch::eHAS_FACE_INDICES) @@ -154,6 +173,8 @@ public: /** \brief Get the maximum impulse for a specific contact point in the set. + \param[in] i Index of the point in the set + \return The maximum impulse @see PxModifiableContact.maxImpulse */ @@ -161,12 +182,14 @@ public: /** \brief Alter the maximum impulse for a specific contact point in the set. + \param[in] i Index of the point in the set + \param[in] s The new maximum impulse \note Must be nonnegative. If set to zero, the contact point will be ignored - @see PxModifiableContact.maxImpulse + @see PxModifiableContact.maxImpulse, ignore() */ - PX_FORCE_INLINE void setMaxImpulse(PxU32 i, PxReal s) + PX_FORCE_INLINE void setMaxImpulse(PxU32 i, PxReal s) { PxContactPatch* patch = getPatch(); patch->internalFlags |= PxContactPatch::eHAS_MAX_IMPULSE; @@ -175,6 +198,8 @@ public: /** \brief Get the restitution coefficient for a specific contact point in the set. + \param[in] i Index of the point in the set + \return The restitution coefficient @see PxModifiableContact.restitution */ @@ -182,12 +207,14 @@ public: /** \brief Alter the restitution coefficient for a specific contact point in the set. + \param[in] i Index of the point in the set + \param[in] r The new restitution coefficient \note Valid ranges [0,1] @see PxModifiableContact.restitution */ - PX_FORCE_INLINE void setRestitution(PxU32 i, PxReal r) + PX_FORCE_INLINE void setRestitution(PxU32 i, PxReal r) { PxContactPatch* patch = getPatch(); patch->internalFlags |= PxContactPatch::eREGENERATE_PATCHES; @@ -196,6 +223,8 @@ public: /** \brief Get the static friction coefficient for a specific contact point in the set. + \param[in] i Index of the point in the set + \return The friction coefficient (dimensionless) @see PxModifiableContact.staticFriction */ @@ -203,6 +232,8 @@ public: /** \brief Alter the static friction coefficient for a specific contact point in the set. + \param[in] i Index of the point in the set + \param[in] f The new friction coefficient (dimensionless), range [0, inf] @see PxModifiableContact.staticFriction */ @@ -215,6 +246,8 @@ public: /** \brief Get the static friction coefficient for a specific contact point in the set. + \param[in] i Index of the point in the set + \return The friction coefficient @see PxModifiableContact.dynamicFriction */ @@ -222,8 +255,10 @@ public: /** \brief Alter the static dynamic coefficient for a specific contact point in the set. + \param[in] i Index of the point in the set + \param[in] f The new friction coefficient - @see PxModifiableContact.dynamic + @see PxModifiableContact.dynamicFriction */ PX_FORCE_INLINE void setDynamicFriction(PxU32 i, PxReal f) { @@ -234,10 +269,11 @@ public: /** \brief Ignore the contact point. + \param[in] i Index of the point in the set If a contact point is ignored then no force will get applied at this point. This can be used to disable collision in certain areas of a shape, for example. */ - PX_FORCE_INLINE void ignore(PxU32 i) { mContacts[i].maxImpulse = 0.f; } + PX_FORCE_INLINE void ignore(PxU32 i) { setMaxImpulse(i, 0.0f); } /** \brief The number of contact points in the set. @@ -294,6 +330,7 @@ public: /** \brief Sets the invMassScale of body 0 + \param[in] scale The new scale This can be set to any value in the range [0, PX_MAX_F32). A value < 1.0 makes this contact treat the body as if it had larger mass. A value of 0.f makes this contact treat the body as if it had infinite mass. Any value > 1.f makes this contact treat the body as if it had smaller mass. @@ -307,6 +344,7 @@ public: /** \brief Sets the invMassScale of body 1 + \param[in] scale The new scale This can be set to any value in the range [0, PX_MAX_F32). A value < 1.0 makes this contact treat the body as if it had larger mass. A value of 0.f makes this contact treat the body as if it had infinite mass. Any value > 1.f makes this contact treat the body as if it had smaller mass. @@ -320,6 +358,7 @@ public: /** \brief Sets the invInertiaScale of body 0 + \param[in] scale The new scale This can be set to any value in the range [0, PX_MAX_F32). A value < 1.0 makes this contact treat the body as if it had larger inertia. A value of 0.f makes this contact treat the body as if it had infinite inertia. Any value > 1.f makes this contact treat the body as if it had smaller inertia. @@ -333,6 +372,7 @@ public: /** \brief Sets the invInertiaScale of body 1 + \param[in] scale The new scale This can be set to any value in the range [0, PX_MAX_F32). A value < 1.0 makes this contact treat the body as if it had larger inertia. A value of 0.f makes this contact treat the body as if it had infinite inertia. Any value > 1.f makes this contact treat the body as if it had smaller inertia. @@ -373,14 +413,13 @@ public: Note that these are the actors as seen by the simulation, and may have been deleted since the simulation step started. */ - const PxRigidActor* actor[2]; + /** \brief The shapes which make up the pair in contact. Note that these are the shapes as seen by the simulation, and may have been deleted since the simulation step started. */ - const PxShape* shape[2]; /** @@ -388,15 +427,12 @@ public: These are the transforms as the simulation engine sees them, and may have been modified by the application since the simulation step started. - */ - PxTransform transform[2]; /** \brief An array of contact points between these two shapes. */ - PxContactSet contacts; }; @@ -426,11 +462,14 @@ public: /** \brief Passes modifiable arrays of contacts to the application. - The initial contacts are as determined fresh each frame by collision detection. + The initial contacts are regenerated from scratch each frame by collision detection. The number of contacts can not be changed, so you cannot add your own contacts. You may however disable contacts using PxContactSet::ignore(). + \param[in,out] pairs The contact pairs that may be modified + \param[in] count Number of contact pairs + @see PxContactModifyPair */ virtual void onContactModify(PxContactModifyPair* const pairs, PxU32 count) = 0; @@ -464,12 +503,13 @@ public: /** \brief Passes modifiable arrays of contacts to the application. - The initial contacts are as determined fresh each frame by collision detection. - + The initial contacts are regenerated from scratch each frame by collision detection. + The number of contacts can not be changed, so you cannot add your own contacts. You may however disable contacts using PxContactSet::ignore(). - @see PxContactModifyPair + \param[in,out] pairs The contact pairs that may be modified + \param[in] count Number of contact pairs */ virtual void onCCDContactModify(PxContactModifyPair* const pairs, PxU32 count) = 0; diff --git a/Source/ThirdParty/PhysX/PxCustomParticleSystemSolverCallback.h b/Source/ThirdParty/PhysX/PxCustomParticleSystemSolverCallback.h new file mode 100644 index 000000000..be66d7f56 --- /dev/null +++ b/Source/ThirdParty/PhysX/PxCustomParticleSystemSolverCallback.h @@ -0,0 +1,105 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_CUSTOM_PARTICLE_SYSTEM_SOLVER_CALLBACK_H +#define PX_CUSTOM_PARTICLE_SYSTEM_SOLVER_CALLBACK_H +/** \addtogroup physics +@{ */ + +#include "foundation/PxSimpleTypes.h" +#include "cudamanager/PxCudaTypes.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +#if PX_VC +#pragma warning(push) +#pragma warning(disable : 4435) +#endif + +class PxGpuParticleSystem; + + +class PxCustomParticleSystemSolverCallback +{ +public: + /** + \brief callback called when the particle solver begins. + + This is called once per frame. It occurs after external forces have been pre-integrated into the particle state. + It is called prior to the particles being reordered by spatial hash index, so state can be accessed in the unsorted buffers only at this stage. This provides an opportunity to add custom + forces and modifications to position or velocity. + + \param [in] gpuParticleSystem A pointer to the GPU particle system. This pointer points to a mirror of the particle system in device memory. + \param [in] dt The time-step. + \param [in] stream The CUDA stream currently being used by the particle system. Additional kernels should either be launched on this stream, or synchronization events should be used to avoid race conditions. + */ + virtual void onBegin(PxGpuParticleSystem* gpuParticleSystem, PxReal dt, CUstream stream) = 0; + + /** + \brief callback called during the iterative particle solve stage. + + This callback will potentially be called multiple times between onBegin and onFinalize. + + \param [in] gpuParticleSystem A pointer to the GPU particle system. This pointer points to a mirror of the particle system in device memory. + \param [in] dt The time-step. + \param [in] stream The CUDA stream currently being used by the particle system. Additional kernels should either be launched on this stream, or synchronization events should be used to avoid race conditions. + */ + virtual void onSolve(PxGpuParticleSystem* gpuParticleSystem, PxReal dt, CUstream stream) = 0; + + /** + \brief callback called after all solver iterations have completed. + + This callback will be called once per frame, after integration has completed. + + \param [in] gpuParticleSystem A pointer to the GPU particle system. This pointer points to a mirror of the particle system in device memory. + \param [in] dt The time-step. + \param [in] stream The CUDA stream currently being used by the particle system. Additional kernels should either be launched on this stream, or synchronization events should be used to avoid race conditions. + */ + virtual void onFinalize(PxGpuParticleSystem* gpuParticleSystem, PxReal dt, CUstream stream) = 0; + + /** + \brief Destructor + */ + virtual ~PxCustomParticleSystemSolverCallback() {} +}; + + +#if PX_VC +#pragma warning(pop) +#endif + + +#if !PX_DOXYGEN +} // namespace physx +#endif + + /** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/PxDeletionListener.h b/Source/ThirdParty/PhysX/PxDeletionListener.h index 953bd7bd9..310f58363 100644 --- a/Source/ThirdParty/PhysX/PxDeletionListener.h +++ b/Source/ThirdParty/PhysX/PxDeletionListener.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_NX_DELETIONLISTENER -#define PX_PHYSICS_NX_DELETIONLISTENER +#ifndef PX_DELETION_LISTENER_H +#define PX_DELETION_LISTENER_H /** \addtogroup physics @{ */ diff --git a/Source/ThirdParty/PhysX/PxFEMClothFlags.h b/Source/ThirdParty/PhysX/PxFEMClothFlags.h new file mode 100644 index 000000000..43b7b18d6 --- /dev/null +++ b/Source/ThirdParty/PhysX/PxFEMClothFlags.h @@ -0,0 +1,75 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_PHYSICS_FEM_CLOTH_FLAGS_H +#define PX_PHYSICS_FEM_CLOTH_FLAGS_H + +#include "foundation/PxFlags.h" +#include "foundation/PxSimpleTypes.h" + + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +/** +\brief Identifies input and output buffers for PxFEMCloth. +@see PxFEMClothData::readData(), PxFEMClothData::writeData(), PxBuffer. +*/ +struct PxFEMClothData +{ + enum Enum + { + eNONE = 0, + ePOSITION_INVMASS = 1 << 0, + eVELOCITY = 1 << 1, + eREST_POSITION = 1 << 2, + eALL = ePOSITION_INVMASS | eVELOCITY | eREST_POSITION + }; +}; + +typedef PxFlags PxFEMClothDataFlags; + +struct PxFEMClothFlag +{ + enum Enum + { + eDISABLE_SELF_COLLISION = 1 << 0, + eUSE_ISOTROPIC_CLOTH = 1 << 1, // 0: use anistropic model + eUSE_REST_POSITION_FOR_BENDING = 1 << 2 // 0: use zero bending angle + }; +}; + +typedef PxFlags PxFEMClothFlags; + +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif diff --git a/Source/ThirdParty/PhysX/PxFEMClothMaterial.h b/Source/ThirdParty/PhysX/PxFEMClothMaterial.h new file mode 100644 index 000000000..c1b99cc4d --- /dev/null +++ b/Source/ThirdParty/PhysX/PxFEMClothMaterial.h @@ -0,0 +1,116 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_FEM_CLOTH_MATERIAL_H +#define PX_FEM_CLOTH_MATERIAL_H +/** \addtogroup physics +@{ +*/ + +#include "PxFEMMaterial.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + /** + \brief Material class to represent a set of FEM material properties. + + @see PxPhysics.createFEMClothMaterial + */ + class PxFEMClothMaterial : public PxFEMMaterial + { + public: + + /** + \brief Sets material thickness + + \param[in] thickness Material thickness. + + @see getThickness + */ + virtual void setThickness(PxReal thickness) = 0; + + /** + \brief Retrieves the material thickness. + \return thickness. + + @see setDamping() + */ + virtual PxReal getThickness() const = 0; + + /** + \brief Sets the elasticity damping for the internal cloth solver. + + \param[in] damping The elasticity damping term. Range: [0.0, Inf) + + @see getElasticityDamping() + */ + virtual void setElasticityDamping(PxReal damping) = 0; + + /** + \brief Retrieves the elasticity damping term. + \return The elasticity damping term. + + @see setElasticityDamping() + */ + virtual PxReal getElasticityDamping() const = 0; + + /** + \brief Sets the bending coefficient for bending constraints. + + \param[in] damping The bending coefficient. Range: [0.0, Inf) + + @see getBendingDamping() + */ + virtual void setBendingDamping(PxReal damping) = 0; + + /** + \brief Retrieves the bending coefficient for bending constraints. + \return The bending coefficient. + + @see setBendingDamping() + */ + virtual PxReal getBendingDamping() const = 0; + + virtual const char* getConcreteTypeName() const { return "PxFEMClothMaterial"; } + + protected: + PX_INLINE PxFEMClothMaterial(PxType concreteType, PxBaseFlags baseFlags) : PxFEMMaterial(concreteType, baseFlags) {} + PX_INLINE PxFEMClothMaterial(PxBaseFlags baseFlags) : PxFEMMaterial(baseFlags) {} + virtual ~PxFEMClothMaterial() {} + virtual bool isKindOf(const char* name) const { return !::strcmp("PxFEMClothMaterial", name) || PxRefCounted::isKindOf(name); } + }; + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/PxFEMMaterial.h b/Source/ThirdParty/PhysX/PxFEMMaterial.h new file mode 100644 index 000000000..1a8142097 --- /dev/null +++ b/Source/ThirdParty/PhysX/PxFEMMaterial.h @@ -0,0 +1,118 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_FEM_MATERIAL_H +#define PX_FEM_MATERIAL_H +/** \addtogroup physics +@{ +*/ + +#include "PxPhysXConfig.h" +#include "PxBaseMaterial.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + class PxScene; + + /** + \brief Material class to represent a set of FEM material properties. + + @see PxPhysics.createFEMSoftBodyMaterial + */ + class PxFEMMaterial : public PxBaseMaterial + { + public: + + /** + \brief Sets young's modulus which defines the body's stiffness + + \param[in] young Young's modulus. Range: [0, PX_MAX_F32) + + @see getYoungsModulus() + */ + virtual void setYoungsModulus(PxReal young) = 0; + + /** + \brief Retrieves the young's modulus value. + + \return The young's modulus value. + + @see setYoungsModulus() + */ + virtual PxReal getYoungsModulus() const = 0; + + /** + \brief Sets the Poisson's ratio which defines the body's volume preservation. Completely incompressible materials have a poisson ratio of 0.5. Its value should not be set to exactly 0.5 because this leads to numerical problems. + + \param[in] poisson Poisson's ratio. Range: [0, 0.5) + + @see getPoissons() + */ + virtual void setPoissons(PxReal poisson) = 0; + + /** + \brief Retrieves the Poisson's ratio. + \return The Poisson's ratio. + + @see setPoissons() + */ + virtual PxReal getPoissons() const = 0; + + /** + \brief Sets the dynamic friction value which defines the strength of resistance when two objects slide relative to each other while in contact. + + \param[in] dynamicFriction The dynamic friction value. Range: [0, PX_MAX_F32) + + @see getDynamicFriction() + */ + virtual void setDynamicFriction(PxReal dynamicFriction) = 0; + + /** + \brief Retrieves the dynamic friction value + \return The dynamic friction value + + @see setDynamicFriction() + */ + virtual PxReal getDynamicFriction() const = 0; + + protected: + PX_INLINE PxFEMMaterial(PxType concreteType, PxBaseFlags baseFlags) : PxBaseMaterial(concreteType, baseFlags) {} + PX_INLINE PxFEMMaterial(PxBaseFlags baseFlags) : PxBaseMaterial(baseFlags) {} + virtual ~PxFEMMaterial() {} + virtual bool isKindOf(const char* name) const { return !::strcmp("PxFEMMaterial", name) || PxBaseMaterial::isKindOf(name); } + }; + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/PxFEMParameter.h b/Source/ThirdParty/PhysX/PxFEMParameter.h new file mode 100644 index 000000000..25fbafeb0 --- /dev/null +++ b/Source/ThirdParty/PhysX/PxFEMParameter.h @@ -0,0 +1,95 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + + +#ifndef PX_PHYSICS_FEM_PARAMETER_H +#define PX_PHYSICS_FEM_PARAMETER_H + +#include "foundation/PxSimpleTypes.h" + + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + /** + \brief Set of parameters to control the sleeping and collision behavior of FEM based objects + */ + struct PxFEMParameters + { + public: + /** + \brief Velocity damping value. After every timestep the velocity is reduced while the magnitude of the reduction depends on velocityDamping + Default: 0.05 + */ + PxReal velocityDamping; + /** + \brief Threshold that defines the maximal magnitude of the linear motion a fem body can move in one second before it becomes a candidate for sleeping + Default: 0.1 + */ + PxReal settlingThreshold; + /** + \brief Threshold that defines the maximal magnitude of the linear motion a fem body can move in one second such that it can go to sleep in the next frame + Default: 0.05 + */ + PxReal sleepThreshold; + /** + \brief Damping value that damps the motion of bodies that move slow enough to be candidates for sleeping (see settlingThreshold) + Default: 10 + */ + PxReal sleepDamping; + /** + \brief Penetration value that needs to get exceeded before contacts for self collision are generated. Will only have an effect if self collisions are enabled. + Default: 0.1 + */ + PxReal selfCollisionFilterDistance; + /** + \brief Stress threshold to deactivate collision contacts in case the tetrahedron's stress magnitude exceeds the threshold + Default: 0.9 + */ + PxReal selfCollisionStressTolerance; + +#ifndef __CUDACC__ + PxFEMParameters() + { + velocityDamping = 0.05f; + settlingThreshold = 0.1f; + sleepThreshold = 0.05f; + sleepDamping = 10.f; + selfCollisionFilterDistance = 0.1f; + selfCollisionStressTolerance = 0.9f; + } +#endif + }; + +#if !PX_DOXYGEN +} +#endif + +#endif diff --git a/Source/ThirdParty/PhysX/PxFEMSoftBodyMaterial.h b/Source/ThirdParty/PhysX/PxFEMSoftBodyMaterial.h new file mode 100644 index 000000000..ad856bffa --- /dev/null +++ b/Source/ThirdParty/PhysX/PxFEMSoftBodyMaterial.h @@ -0,0 +1,100 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_FEM_SOFT_BODY_MATERIAL_H +#define PX_FEM_SOFT_BODY_MATERIAL_H +/** \addtogroup physics +@{ +*/ + +#include "PxFEMMaterial.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + class PxScene; + /** + \brief Material class to represent a set of softbody FEM material properties. + + @see PxPhysics.createFEMSoftBodyMaterial + */ + class PxFEMSoftBodyMaterial : public PxFEMMaterial + { + public: + + /** + \brief Sets material velocity damping term + + \param[in] damping Material velocity damping term. Range: [0, PX_MAX_F32)
+ + @see getDamping + */ + virtual void setDamping(PxReal damping) = 0; + + /** + \brief Retrieves velocity damping + \return The velocity damping. + + @see setDamping() + */ + virtual PxReal getDamping() const = 0; + + /** + \brief Sets material damping scale. A scale of 1 corresponds to default damping, a value of 0 will only apply damping to certain motions leading to special effects that look similar to water filled softbodies. + + \param[in] scale Damping scale term. Default: 1 Range: [0, 1] + + @see getDampingScale + */ + virtual void setDampingScale(PxReal scale) = 0; + + /** + \brief Retrieves material damping scale. + \return The damping scale term. + + @see setDamping() + */ + virtual PxReal getDampingScale() const = 0; + + virtual const char* getConcreteTypeName() const { return "PxFEMSoftBodyMaterial"; } + + protected: + PX_INLINE PxFEMSoftBodyMaterial(PxType concreteType, PxBaseFlags baseFlags) : PxFEMMaterial(concreteType, baseFlags) {} + PX_INLINE PxFEMSoftBodyMaterial(PxBaseFlags baseFlags) : PxFEMMaterial(baseFlags) {} + virtual ~PxFEMSoftBodyMaterial() {} + virtual bool isKindOf(const char* name) const { return !::strcmp("PxFEMSoftBodyMaterial", name) || PxFEMMaterial::isKindOf(name); } + }; + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/PxFLIPMaterial.h b/Source/ThirdParty/PhysX/PxFLIPMaterial.h new file mode 100644 index 000000000..b27d505a7 --- /dev/null +++ b/Source/ThirdParty/PhysX/PxFLIPMaterial.h @@ -0,0 +1,83 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_FLIP_MATERIAL_H +#define PX_FLIP_MATERIAL_H +/** \addtogroup physics +@{ +*/ + +#include "PxParticleMaterial.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + class PxScene; + /** + \brief Material class to represent a set of FLIP particle material properties. + + @see #PxPhysics.createFLIPMaterial() + */ + class PxFLIPMaterial : public PxParticleMaterial + { + public: + /** + \brief Sets viscosity + + \param[in] viscosity Viscosity. Range: [0, PX_MAX_F32) + + @see #getViscosity() + */ + virtual void setViscosity(PxReal viscosity) = 0; + + /** + \brief Retrieves the viscosity value. + + \return The viscosity value. + + @see #setViscosity() + */ + virtual PxReal getViscosity() const = 0; + + virtual const char* getConcreteTypeName() const { return "PxFLIPMaterial"; } + + protected: + PX_INLINE PxFLIPMaterial(PxType concreteType, PxBaseFlags baseFlags) : PxParticleMaterial(concreteType, baseFlags) {} + PX_INLINE PxFLIPMaterial(PxBaseFlags baseFlags) : PxParticleMaterial(baseFlags) {} + virtual ~PxFLIPMaterial() {} + virtual bool isKindOf(const char* name) const { return !::strcmp("PxFLIPMaterial", name) || PxParticleMaterial::isKindOf(name); } + }; + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/PxFiltering.h b/Source/ThirdParty/PhysX/PxFiltering.h index 91105ca90..16f54e8c5 100644 --- a/Source/ThirdParty/PhysX/PxFiltering.h +++ b/Source/ThirdParty/PhysX/PxFiltering.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_NX_FILTERING -#define PX_PHYSICS_NX_FILTERING +#ifndef PX_FILTERING_H +#define PX_FILTERING_H /** \addtogroup physics @{ */ @@ -459,14 +457,40 @@ struct PxFilterObjectType /** \brief An articulation - @see PxArticulation + @see PxArticulationReducedCoordinate */ eARTICULATION, - //brief internal use only! + /** + \brief A particle system + @see PxParticleSystem + */ + ePARTICLESYSTEM, + + /** + \brief A FEM-based soft body + @see PxSoftBody + */ + eSOFTBODY, + + /** + \brief A FEM-based cloth + \note In development + @see PxFEMCloth + */ + eFEMCLOTH, + + /** + \brief A hair system + \note In development + @see PxHairSystem + */ + eHAIRSYSTEM, + + //! \brief internal use only! eMAX_TYPE_COUNT = 16, - //brief internal use only! + //! \brief internal use only! eUNDEFINED = eMAX_TYPE_COUNT-1 }; }; @@ -532,26 +556,18 @@ PX_INLINE bool PxFilterObjectIsTrigger(PxFilterObjectAttributes attr) return (attr & PxFilterObjectFlag::eTRIGGER) != 0; } - /** -\brief Filter shader to specify handling of collision pairs. +\brief Filter method to specify how a pair of potentially colliding objects should be processed. Collision filtering is a mechanism to specify how a pair of potentially colliding objects should be processed by the simulation. A pair of objects is potentially colliding if the bounding volumes of the two objects overlap. In short, a collision filter decides whether a collision pair should get processed, temporarily ignored or discarded. If a collision pair should get processed, the filter can additionally specify how it should get processed, for instance, whether contacts should get resolved, which callbacks should get invoked or which reports should be sent etc. +The function returns the PxFilterFlag flags and sets the PxPairFlag flags to define what the simulation should do with the given collision pair. \note A default implementation of a filter shader is provided in the PhysX extensions library, see #PxDefaultSimulationFilterShader. -@see PxSceneDesc.filterShader PxSimulationFilterCallback -*/ - -/** -\brief Filter method to specify how a pair of potentially colliding objects should be processed. - -Return the PxFilterFlag flags and set the PxPairFlag flags to define what the simulation should do with the given collision pair. - This methods gets called when: \li The bounding volumes of two objects start to overlap. \li The bounding volumes of two objects overlap and the filter data or filter attributes of one of the objects changed @@ -582,9 +598,8 @@ logic to filter a collision pair then use the filter callback mechanism for this \return Filter flags defining whether the pair should be discarded, temporarily ignored, processed and whether the filter callback should get invoked for this pair. -@see PxSimulationFilterCallback PxFilterData PxFilterObjectAttributes PxFilterFlag PxFilterFlags PxPairFlag PxPairFlags +@see PxSimulationFilterCallback PxFilterData PxFilterObjectAttributes PxFilterFlag PxFilterFlags PxPairFlag PxPairFlags PxSceneDesc.filterShader */ - typedef PxFilterFlags (*PxSimulationFilterShader) (PxFilterObjectAttributes attributes0, PxFilterData filterData0, PxFilterObjectAttributes attributes1, PxFilterData filterData1, @@ -701,7 +716,7 @@ struct PxPairFilteringMode enum Enum { /** - Output pair from BP, potentially send to user callbacks, create regular interaction object. + \brief Output pair from BP, potentially send to user callbacks, create regular interaction object. Enable contact pair filtering between kinematic/static or kinematic/kinematic rigid bodies. @@ -713,22 +728,54 @@ struct PxPairFilteringMode eKEEP, /** - Output pair from BP, create interaction marker. Can be later switched to regular interaction. + \brief Output pair from BP, create interaction marker. Can be later switched to regular interaction. */ eSUPPRESS, /** - Don't output pair from BP. Cannot be later switched to regular interaction, needs "resetFiltering" call. + \brief Don't output pair from BP. Cannot be later switched to regular interaction, needs "resetFiltering" call. */ eKILL, /** - Default is eSUPPRESS for compatibility with previous PhysX versions. + \brief Default is eSUPPRESS for compatibility with previous PhysX versions. */ eDEFAULT = eSUPPRESS }; }; +/** +\brief Struct for storing a particle/vertex - rigid filter pair with comparison operators +*/ +struct PxParticleRigidFilterPair +{ + PxU64 mID0; //!< Rigid node index + PxU64 mID1; //!< Particle/vertex id + + PX_CUDA_CALLABLE bool operator<(const PxParticleRigidFilterPair& other) const + { + if(mID0 < other.mID0) + return true; + if(mID0 == other.mID0 && mID1 < other.mID1) + return true; + return false; + } + + PX_CUDA_CALLABLE bool operator>(const PxParticleRigidFilterPair& other) const + { + if(mID0 > other.mID0) + return true; + if(mID0 == other.mID0 && mID1 > other.mID1) + return true; + return false; + } + + PX_CUDA_CALLABLE bool operator==(const PxParticleRigidFilterPair& other) const + { + return (mID0 == other.mID0 && mID1 == other.mID1); + } +}; + #if !PX_DOXYGEN } // namespace physx diff --git a/Source/ThirdParty/PhysX/PxForceMode.h b/Source/ThirdParty/PhysX/PxForceMode.h index 9d425d54e..090136b8a 100644 --- a/Source/ThirdParty/PhysX/PxForceMode.h +++ b/Source/ThirdParty/PhysX/PxForceMode.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_NX_FORCE_MODE -#define PX_PHYSICS_NX_FORCE_MODE +#ifndef PX_FORCE_MODE_H +#define PX_FORCE_MODE_H #include "foundation/PxPreprocessor.h" @@ -51,10 +49,10 @@ struct PxForceMode { enum Enum { - eFORCE, //!< parameter has unit of mass * distance/ time^2, i.e. a force - eIMPULSE, //!< parameter has unit of mass * distance /time - eVELOCITY_CHANGE, //!< parameter has unit of distance / time, i.e. the effect is mass independent: a velocity change. - eACCELERATION //!< parameter has unit of distance/ time^2, i.e. an acceleration. It gets treated just like a force except the mass is not divided out before integration. + eFORCE, //!< parameter has unit of mass * length / time^2, i.e., a force + eIMPULSE, //!< parameter has unit of mass * length / time, i.e., force * time + eVELOCITY_CHANGE, //!< parameter has unit of length / time, i.e., the effect is mass independent: a velocity change. + eACCELERATION //!< parameter has unit of length/ time^2, i.e., an acceleration. It gets treated just like a force except the mass is not divided out before integration. }; }; diff --git a/Source/ThirdParty/PhysX/PxHairSystemFlag.h b/Source/ThirdParty/PhysX/PxHairSystemFlag.h new file mode 100644 index 000000000..06f6b3164 --- /dev/null +++ b/Source/ThirdParty/PhysX/PxHairSystemFlag.h @@ -0,0 +1,74 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_HAIR_SYSTEM_FLAG_H +#define PX_HAIR_SYSTEM_FLAG_H + +#include "PxPhysXConfig.h" +#include "foundation/PxFlags.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + /** + \brief Identifies input and output buffers for PxHairSystem + \see PxHairSystemData::readData(), PxHairSystemData::writeData(), PxBuffer + */ + struct PxHairSystemData + { + enum Enum + { + eNONE = 0, //!< No data specified + ePOSITION_INVMASS = 1 << 0, //!< Specifies the position (first 3 floats) and inverse mass (last float) data (array of PxVec4 * max number of vertices) + eVELOCITY = 1 << 1, //!< Specifies the velocity (first 3 floats) data (array of PxVec4 * max number of vertices) + eALL = ePOSITION_INVMASS | eVELOCITY //!< Specifies everything + }; + }; + typedef PxFlags PxHairSystemDataFlags; + + /** + \brief Binary settings for hair system simulation + */ + struct PxHairSystemFlag + { + enum Enum + { + eDISABLE_SELF_COLLISION = 1 << 0, //!< Determines if self-collision between hair vertices is ignored + eDISABLE_EXTERNAL_COLLISION = 1 << 1, //!< Determines if collision between hair and external bodies is ignored + eDISABLE_TWOSIDED_ATTACHMENT = 1 << 2 //!< Determines if attachment constraint is also felt by body to which the hair is attached + }; + }; + typedef PxFlags PxHairSystemFlags; + +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif diff --git a/Source/ThirdParty/PhysX/PxImmediateMode.h b/Source/ThirdParty/PhysX/PxImmediateMode.h index f58872308..e63debd91 100644 --- a/Source/ThirdParty/PhysX/PxImmediateMode.h +++ b/Source/ThirdParty/PhysX/PxImmediateMode.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,16 +22,17 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PX_PHYSICS_IMMEDIATE_MODE -#define PX_PHYSICS_IMMEDIATE_MODE +#ifndef PX_IMMEDIATE_MODE_H +#define PX_IMMEDIATE_MODE_H /** \addtogroup immediatemode @{ */ #include "PxPhysXConfig.h" +#include "foundation/PxMemory.h" #include "solver/PxSolverDefs.h" #include "collision/PxCollisionDefs.h" #include "PxArticulationReducedCoordinate.h" @@ -42,11 +42,28 @@ namespace physx { #endif + class PxCudaContextManager; + class PxBaseTask; + class PxGeometry; + #if !PX_DOXYGEN namespace immediate { #endif + typedef void* PxArticulationHandle; + + /** + \brief Structure to store linear and angular components of spatial vector + */ + struct PxSpatialVector + { + PxVec3 top; + PxReal pad0; + PxVec3 bottom; + PxReal pad1; + }; + /** \brief Structure to store rigid body properties */ @@ -79,7 +96,7 @@ namespace immediate \param [in] index The index of this pair. This is an index from 0-N-1 identifying which pair this relates to from within the array of pairs passed to PxGenerateContacts \return a boolean to indicate if this callback successfully stored the contacts or not. */ - virtual bool recordContacts(const Gu::ContactPoint* contactPoints, const PxU32 nbContacts, const PxU32 index) = 0; + virtual bool recordContacts(const PxContactPoint* contactPoints, const PxU32 nbContacts, const PxU32 index) = 0; virtual ~PxContactRecorder(){} }; @@ -87,12 +104,13 @@ namespace immediate /** \brief Constructs a PxSolverBodyData structure based on rigid body properties. Applies gravity, damping and clamps maximum velocity. \param [in] inRigidData The array rigid body properties - \param [out] outSolverBodyData The array of solverBodyData produced to repreent these bodies + \param [out] outSolverBodyData The array of solverBodyData produced to represent these bodies \param [in] nbBodies The total number of solver bodies to create \param [in] gravity The gravity vector \param [in] dt The timestep + \param [in] gyroscopicForces Indicates whether gyroscopic forces should be integrated */ - PX_C_EXPORT PX_PHYSX_CORE_API void PxConstructSolverBodies(const PxRigidBodyData* inRigidData, PxSolverBodyData* outSolverBodyData, const PxU32 nbBodies, const PxVec3& gravity, const PxReal dt); + PX_C_EXPORT PX_PHYSX_CORE_API void PxConstructSolverBodies(const PxRigidBodyData* inRigidData, PxSolverBodyData* outSolverBodyData, PxU32 nbBodies, const PxVec3& gravity, PxReal dt, bool gyroscopicForces = false); /** \brief Constructs a PxSolverBodyData structure for a static body at a given pose. @@ -118,9 +136,9 @@ namespace immediate infinite mass (static or kinematic). This means that either appending static/kinematic to the end of the array of bodies or placing static/kinematic bodies at before the start body pointer will ensure that the minimum number of batches are produced. */ - PX_C_EXPORT PX_PHYSX_CORE_API PxU32 PxBatchConstraints( const PxSolverConstraintDesc* solverConstraintDescs, const PxU32 nbConstraints, PxSolverBody* solverBodies, const PxU32 nbBodies, + PX_C_EXPORT PX_PHYSX_CORE_API PxU32 PxBatchConstraints( const PxSolverConstraintDesc* solverConstraintDescs, PxU32 nbConstraints, PxSolverBody* solverBodies, PxU32 nbBodies, PxConstraintBatchHeader* outBatchHeaders, PxSolverConstraintDesc* outOrderedConstraintDescs, - Dy::ArticulationV** articulations=NULL, const PxU32 nbArticulations=0); + PxArticulationHandle* articulations=NULL, PxU32 nbArticulations=0); /** \brief Creates a set of contact constraint blocks. Note that, depending the results of PxBatchConstraints, each batchHeader may refer to up to 4 solverConstraintDescs. @@ -136,56 +154,62 @@ namespace immediate then these pairs will always be solved by bias. \param [in] frictionOffsetThreshold The friction offset threshold. Contacts whose separations are below this threshold can generate friction constraints. \param [in] correlationDistance The correlation distance used by friction correlation to identify whether a friction patch is broken on the grounds of relation separation. + \param [out] Z Temporary buffer for impulse propagation. \return a boolean to define if this method was successful or not. */ - PX_C_EXPORT PX_PHYSX_CORE_API bool PxCreateContactConstraints(PxConstraintBatchHeader* batchHeaders, const PxU32 nbHeaders, PxSolverContactDesc* contactDescs, - PxConstraintAllocator& allocator, const PxReal invDt, const PxReal bounceThreshold, const PxReal frictionOffsetThreshold, const PxReal correlationDistance); + PX_C_EXPORT PX_PHYSX_CORE_API bool PxCreateContactConstraints(PxConstraintBatchHeader* batchHeaders, PxU32 nbHeaders, PxSolverContactDesc* contactDescs, + PxConstraintAllocator& allocator, PxReal invDt, PxReal bounceThreshold, PxReal frictionOffsetThreshold, PxReal correlationDistance, + PxSpatialVector* Z = NULL); /** \brief Creates a set of joint constraint blocks. Note that, depending the results of PxBatchConstraints, the batchHeader may refer to up to 4 solverConstraintDescs - \param [in] batchHeaders The array of batch headers to be processed - \param [in] nbHeaders The total number of batch headers to process - \param [in] jointDescs An array of constraint prep descs defining the properties of the constraints being created - \param [in] allocator An allocator callback to allocate constraint data - \param [in] dt The timestep - \param [in] invDt The inverse timestep + \param [in] batchHeaders The array of batch headers to be processed. + \param [in] nbHeaders The total number of batch headers to process. + \param [in] jointDescs An array of constraint prep descs defining the properties of the constraints being created. + \param [in] allocator An allocator callback to allocate constraint data. + \param [in] dt The timestep. + \param [in] invDt The inverse timestep. + \param [out] Z Temporary buffer for impulse propagation. \return a boolean indicating if this method was successful or not. */ - PX_C_EXPORT PX_PHYSX_CORE_API bool PxCreateJointConstraints(PxConstraintBatchHeader* batchHeaders, const PxU32 nbHeaders, PxSolverConstraintPrepDesc* jointDescs, PxConstraintAllocator& allocator, const PxReal dt, const PxReal invDt); + PX_C_EXPORT PX_PHYSX_CORE_API bool PxCreateJointConstraints(PxConstraintBatchHeader* batchHeaders, PxU32 nbHeaders, PxSolverConstraintPrepDesc* jointDescs, PxConstraintAllocator& allocator, PxSpatialVector* Z, PxReal dt, PxReal invDt); /** \brief Creates a set of joint constraint blocks. This function runs joint shaders defined inside PxConstraint** param, fills in joint row information in jointDescs and then calls PxCreateJointConstraints. - \param [in] batchHeaders The set of batchHeaders to be processed + \param [in] batchHeaders The set of batchHeaders to be processed. \param [in] nbBatchHeaders The number of batch headers to process. - \param [in] constraints The set of constraints to be used to produce constraint rows - \param [in,out] jointDescs An array of constraint prep descs defining the properties of the constraints being created - \param [in] allocator An allocator callback to allocate constraint data - \param [in] dt The timestep - \param [in] invDt The inverse timestep + \param [in] constraints The set of constraints to be used to produce constraint rows. + \param [in,out] jointDescs An array of constraint prep descs defining the properties of the constraints being created. + \param [in] allocator An allocator callback to allocate constraint data. + \param [in] dt The timestep. + \param [in] invDt The inverse timestep. + \param [out] Z Temporary buffer for impulse propagation. \return a boolean indicating if this method was successful or not. @see PxCreateJointConstraints */ - PX_C_EXPORT PX_PHYSX_CORE_API bool PxCreateJointConstraintsWithShaders(PxConstraintBatchHeader* batchHeaders, const PxU32 nbBatchHeaders, PxConstraint** constraints, PxSolverConstraintPrepDesc* jointDescs, PxConstraintAllocator& allocator, const PxReal dt, const PxReal invDt); + PX_C_EXPORT PX_PHYSX_CORE_API bool PxCreateJointConstraintsWithShaders(PxConstraintBatchHeader* batchHeaders, PxU32 nbBatchHeaders, PxConstraint** constraints, PxSolverConstraintPrepDesc* jointDescs, PxConstraintAllocator& allocator, PxReal dt, PxReal invDt, PxSpatialVector* Z = NULL); struct PxImmediateConstraint { PxConstraintSolverPrep prep; const void* constantBlock; }; + /** \brief Creates a set of joint constraint blocks. This function runs joint shaders defined inside PxImmediateConstraint* param, fills in joint row information in jointDescs and then calls PxCreateJointConstraints. - \param [in] batchHeaders The set of batchHeaders to be processed + \param [in] batchHeaders The set of batchHeaders to be processed. \param [in] nbBatchHeaders The number of batch headers to process. - \param [in] constraints The set of constraints to be used to produce constraint rows - \param [in,out] jointDescs An array of constraint prep descs defining the properties of the constraints being created - \param [in] allocator An allocator callback to allocate constraint data - \param [in] dt The timestep - \param [in] invDt The inverse timestep + \param [in] constraints The set of constraints to be used to produce constraint rows. + \param [in,out] jointDescs An array of constraint prep descs defining the properties of the constraints being created. + \param [in] allocator An allocator callback to allocate constraint data. + \param [in] dt The timestep. + \param [in] invDt The inverse timestep. + \param [out] Z Temporary buffer for impulse propagation. \return a boolean indicating if this method was successful or not. @see PxCreateJointConstraints */ - PX_C_EXPORT PX_PHYSX_CORE_API bool PxCreateJointConstraintsWithImmediateShaders(PxConstraintBatchHeader* batchHeaders, const PxU32 nbBatchHeaders, PxImmediateConstraint* constraints, PxSolverConstraintPrepDesc* jointDescs, PxConstraintAllocator& allocator, const PxReal dt, const PxReal invDt); + PX_C_EXPORT PX_PHYSX_CORE_API bool PxCreateJointConstraintsWithImmediateShaders(PxConstraintBatchHeader* batchHeaders, PxU32 nbBatchHeaders, PxImmediateConstraint* constraints, PxSolverConstraintPrepDesc* jointDescs, PxConstraintAllocator& allocator, PxReal dt, PxReal invDt, PxSpatialVector* Z = NULL); /** \brief Iteratively solves the set of constraints defined by the provided PxConstraintBatchHeader and PxSolverConstraintDesc structures. Updates deltaVelocities inside the PxSolverBody structures. Produces resulting linear and angular motion velocities. @@ -202,10 +226,12 @@ namespace immediate \param [in] invDt Inverse timestep. Only needed if articulations are sent to the function. \param [in] nbSolverArticulations Number of articulations to solve constraints for. \param [in] solverArticulations Array of articulations to solve constraints for. + \param [out] Z Temporary buffer for impulse propagation + \param [out] deltaV Temporary buffer for velocity change */ - PX_C_EXPORT PX_PHYSX_CORE_API void PxSolveConstraints(const PxConstraintBatchHeader* batchHeaders, const PxU32 nbBatchHeaders, const PxSolverConstraintDesc* solverConstraintDescs, - const PxSolverBody* solverBodies, PxVec3* linearMotionVelocity, PxVec3* angularMotionVelocity, const PxU32 nbSolverBodies, const PxU32 nbPositionIterations, const PxU32 nbVelocityIterations, - const float dt=0.0f, const float invDt=0.0f, const PxU32 nbSolverArticulations=0, Dy::ArticulationV** solverArticulations=NULL); + PX_C_EXPORT PX_PHYSX_CORE_API void PxSolveConstraints(const PxConstraintBatchHeader* batchHeaders, PxU32 nbBatchHeaders, const PxSolverConstraintDesc* solverConstraintDescs, + const PxSolverBody* solverBodies, PxVec3* linearMotionVelocity, PxVec3* angularMotionVelocity, PxU32 nbSolverBodies, PxU32 nbPositionIterations, PxU32 nbVelocityIterations, + float dt=0.0f, float invDt=0.0f, PxU32 nbSolverArticulations=0, PxArticulationHandle* solverArticulations=NULL, PxSpatialVector* Z = NULL, PxSpatialVector* deltaV = NULL); /** \brief Integrates a rigid body, returning the new velocities and transforms. After this function has been called, solverBodyData stores all the body's velocity data. @@ -217,10 +243,10 @@ namespace immediate \param [in] nbBodiesToIntegrate The total number of bodies to integrate \param [in] dt The timestep */ - PX_C_EXPORT PX_PHYSX_CORE_API void PxIntegrateSolverBodies(PxSolverBodyData* solverBodyData, PxSolverBody* solverBody, const PxVec3* linearMotionVelocity, const PxVec3* angularMotionState, const PxU32 nbBodiesToIntegrate, const PxReal dt); + PX_C_EXPORT PX_PHYSX_CORE_API void PxIntegrateSolverBodies(PxSolverBodyData* solverBodyData, PxSolverBody* solverBody, const PxVec3* linearMotionVelocity, const PxVec3* angularMotionState, PxU32 nbBodiesToIntegrate, PxReal dt); /** - \brief Performs contact generation for a given pair of geometries at the specified poses. Produced contacts are stored in the provided Gu::ContactBuffer. Information is cached in PxCache structure + \brief Performs contact generation for a given pair of geometries at the specified poses. Produced contacts are stored in the provided contact recorder. Information is cached in PxCache structure to accelerate future contact generation between pairs. This cache data is valid only as long as the memory provided by PxCacheAllocator has not been released/re-used. Recommendation is to retain that data for a single simulation frame, discarding cached data after 2 frames. If the cached memory has been released/re-used prior to the corresponding pair having contact generation performed again, it is the application's responsibility to reset the PxCache. @@ -231,7 +257,7 @@ namespace immediate \param [in] pose1 Array of poses associated with the corresponding entry in the geom1 array \param [in,out] contactCache Array of contact caches associated with each pair geom0[i] + geom1[i] \param [in] nbPairs The total number of pairs to process - \param [in] contactRecorder A callback that is called to record contacts for each pair that detects contacts + \param [out] contactRecorder A callback that is called to record contacts for each pair that detects contacts \param [in] contactDistance The distance at which contacts begin to be generated between the pairs \param [in] meshContactMargin The mesh contact margin. \param [in] toleranceLength The toleranceLength. Used for scaling distance-based thresholds internally to produce appropriate results given simulations in different units @@ -239,8 +265,9 @@ namespace immediate \return a boolean indicating if the function was successful or not. */ - PX_C_EXPORT PX_PHYSX_CORE_API bool PxGenerateContacts(const PxGeometry* const * geom0, const PxGeometry* const * geom1, const PxTransform* pose0, const PxTransform* pose1, PxCache* contactCache, const PxU32 nbPairs, PxContactRecorder& contactRecorder, - const PxReal contactDistance, const PxReal meshContactMargin, const PxReal toleranceLength, PxCacheAllocator& allocator); + PX_C_EXPORT PX_PHYSX_CORE_API bool PxGenerateContacts( const PxGeometry* const * geom0, const PxGeometry* const * geom1, const PxTransform* pose0, const PxTransform* pose1, + PxCache* contactCache, PxU32 nbPairs, PxContactRecorder& contactRecorder, + PxReal contactDistance, PxReal meshContactMargin, PxReal toleranceLength, PxCacheAllocator& allocator); /** \brief Register articulation-related solver functions. This is equivalent to PxRegisterArticulationsReducedCoordinate() for PxScene-level articulations. @@ -250,30 +277,50 @@ namespace immediate */ PX_C_EXPORT PX_PHYSX_CORE_API void PxRegisterImmediateArticulations(); - struct PxArticulationJointData + struct PxArticulationJointDataRC { - PxTransform parentPose; - PxTransform childPose; - }; - - struct PxFeatherstoneArticulationJointData : PxArticulationJointData - { - PxArticulationJointType::Enum type; + PxTransform parentPose; + PxTransform childPose; PxArticulationMotion::Enum motion[PxArticulationAxis::eCOUNT]; PxArticulationLimit limits[PxArticulationAxis::eCOUNT]; PxArticulationDrive drives[PxArticulationAxis::eCOUNT]; PxReal targetPos[PxArticulationAxis::eCOUNT]; PxReal targetVel[PxArticulationAxis::eCOUNT]; + PxReal armature[PxArticulationAxis::eCOUNT]; + PxReal jointPos[PxArticulationAxis::eCOUNT]; + PxReal jointVel[PxArticulationAxis::eCOUNT]; PxReal frictionCoefficient; PxReal maxJointVelocity; + PxArticulationJointType::Enum type; + + void initData() + { + parentPose = PxTransform(PxIdentity); + childPose = PxTransform(PxIdentity); + frictionCoefficient = 0.05f; + maxJointVelocity = 100.0f; + type = PxArticulationJointType::eUNDEFINED; // For root + + for(PxU32 i=0;i PxMPMCuttingFlags; + PX_FLAGS_OPERATORS(PxMPMCuttingFlag::Enum,PxU16) + + class PxScene; + + /** + \brief Material class to represent a set of MPM particle material properties. + + @see PxPhysics.createMPMMaterial + */ + class PxMPMMaterial : public PxParticleMaterial + { + public: + /** + \brief Sets stretch and shear damping which dampens stretch and shear motion of MPM bodies. The effect is comparable to viscosity for fluids. + + \param[in] stretchAndShearDamping The stretch and shear damping + + @see getStretchAndShearDamping() + */ + virtual void setStretchAndShearDamping(PxReal stretchAndShearDamping) = 0; + + /** + \brief Retrieves the stretch and shear damping. + + \return The stretch and shear damping + + @see setStretchAndShearDamping() + */ + virtual PxReal getStretchAndShearDamping() const = 0; + + + /** + \brief Sets the rotational damping which dampens rotations of mpm bodies + + \param[in] rotationalDamping The rotational damping + + @see getRotationalDamping() + */ + virtual void setRotationalDamping(PxReal rotationalDamping) = 0; + + /** + \brief Retrieves the rotational damping. + + \return The rotational damping + + @see setRotationalDamping() + */ + virtual PxReal getRotationalDamping() const = 0; + + + /** + \brief Sets density which influences the body's weight + + \param[in] density The material's density + + @see getDensity() + */ + virtual void setDensity(PxReal density) = 0; + + /** + \brief Retrieves the density value. + + \return The density + + @see setDensity() + */ + virtual PxReal getDensity() const = 0; + + + /** + \brief Sets the material model which influences interaction between MPM particles + + \param[in] materialModel The material model + + @see getMaterialModel() + */ + virtual void setMaterialModel(PxMPMMaterialModel::Enum materialModel) = 0; + + /** + \brief Retrieves the material model. + + \return The material model + + @see setMaterialModel() + */ + virtual PxMPMMaterialModel::Enum getMaterialModel() const = 0; + + + /** + \brief Sets the cutting flags which can enable damage tracking or thin blade support + + \param[in] cuttingFlags The cutting flags + + @see getCuttingFlags() + */ + virtual void setCuttingFlags(PxMPMCuttingFlags cuttingFlags) = 0; + + /** + \brief Retrieves the cutting flags. + + \return The cutting flags + + @see setCuttingFlags() + */ + virtual PxMPMCuttingFlags getCuttingFlags() const = 0; + + + /** + \brief Sets the sand friction angle, only applied if the material model is set to sand + + \param[in] sandFrictionAngle The sand friction angle + + @see getSandFrictionAngle() + */ + virtual void setSandFrictionAngle(PxReal sandFrictionAngle) = 0; + + /** + \brief Retrieves the sand friction angle. + + \return The sand friction angle + + @see setSandFrictionAngle() + */ + virtual PxReal getSandFrictionAngle() const = 0; + + + /** + \brief Sets the yield stress, only applied if the material model is set to Von Mises + + \param[in] yieldStress The yield stress + + @see getYieldStress() + */ + virtual void setYieldStress(PxReal yieldStress) = 0; + + + /** + \brief Retrieves the yield stress. + + \return The yield stress + + @see setYieldStress() + */ + virtual PxReal getYieldStress() const = 0; + + + /** + \brief Set material to plastic + + \param[in] isPlastic True if plastic + + @see getIsPlastic() + */ + virtual void setIsPlastic(bool isPlastic) = 0; + + /** + \brief Returns true if material is plastic + + \return True if plastic + + @see setIsPlastic() + */ + virtual bool getIsPlastic() const = 0; + + /** + \brief Sets Young's modulus which defines the body's stiffness + + \param[in] young Young's modulus. Range: [0, PX_MAX_F32) + + @see getYoungsModulus() + */ + virtual void setYoungsModulus(PxReal young) = 0; + + /** + \brief Retrieves the Young's modulus value. + + \return The Young's modulus value. + + @see setYoungsModulus() + */ + virtual PxReal getYoungsModulus() const = 0; + + /** + \brief Sets Poisson's ratio defines the body's volume preservation. Completely incompressible materials have a Poisson ratio of 0.5 which will lead to numerical problems. + + \param[in] poisson Poisson's ratio. Range: [0, 0.5) + + @see getPoissons() + */ + virtual void setPoissons(PxReal poisson) = 0; + + /** + \brief Retrieves the Poisson's ratio. + \return The Poisson's ratio. + + @see setPoissons() + */ + virtual PxReal getPoissons() const = 0; + + /** + \brief Sets material hardening coefficient + + Tendency to get more rigid under compression. Range: [0, PX_MAX_F32) + + \param[in] hardening Material hardening coefficient. + + @see getHardening + */ + virtual void setHardening(PxReal hardening) = 0; + + /** + \brief Retrieves the hardening coefficient. + + \return The hardening coefficient. + + @see setHardening() + */ + virtual PxReal getHardening() const = 0; + + /** + \brief Sets material critical compression coefficient + + Compression clamping threshold (higher means more compression is allowed before yield). Range: [0, 1) + + \param[in] criticalCompression Material critical compression coefficient. + + @see getCriticalCompression + */ + virtual void setCriticalCompression(PxReal criticalCompression) = 0; + + /** + \brief Retrieves the critical compression coefficient. + + \return The criticalCompression coefficient. + + @see setCriticalCompression() + */ + virtual PxReal getCriticalCompression() const = 0; + + /** + \brief Sets material critical stretch coefficient + + Stretch clamping threshold (higher means more stretching is allowed before yield). Range: [0, 1] + + \param[in] criticalStretch Material critical stretch coefficient. + + @see getCriticalStretch + */ + virtual void setCriticalStretch(PxReal criticalStretch) = 0; + + /** + \brief Retrieves the critical stretch coefficient. + + \return The criticalStretch coefficient. + + @see setCriticalStretch() + */ + virtual PxReal getCriticalStretch() const = 0; + + /** + \brief Sets material tensile damage sensitivity coefficient + + Sensitivity to tensile loads. The higher the sensitivity, the quicker damage will occur under tensile loads. Range: [0, PX_MAX_U32) + + \param[in] tensileDamageSensitivity Material tensile damage sensitivity coefficient. + + @see getTensileDamageSensitivity + */ + virtual void setTensileDamageSensitivity(PxReal tensileDamageSensitivity) = 0; + + /** + \brief Retrieves the tensile damage sensitivity coefficient. + + \return The tensileDamageSensitivity coefficient. + + @see setTensileDamageSensitivity() + */ + virtual PxReal getTensileDamageSensitivity() const = 0; + + /** + \brief Sets material compressive damage sensitivity coefficient + + Sensitivity to compressive loads. The higher the sensitivity, the quicker damage will occur under compressive loads Range: [0, PX_MAX_U32) + + \param[in] compressiveDamageSensitivity Material compressive damage sensitivity coefficient. + + @see getCompressiveDamageSensitivity + */ + virtual void setCompressiveDamageSensitivity(PxReal compressiveDamageSensitivity) = 0; + + /** + \brief Retrieves the compressive damage sensitivity coefficient. + + \return The compressiveDamageSensitivity coefficient. + + @see setCompressiveDamageSensitivity() + */ + virtual PxReal getCompressiveDamageSensitivity() const = 0; + + /** + \brief Sets material attractive force residual coefficient + + Relative amount of attractive force a fully damaged particle can exert on other particles compared to an undamaged one. Range: [0, 1] + + \param[in] attractiveForceResidual Material attractive force residual coefficient. + + @see getAttractiveForceResidual + */ + virtual void setAttractiveForceResidual(PxReal attractiveForceResidual) = 0; + + /** + \brief Retrieves the attractive force residual coefficient. + \return The attractiveForceResidual coefficient. + + @see setAttractiveForceResidual() + */ + virtual PxReal getAttractiveForceResidual() const = 0; + + virtual const char* getConcreteTypeName() const { return "PxMPMMaterial"; } + + protected: + PX_INLINE PxMPMMaterial(PxType concreteType, PxBaseFlags baseFlags) : PxParticleMaterial(concreteType, baseFlags) {} + PX_INLINE PxMPMMaterial(PxBaseFlags baseFlags) : PxParticleMaterial(baseFlags) {} + virtual ~PxMPMMaterial() {} + virtual bool isKindOf(const char* name) const { return !::strcmp("PxMPMMaterial", name) || PxParticleMaterial::isKindOf(name); } + }; + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/PxMaterial.h b/Source/ThirdParty/PhysX/PxMaterial.h index d6f8685d9..f862dd841 100644 --- a/Source/ThirdParty/PhysX/PxMaterial.h +++ b/Source/ThirdParty/PhysX/PxMaterial.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,19 +22,17 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_NXMATERIAL -#define PX_PHYSICS_NXMATERIAL +#ifndef PX_MATERIAL_H +#define PX_MATERIAL_H /** \addtogroup physics @{ */ -#include "PxPhysXConfig.h" -#include "common/PxBase.h" +#include "PxBaseMaterial.h" #if !PX_DOXYGEN namespace physx @@ -55,11 +52,12 @@ struct PxMaterialFlag { /** - If this flag is set, friction computations are always skipped between shapes with this material and any other shape. + \brief If this flag is set, friction computations are always skipped between shapes with this material and any other shape. */ eDISABLE_FRICTION = 1 << 0, /** + \brief Whether to use strong friction. The difference between "normal" and "strong" friction is that the strong friction feature remembers the "friction error" between simulation steps. The friction is a force trying to hold objects in place (or slow them down) and this is handled in the solver. But since the @@ -71,7 +69,7 @@ struct PxMaterialFlag However, in some cases the strong friction could cause problems, and this is why it is possible to disable the strong friction feature by setting this flag. One example is - raycast vehicles, that are sliding fast across the surface, but still need a precise + raycast vehicles that are sliding fast across the surface, but still need a precise steering behavior. It may be a good idea to reenable the strong friction when objects are coming to a rest, to prevent them from slowly creeping down inclines. @@ -80,6 +78,7 @@ struct PxMaterialFlag eDISABLE_STRONG_FRICTION = 1 << 1, /** + \brief Whether to use the patch friction model. This flag only has an effect if PxFrictionType::ePATCH friction model is used. When using the patch friction model, up to 2 friction anchors are generated per patch. As the number of friction anchors @@ -88,9 +87,15 @@ struct PxMaterialFlag as analytical models suggest). This flag causes the normal force to be distributed between the friction anchors such that the total amount of friction applied does not - exceed the analyical results. + exceed the analytical results. */ - eIMPROVED_PATCH_FRICTION = 1 << 2 + eIMPROVED_PATCH_FRICTION = 1 << 2, + + /** + \brief This flag has the effect of enabling an implicit spring model for the normal force computation. + @see PxMaterial.setRestitution, PxMaterial.setDamping + */ + eCOMPLIANT_CONTACT = 1 << 3 }; }; @@ -104,7 +109,7 @@ PX_FLAGS_OPERATORS(PxMaterialFlag::Enum,PxU16) /** -\brief enumeration that determines the way in which two material properties will be combined to yield a friction or restitution coefficient for a collision. +\brief Enumeration that determines the way in which two material properties will be combined to yield a friction or restitution coefficient for a collision. When two actors come in contact with each other, they each have materials with various coefficients, but we only need a single set of coefficients for the pair. @@ -140,34 +145,10 @@ struct PxCombineMode @see PxPhysics.createMaterial */ -class PxMaterial : public PxBase +class PxMaterial : public PxBaseMaterial { public: - /** - \brief Decrements the reference count of a material and releases it if the new reference count is zero. - - @see PxPhysics.createMaterial() - */ - virtual void release() = 0; - - /** - \brief Returns the reference count of the material. - - At creation, the reference count of the material is 1. Every shape referencing this material increments the - count by 1. When the reference count reaches 0, and only then, the material gets destroyed automatically. - - \return the current reference count. - */ - virtual PxU32 getReferenceCount() const = 0; - - /** - \brief Acquires a counted reference to a material. - - This method increases the reference count of the material by 1. Decrement the reference count by calling release() - */ - virtual void acquireReference() = 0; - /** \brief Sets the coefficient of dynamic friction. @@ -179,7 +160,7 @@ public: @see getDynamicFriction() */ - virtual void setDynamicFriction(PxReal coef) = 0; + virtual void setDynamicFriction(PxReal coef) = 0; /** \brief Retrieves the DynamicFriction value. @@ -188,7 +169,7 @@ public: @see setDynamicFriction */ - virtual PxReal getDynamicFriction() const = 0; + virtual PxReal getDynamicFriction() const = 0; /** \brief Sets the coefficient of static friction @@ -201,7 +182,7 @@ public: @see getStaticFriction() */ - virtual void setStaticFriction(PxReal coef) = 0; + virtual void setStaticFriction(PxReal coef) = 0; /** \brief Retrieves the coefficient of static friction. @@ -209,20 +190,24 @@ public: @see setStaticFriction */ - virtual PxReal getStaticFriction() const = 0; + virtual PxReal getStaticFriction() const = 0; /** \brief Sets the coefficient of restitution A coefficient of 0 makes the object bounce as little as possible, higher values up to 1.0 result in more bounce. + This property is overloaded when PxMaterialFlag::eCOMPLIANT_CONTACT flag is enabled. This permits negative values for restitution to be provided. + The negative values are converted into spring stiffness terms for an implicit spring simulated at the contact site, with the spring positional error defined by + the contact separation value. Higher stiffness terms produce stiffer springs that behave more like a rigid contact. + Sleeping: Does NOT wake any actors which may be affected. - \param[in] rest Coefficient of restitution. Range: [0,1] + \param[in] rest Coefficient of restitution. Range: [-INF,1] @see getRestitution() */ - virtual void setRestitution(PxReal rest) = 0; + virtual void setRestitution(PxReal rest) = 0; /** \brief Retrieves the coefficient of restitution. @@ -233,31 +218,65 @@ public: @see setRestitution() */ - virtual PxReal getRestitution() const = 0; + virtual PxReal getRestitution() const = 0; + + + /** + \brief Sets the coefficient of damping + + This property only affects the simulation if PxMaterialFlag::eCOMPLIANT_CONTACT is raised. + Damping works together with spring stiffness (set through a negative restitution value). Spring stiffness corrects positional error while + damping resists relative velocity. Setting a high damping coefficient can produce spongy contacts. + + Sleeping: Does NOT wake any actors which may be affected. + + \param[in] damping Coefficient of damping. Range: [0,INF] + + @see getDamping() + */ + virtual void setDamping(PxReal damping) = 0; + + /** + \brief Retrieves the coefficient of damping. + + See #setDamping. + + \return The coefficient of damping. + + @see setDamping() + */ + virtual PxReal getDamping() const = 0; /** \brief Raises or clears a particular material flag. See the list of flags #PxMaterialFlag + Default: eIMPROVED_PATCH_FRICTION + Sleeping: Does NOT wake any actors which may be affected. - \param[in] flag The PxMaterial flag to raise(set) or clear. + \param[in] flag The PxMaterial flag to raise(set) or clear. + \param[in] b New state of the flag - @see getFlags() PxMaterialFlag + @see getFlags() setFlags() PxMaterialFlag */ - virtual void setFlag(PxMaterialFlag::Enum flag, bool) = 0; - + virtual void setFlag(PxMaterialFlag::Enum flag, bool b) = 0; /** \brief sets all the material flags. See the list of flags #PxMaterialFlag + Default: eIMPROVED_PATCH_FRICTION + Sleeping: Does NOT wake any actors which may be affected. + \param[in] flags All PxMaterial flags + + @see getFlags() setFlag() PxMaterialFlag */ - virtual void setFlags( PxMaterialFlags inFlags ) = 0; + virtual void setFlags(PxMaterialFlags flags) = 0; /** \brief Retrieves the flags. See #PxMaterialFlag. @@ -273,13 +292,15 @@ public: See the enum ::PxCombineMode . + Default: PxCombineMode::eAVERAGE + Sleeping: Does NOT wake any actors which may be affected. \param[in] combMode Friction combine mode to set for this material. See #PxCombineMode. @see PxCombineMode getFrictionCombineMode setStaticFriction() setDynamicFriction() */ - virtual void setFrictionCombineMode(PxCombineMode::Enum combMode) = 0; + virtual void setFrictionCombineMode(PxCombineMode::Enum combMode) = 0; /** \brief Retrieves the friction combine mode. @@ -297,13 +318,15 @@ public: See the enum ::PxCombineMode . + Default: PxCombineMode::eAVERAGE + Sleeping: Does NOT wake any actors which may be affected. \param[in] combMode Restitution combine mode for this material. See #PxCombineMode. @see PxCombineMode getRestitutionCombineMode() setRestitution() */ - virtual void setRestitutionCombineMode(PxCombineMode::Enum combMode) = 0; + virtual void setRestitutionCombineMode(PxCombineMode::Enum combMode) = 0; /** \brief Retrieves the restitution combine mode. @@ -316,17 +339,15 @@ public: */ virtual PxCombineMode::Enum getRestitutionCombineMode() const = 0; - //public variables: - void* userData; //!< user can assign this to whatever, usually to create a 1:1 relationship with a user object. - - virtual const char* getConcreteTypeName() const { return "PxMaterial"; } + // PxBase + virtual const char* getConcreteTypeName() const PX_OVERRIDE { return "PxMaterial"; } + //~PxBase protected: - PX_INLINE PxMaterial(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags), userData(NULL) {} - PX_INLINE PxMaterial(PxBaseFlags baseFlags) : PxBase(baseFlags) {} - virtual ~PxMaterial() {} - virtual bool isKindOf(const char* name) const { return !::strcmp("PxMaterial", name) || PxBase::isKindOf(name); } - + PX_INLINE PxMaterial(PxType concreteType, PxBaseFlags baseFlags) : PxBaseMaterial(concreteType, baseFlags) {} + PX_INLINE PxMaterial(PxBaseFlags baseFlags) : PxBaseMaterial(baseFlags) {} + virtual ~PxMaterial() {} + virtual bool isKindOf(const char* name) const { return !::strcmp("PxMaterial", name) || PxBaseMaterial::isKindOf(name); } }; #if !PX_DOXYGEN diff --git a/Source/ThirdParty/PhysX/PxNodeIndex.h b/Source/ThirdParty/PhysX/PxNodeIndex.h new file mode 100644 index 000000000..dda4d6b48 --- /dev/null +++ b/Source/ThirdParty/PhysX/PxNodeIndex.h @@ -0,0 +1,89 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_NODEINDEX_H +#define PX_NODEINDEX_H + +#include "foundation/PxSimpleTypes.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +#define PX_INVALID_NODE 0xFFFFFFFFu + + + /** + \brief PxNodeIndex + + Node index is the unique index for each actor referenced by the island gen. It contains details like + if the actor is an articulation or rigid body. If it is an articulation, the node index also contains + the link index of the rigid body within the articulation. Also, it contains information to detect whether + the rigid body is static body or not + */ + class PxNodeIndex + { + protected: + PxU64 ind; + + public: + + explicit PX_CUDA_CALLABLE PX_FORCE_INLINE PxNodeIndex(PxU32 id, PxU32 articLinkId) : ind((PxU64(id) << 32) | (articLinkId << 1) | 1) + { + } + + explicit PX_CUDA_CALLABLE PX_FORCE_INLINE PxNodeIndex(PxU32 id = PX_INVALID_NODE) : ind((PxU64(id) << 32)) + { + } + + PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 index() const { return PxU32(ind >> 32); } + PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 articulationLinkId() const { return PxU32((ind >> 1) & 0x7FFFFFFF); } + PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 isArticulation() const { return PxU32(ind & 1); } + + PX_CUDA_CALLABLE PX_FORCE_INLINE bool isStaticBody() const { return PxU32(ind >> 32) == PX_INVALID_NODE; } + + PX_CUDA_CALLABLE bool isValid() const { return PxU32(ind >> 32) != PX_INVALID_NODE; } + + PX_CUDA_CALLABLE void setIndices(PxU32 index, PxU32 articLinkId) { ind = ((PxU64(index) << 32) | (articLinkId << 1) | 1); } + + PX_CUDA_CALLABLE void setIndices(PxU32 index) { ind = ((PxU64(index) << 32)); } + + PX_CUDA_CALLABLE bool operator < (const PxNodeIndex& other) const { return ind < other.ind; } + + PX_CUDA_CALLABLE bool operator <= (const PxNodeIndex& other) const { return ind <= other.ind; } + + PX_CUDA_CALLABLE bool operator == (const PxNodeIndex& other) const { return ind == other.ind; } + + PX_CUDA_CALLABLE PxU64 getInd() const { return ind; } + }; +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif diff --git a/Source/ThirdParty/PhysX/PxPBDMaterial.h b/Source/ThirdParty/PhysX/PxPBDMaterial.h new file mode 100644 index 000000000..f58184368 --- /dev/null +++ b/Source/ThirdParty/PhysX/PxPBDMaterial.h @@ -0,0 +1,231 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_PBD_MATERIAL_H +#define PX_PBD_MATERIAL_H +/** \addtogroup physics +@{ +*/ + +#include "PxParticleMaterial.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + class PxScene; + /** + \brief Material class to represent a set of PBD particle material properties. + + @see #PxPhysics.createPBDMaterial + */ + class PxPBDMaterial : public PxParticleMaterial + { + public: + + /** + \brief Sets viscosity + + \param[in] viscosity Viscosity. Range: [0, PX_MAX_F32) + + @see #getViscosity() + */ + virtual void setViscosity(PxReal viscosity) = 0; + + /** + \brief Retrieves the viscosity value. + + \return The viscosity value. + + @see #setViscosity() + */ + virtual PxReal getViscosity() const = 0; + + /** + \brief Sets material vorticity confinement coefficient + + \param[in] vorticityConfinement Material vorticity confinement coefficient. Range: [0, PX_MAX_F32) + + @see #getVorticityConfinement() + */ + virtual void setVorticityConfinement(PxReal vorticityConfinement) = 0; + + /** + \brief Retrieves the vorticity confinement coefficient. + \return The vorticity confinement coefficient. + + @see #setVorticityConfinement() + */ + virtual PxReal getVorticityConfinement() const = 0; + + /** + \brief Sets material surface tension coefficient + + \param[in] surfaceTension Material surface tension coefficient. Range: [0, PX_MAX_F32) + + @see #getSurfaceTension() + */ + virtual void setSurfaceTension(PxReal surfaceTension) = 0; + + /** + \brief Retrieves the surface tension coefficient. + \return The surface tension coefficient. + + @see #setSurfaceTension() + */ + virtual PxReal getSurfaceTension() const = 0; + + /** + \brief Sets material cohesion coefficient + + \param[in] cohesion Material cohesion coefficient. Range: [0, PX_MAX_F32) + + @see #getCohesion() + */ + virtual void setCohesion(PxReal cohesion) = 0; + + /** + \brief Retrieves the cohesion coefficient. + \return The cohesion coefficient. + + @see #setCohesion() + */ + virtual PxReal getCohesion() const = 0; + + /** + \brief Sets material lift coefficient + + \param[in] lift Material lift coefficient. Range: [0, PX_MAX_F32) + + @see #getLift() + */ + virtual void setLift(PxReal lift) = 0; + + /** + \brief Retrieves the lift coefficient. + \return The lift coefficient. + + @see #setLift() + */ + virtual PxReal getLift() const = 0; + + /** + \brief Sets material drag coefficient + + \param[in] drag Material drag coefficient. Range: [0, PX_MAX_F32) + + @see #getDrag() + */ + virtual void setDrag(PxReal drag) = 0; + + /** + \brief Retrieves the drag coefficient. + \return The drag coefficient. + + @see #setDrag() + */ + virtual PxReal getDrag() const = 0; + + /** + \brief Sets the CFL coefficient. + + \param[in] coefficient CFL coefficient. This coefficient scales the CFL term used to limit relative motion between fluid particles. Range: [1.f, PX_MAX_F32) + */ + virtual void setCFLCoefficient(PxReal coefficient) = 0; + + /** + \brief Retrieves the CFL coefficient. + \return The CFL coefficient. + + @see #setCFLCoefficient() + */ + virtual PxReal getCFLCoefficient() const = 0; + + /** + \brief Sets material particle friction scale. This allows the application to scale up/down the frictional effect between particles independent of the friction + coefficient, which also defines frictional behavior between the particle and rigid bodies/soft bodies/cloth etc. + + \param[in] scale particle friction scale. Range: [0, PX_MAX_F32) + + @see #getParticleFrictionScale() + */ + virtual void setParticleFrictionScale(PxReal scale) = 0; + + /** + \brief Retrieves the particle friction scale. + \return The particle friction scale. + + @see #setParticleFrictionScale() + */ + virtual PxReal getParticleFrictionScale() const = 0; + + /** + \brief Sets material particle adhesion scale value. This is the adhesive value between particles defined as a scaled multiple of the adhesion parameter. + + \param[in] adhesion particle adhesion scale value. Range: [0, PX_MAX_F32) + + @see #getParticleAdhesionScale() + */ + virtual void setParticleAdhesionScale(PxReal adhesion) = 0; + + /** + \brief Retrieves the particle adhesion scale value. + \return The particle adhesion scale value. + + @see #setParticleAdhesionScale() + */ + virtual PxReal getParticleAdhesionScale() const = 0; + + virtual const char* getConcreteTypeName() const { return "PxPBDMaterial"; } + + protected: + PX_INLINE PxPBDMaterial(PxType concreteType, PxBaseFlags baseFlags) : PxParticleMaterial(concreteType, baseFlags) {} + PX_INLINE PxPBDMaterial(PxBaseFlags baseFlags) : PxParticleMaterial(baseFlags) {} + virtual ~PxPBDMaterial() {} + virtual bool isKindOf(const char* name) const { return !::strcmp("PxPBDMaterial", name) || PxParticleMaterial::isKindOf(name); } + }; + + class PxCustomMaterial : public PxParticleMaterial + { + public: + + virtual const char* getConcreteTypeName() const { return "PxCustomMaterial"; } + + protected: + PX_INLINE PxCustomMaterial(PxType concreteType, PxBaseFlags baseFlags) : PxParticleMaterial(concreteType, baseFlags) {} + PX_INLINE PxCustomMaterial(PxBaseFlags baseFlags) : PxParticleMaterial(baseFlags) {} + virtual ~PxCustomMaterial() {} + virtual bool isKindOf(const char* name) const { return !::strcmp("PxCustomMaterial", name) || PxParticleMaterial::isKindOf(name); } + }; +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/PxPBDParticleSystem.h b/Source/ThirdParty/PhysX/PxPBDParticleSystem.h new file mode 100644 index 000000000..33d0ffb11 --- /dev/null +++ b/Source/ThirdParty/PhysX/PxPBDParticleSystem.h @@ -0,0 +1,149 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_PBD_PARTICLE_SYSTEM_H +#define PX_PBD_PARTICLE_SYSTEM_H +/** \addtogroup physics +@{ */ + +#include "foundation/PxSimpleTypes.h" +#include "foundation/PxVec3.h" + +#include "PxParticleSystem.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +#if PX_VC +#pragma warning(push) +#pragma warning(disable : 4435) +#endif + +/** +\brief A particle system that uses the position based dynamics(PBD) solver. + +The position based dynamics solver for particle systems supports behaviors like +fluid, cloth, inflatables etc. + +*/ +class PxPBDParticleSystem : public PxParticleSystem +{ +public: + + virtual ~PxPBDParticleSystem() {} + + /** + \brief Set wind direction and intensity + + \param[in] wind The wind direction and intensity + */ + virtual void setWind(const PxVec3& wind) = 0; + + /** + \brief Retrieves the wind direction and intensity. + + \return The wind direction and intensity + */ + virtual PxVec3 getWind() const = 0; + + /** + \brief Set the fluid boundary density scale + + Defines how strong of a contribution the boundary (typically a rigid surface) should have on a fluid particle's density. + + \param[in] fluidBoundaryDensityScale Range: (0.0, 1.0) + */ + virtual void setFluidBoundaryDensityScale(PxReal fluidBoundaryDensityScale) = 0; + + /** + \brief Return the fluid boundary density scale + \return the fluid boundary density scale + + See #setFluidBoundaryDensityScale() + */ + virtual PxReal getFluidBoundaryDensityScale() const = 0; + + /** + \brief Set the fluid rest offset + + Two fluid particles will come to rest at a distance equal to twice the fluidRestOffset value. + + \param[in] fluidRestOffset Range: (0, particleContactOffset) + */ + virtual void setFluidRestOffset(PxReal fluidRestOffset) = 0; + + /** + \brief Return the fluid rest offset + \return the fluid rest offset + + See #setFluidRestOffset() + */ + virtual PxReal getFluidRestOffset() const = 0; + + /** + \brief Set the particle system grid size x dimension + + \param[in] gridSizeX x dimension in the particle grid + */ + virtual void setGridSizeX(PxU32 gridSizeX) = 0; + + /** + \brief Set the particle system grid size y dimension + + \param[in] gridSizeY y dimension in the particle grid + */ + virtual void setGridSizeY(PxU32 gridSizeY) = 0; + + /** + \brief Set the particle system grid size z dimension + + \param[in] gridSizeZ z dimension in the particle grid + */ + virtual void setGridSizeZ(PxU32 gridSizeZ) = 0; + + virtual const char* getConcreteTypeName() const PX_OVERRIDE { return "PxPBDParticleSystem"; } + +protected: + PX_INLINE PxPBDParticleSystem(PxType concreteType, PxBaseFlags baseFlags) : PxParticleSystem(concreteType, baseFlags) {} + PX_INLINE PxPBDParticleSystem(PxBaseFlags baseFlags) : PxParticleSystem(baseFlags) {} + virtual bool isKindOf(const char* name) const PX_OVERRIDE { return !::strcmp("PxPBDParticleSystem", name) || PxParticleSystem::isKindOf(name); } +}; + +#if PX_VC +#pragma warning(pop) +#endif + + +#if !PX_DOXYGEN +} // namespace physx +#endif + + /** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/PxParticleBuffer.h b/Source/ThirdParty/PhysX/PxParticleBuffer.h new file mode 100644 index 000000000..7b23068d7 --- /dev/null +++ b/Source/ThirdParty/PhysX/PxParticleBuffer.h @@ -0,0 +1,608 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_PARTICLE_BUFFER_H +#define PX_PARTICLE_BUFFER_H +/** \addtogroup physics +@{ */ + +#include "common/PxBase.h" +#include "common/PxPhysXCommonConfig.h" +#include "common/PxTypeInfo.h" + +#include "PxParticleSystemFlag.h" + +#include "foundation/PxBounds3.h" +#include "foundation/PxSimpleTypes.h" +#include "foundation/PxVec4.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +#if PX_VC +#pragma warning(push) +#pragma warning(disable : 4435) +#endif + +class PxCudaContextManager; +struct PxParticleRigidFilterPair; +struct PxParticleRigidAttachment; + +/** +\brief Particle volume structure. Used to track the bounding volume of a user-specified set of particles. The particles are required +to be laid out contiguously within the same PxParticleBuffer. +*/ +PX_ALIGN_PREFIX(16) +struct PxParticleVolume +{ + PxBounds3 bound; //!< The current bounds of the particles contained in this #PxParticleVolume. + PxU32 particleIndicesOffset; //!< The index into the particle list of the #PxParticleBuffer for the first particle of this volume. + PxU32 numParticles; //!< The number of particles contained in this #PxParticleVolume. +} PX_ALIGN_SUFFIX(16); + + +/** +\brief The shared base class for all particle buffers, can be instantiated directly to simulate granular and fluid particles. + +See #PxPhysics::createParticleBuffer. + +A particle buffer is a container that specifies per-particle attributes of a set of particles that will be used during the simulation +of a particle system. It exposes direct access to the underlying GPU buffers and is independent of the scene and particle system. Particle +buffers can be added/removed from a particle system at any time between simulation steps, and transferred from one particle system to another. +*/ +class PxParticleBuffer : public PxBase +{ +public: + + /** + \brief Get positions and inverse masses for this particle buffer. + \return A pointer to a device buffer containing the positions and inverse mass packed as PxVec4(pos.x, pos.y, pos.z, inverseMass). + */ + virtual PxVec4* getPositionInvMasses() const = 0; + + /** + \brief Get velocities for this particle buffer. + \return A pointer to a device buffer containing the velocities packed as PxVec4(vel.x, vel.y, vel.z, 0.0f). + */ + virtual PxVec4* getVelocities() const = 0; + + /** + \brief Get phases for this particle buffer. + + See #PxParticlePhase + + \return A pointer to a device buffer containing the per-particle phases for this particle buffer. + */ + virtual PxU32* getPhases() const = 0; + + /** + \brief Get particle volumes for this particle buffer. + + See #PxParticleVolume + + \return A pointer to a device buffer containing the #PxParticleVolume s for this particle buffer. + */ + virtual PxParticleVolume* getParticleVolumes() const = 0; + + /** + \brief Set the number of active particles for this particle buffer. + \param[in] nbActiveParticles The number of active particles. + + The number of active particles can be <= PxParticleBuffer::getMaxParticles(). The particle system will simulate the first + x particles in the #PxParticleBuffer, where x is the number of active particles. + */ + virtual void setNbActiveParticles(PxU32 nbActiveParticles) = 0; + + /** + \brief Get the number of active particles for this particle buffer. + \return The number of active particles. + */ + virtual PxU32 getNbActiveParticles() const = 0; + + /** + \brief Get the maximum number particles this particle buffer can hold. + + The maximum number of particles is specified when creating a #PxParticleBuffer. See #PxPhysics::createParticleBuffer. + + \return The maximum number of particles. + */ + virtual PxU32 getMaxParticles() const = 0; + + /** + \brief Get the number of particle volumes in this particle buffer. + \return The number of #PxParticleVolume s for this particle buffer. + */ + virtual PxU32 getNbParticleVolumes() const = 0; + + /** + \brief Set the number of #PxParticleVolume s for this particle buffer. + \param[in] nbParticleVolumes The number of particle volumes in this particle buffer. + */ + virtual void setNbParticleVolumes(PxU32 nbParticleVolumes) = 0; + + /** + \brief Get the maximum number of particle volumes this particle buffer can hold. + + See #PxParticleVolume. + + \return The maximum number of particle volumes this particle buffer can hold. + */ + virtual PxU32 getMaxParticleVolumes() const = 0; + + /** + \brief Set the #PxParticleRigidFilterPair s for collision filtering of particles in this buffer with rigid bodies. + + See #PxParticleRigidFilterPair + + \param[in] filters A device buffer containing #PxParticleRigidFilterPair s. + \param[in] nbFilters The number of particle-rigid body collision filtering pairs. + */ + virtual void setRigidFilters(PxParticleRigidFilterPair* filters, PxU32 nbFilters) = 0; + + /** + \brief Set the particle-rigid body attachments for particles in this particle buffer. + + See #PxParticleRigidAttachment + + \param[in] attachments A device buffer containing #PxParticleRigidAttachment s. + \param[in] nbAttachments The number of particle-rigid body attachments. + */ + virtual void setRigidAttachments(PxParticleRigidAttachment* attachments, PxU32 nbAttachments) = 0; + + /** + \brief Get the start index for the first particle of this particle buffer in the complete list of + particles of the particle system this buffer is used in. + + The return value is only correct if the particle buffer is assigned to a particle system and at least + one call to simulate() has been performed. + + \return The index of the first particle in the complete particle list. + */ + virtual PxU32 getFlatListStartIndex() const = 0; + + /** + \brief Raise dirty flags on this particle buffer to communicate that the corresponding data has been updated + by the user. + \param[in] flags The flag corresponding to the data that is dirty. + + See #PxParticleBufferFlag. + */ + virtual void raiseFlags(PxParticleBufferFlag::Enum flags) = 0; + + /** + \brief Release this buffer and deallocate all the memory. + */ + virtual void release() = 0; + + /** + \brief Cleanup helper used in case a particle system is released before the particle buffers have been removed. + */ + virtual void onParticleSystemDestroy() = 0; + + /** + \brief Reserved for internal use. + */ + virtual void setInternalData(void* data) = 0; + + /** + \brief Index of this buffer in the particle system it is assigned to. + */ + PxU32 bufferIndex; + + /** + \brief Unique index that does not change over the lifetime of a PxParticleBuffer. + */ + const PxU32 bufferUniqueId; + +protected: + + virtual ~PxParticleBuffer() { } + PX_INLINE PxParticleBuffer(PxU32 uniqueId) : PxBase(PxConcreteType::ePARTICLE_BUFFER, PxBaseFlag::eOWNS_MEMORY | PxBaseFlag::eIS_RELEASABLE), bufferIndex(0xffffffff), bufferUniqueId(uniqueId){} + PX_INLINE PxParticleBuffer(PxU32 uniqueId, PxType type) : PxBase(type, PxBaseFlag::eOWNS_MEMORY | PxBaseFlag::eIS_RELEASABLE), bufferIndex(0xffffffff), bufferUniqueId(uniqueId){} + +private: + PX_NOCOPY(PxParticleBuffer) +}; + +/** +\brief Parameters to configure the behavior of diffuse particles +*/ +class PxDiffuseParticleParams +{ +public: + /** + \brief Construct parameters with default values. + */ + PX_INLINE PxDiffuseParticleParams() + { + threshold = 100.0f; + lifetime = 5.0f; + airDrag = 0.0f; + bubbleDrag = 0.5f; + buoyancy = 0.8f; + kineticEnergyWeight = 0.01f; + pressureWeight = 1.0f; + divergenceWeight = 5.0f; + collisionDecay = 0.5f; + useAccurateVelocity = false; + } + + /** + \brief (re)sets the structure to the default. + */ + PX_INLINE void setToDefault() + { + *this = PxDiffuseParticleParams(); + } + + PxReal threshold; //!< Particles with potential value greater than the threshold will spawn diffuse particles + PxReal lifetime; //!< Diffuse particle will be removed after the specified lifetime + PxReal airDrag; //!< Air drag force factor for spray particles + PxReal bubbleDrag; //!< Fluid drag force factor for bubble particles + PxReal buoyancy; //!< Buoyancy force factor for bubble particles + PxReal kineticEnergyWeight; //!< Contribution from kinetic energy when deciding diffuse particle creation. + PxReal pressureWeight; //!< Contribution from pressure when deciding diffuse particle creation. + PxReal divergenceWeight; //!< Contribution from divergence when deciding diffuse particle creation. + PxReal collisionDecay; //!< Decay factor of diffuse particles' lifetime after they collide with shapes. + bool useAccurateVelocity; //!< If true, enables accurate velocity estimation when using PBD solver. +}; + +/** +\brief A particle buffer used to simulate diffuse particles. + +See #PxPhysics::createParticleAndDiffuseBuffer. +*/ +class PxParticleAndDiffuseBuffer : public PxParticleBuffer +{ +public: + + /** + \brief Get a device buffer of positions and remaining lifetimes for the diffuse particles. + \return A device buffer containing positions and lifetimes of diffuse particles packed as PxVec4(pos.x, pos.y, pos.z, lifetime). + */ + virtual PxVec4* getDiffusePositionLifeTime() const = 0; + + /** + \brief Get number of currently active diffuse particles. + \return The number of currently active diffuse particles. + */ + virtual PxU32 getNbActiveDiffuseParticles() const = 0; + + /** + \brief Set the maximum possible number of diffuse particles for this buffer. + \param[in] maxActiveDiffuseParticles the maximum number of active diffuse particles. + + \note Must be in the range [0, PxParticleAndDiffuseBuffer::getMaxDiffuseParticles()] + */ + virtual void setMaxActiveDiffuseParticles(PxU32 maxActiveDiffuseParticles) = 0; + + /** + \brief Get maximum possible number of diffuse particles. + \return The maximum possible number diffuse particles. + */ + virtual PxU32 getMaxDiffuseParticles() const = 0; + + /** + \brief Set the parameters for diffuse particle simulation. + \param[in] params The diffuse particle parameters. + + See #PxDiffuseParticleParams + */ + virtual void setDiffuseParticleParams(const PxDiffuseParticleParams& params) = 0; + + /** + \brief Get the parameters currently used for diffuse particle simulation. + \return A PxDiffuseParticleParams structure. + */ + virtual PxDiffuseParticleParams getDiffuseParticleParams() const = 0; + +protected: + + virtual ~PxParticleAndDiffuseBuffer() {} + PX_INLINE PxParticleAndDiffuseBuffer(PxU32 uniqueId) : PxParticleBuffer(uniqueId, PxConcreteType::ePARTICLE_DIFFUSE_BUFFER){} + +private: + PX_NOCOPY(PxParticleAndDiffuseBuffer) +}; + +/** +\brief Holds all the information for a spring constraint between two particles. Used for particle cloth simulation. +*/ +struct PX_ALIGN_PREFIX(8) PxParticleSpring +{ + PxU32 ind0; //!< particle index of first particle + PxU32 ind1; //!< particle index of second particle + PxReal length; //!< spring length + PxReal stiffness; //!< spring stiffness + PxReal damping; //!< spring damping factor + PxReal pad; //!< padding bytes. +} PX_ALIGN_SUFFIX(8); + +/** +\brief Particle cloth structure. Holds information about a single piece of cloth that is part of a #PxParticleClothBuffer. +*/ +struct PxParticleCloth +{ + PxU32 startVertexIndex; //!< Index of the first particle of this cloth in the position/velocity buffers of the parent #PxParticleClothBuffer + PxU32 numVertices; //!< The number of particles of this piece of cloth + PxReal clothBlendScale; //!< Used internally. + PxReal restVolume; //!< The rest volume of this piece of cloth, used for inflatable simulation. + PxReal pressure; //!< The factor of the rest volume to specify the target volume for this piece of cloth, used for inflatable simulation. + PxU32 startTriangleIndex; //!< The index of the first triangle of this piece of cloth in the triangle list. + PxU32 numTriangles; //!< The number of triangles of this piece of cloth. + + bool operator <= (const PxParticleCloth& other) const { return startVertexIndex <= other.startVertexIndex; } + bool operator >= (const PxParticleCloth& other) const { return startVertexIndex >= other.startVertexIndex; } + bool operator < (const PxParticleCloth& other) const { return startVertexIndex < other.startVertexIndex; } + bool operator > (const PxParticleCloth& other) const { return startVertexIndex > other.startVertexIndex; } + bool operator == (const PxParticleCloth& other) const { return startVertexIndex == other.startVertexIndex; } +}; + +/** +\brief Structure to describe the set of particle cloths in the same #PxParticleClothBuffer. Used an input for the cloth preprocessing. +*/ +struct PxParticleClothDesc +{ + PxParticleClothDesc() : cloths(NULL), triangles(NULL), springs(NULL), restPositions(NULL), + nbCloths(0), nbSprings(0), nbTriangles(0), nbParticles(0) + { + } + + PxParticleCloth* cloths; //!< List of PxParticleCloth s, describes the individual cloths. + PxU32* triangles; //!< List of triangle indices, 3 consecutive PxU32 that map triangle vertices to particles + PxParticleSpring* springs; //!< List of PxParticleSpring s. + PxVec4* restPositions; //!< List of rest positions for all particles + PxU32 nbCloths; //!< The number of cloths in described using this cloth descriptor + PxU32 nbSprings; //!< The number of springs in this cloth descriptor + PxU32 nbTriangles; //!< The number of triangles in this cloth descriptor + PxU32 nbParticles; //!< The number of particles in this cloth descriptor +}; + +/** +\brief Structure to describe the output of the particle cloth preprocessing. Used as an input to specify cloth data for a #PxParticleClothBuffer. +All the pointers point to pinned host memory. + +See #PxParticleClothPreProcessor +*/ +struct PX_PHYSX_CORE_API PxPartitionedParticleCloth +{ + PxU32* accumulatedSpringsPerPartitions; //!< The number of springs in each partition. Size: numPartitions. + PxU32* accumulatedCopiesPerParticles; //!< Start index for each particle in the accumulation buffer. Size: numParticles. + PxU32* remapOutput; //!< Index of the next copy of this particle in the next partition, or in the accumulation buffer. Size: numSprings * 2. + PxParticleSpring* orderedSprings; //!< Springs ordered by partition. Size: numSprings. + PxU32* sortedClothStartIndices; //!< The first particle index into the position buffer of the #PxParticleClothBuffer for each cloth. Cloths are sorted by start particle index. Size: numCloths. + PxParticleCloth* cloths; //!< The #PxParticleCloth s sorted by start particle index. + + PxU32 remapOutputSize; //!< Size of remapOutput. + PxU32 nbPartitions; //!< The number of partitions. + PxU32 nbSprings; //!< The number of springs. + PxU32 nbCloths; //!< The number of cloths. + PxU32 maxSpringsPerPartition; //!< The maximum number of springs in a partition. + + PxCudaContextManager* mCudaManager; //!< A cuda context manager. + + PxPartitionedParticleCloth(); + ~PxPartitionedParticleCloth(); + + /** + \brief allocate all the buffers for this #PxPartitionedParticleCloth. + + \param[in] nbParticles the number of particles this #PxPartitionedParticleCloth will be generated for. + \param[in] cudaManager a cuda context manager. + */ + void allocateBuffers(PxU32 nbParticles, PxCudaContextManager* cudaManager); +}; + +/** +\brief A particle buffer used to simulate particle cloth. + +See #PxPhysics::createParticleClothBuffer. +*/ +class PxParticleClothBuffer : public PxParticleBuffer +{ +public: + + /** + \brief Get rest positions for this particle buffer. + \return A pointer to a device buffer containing the rest positions packed as PxVec4(pos.x, pos.y, pos.z, 0.0f). + */ + virtual PxVec4* getRestPositions() = 0; + + /** + \brief Get the triangle indices for this particle buffer. + \return A pointer to a device buffer containing the triangle indices for this cloth buffer. + */ + virtual PxU32* getTriangles() const = 0; + + /** + \brief Set the number of triangles for this particle buffer. + \param[in] nbTriangles The number of triangles for this particle cloth buffer. + */ + virtual void setNbTriangles(PxU32 nbTriangles) = 0; + + /** + \brief Get the number of triangles for this particle buffer. + \return The number triangles for this cloth buffer. + */ + virtual PxU32 getNbTriangles() const = 0; + + /** + \brief Get the number of springs in this particle buffer. + \return The number of springs in this cloth buffer. + */ + virtual PxU32 getNbSprings() const = 0; + + /** + \brief Get the springs for this particle buffer. + \return A pointer to a device buffer containing the springs for this cloth buffer. + */ + virtual PxParticleSpring* getSprings() = 0; + + /** + \brief Set cloths for this particle buffer. + \param[in] cloths A pointer to a PxPartitionedParticleCloth. + + See #PxPartitionedParticleCloth, #PxParticleClothPreProcessor + */ + virtual void setCloths(PxPartitionedParticleCloth& cloths) = 0; + +protected: + + virtual ~PxParticleClothBuffer() {} + PX_INLINE PxParticleClothBuffer(PxU32 uniqueId) : PxParticleBuffer(uniqueId, PxConcreteType::ePARTICLE_CLOTH_BUFFER) {} + +private: + PX_NOCOPY(PxParticleClothBuffer) +}; + +/** +\brief A particle buffer used to simulate rigid bodies using shape matching with particles. + +See #PxPhysics::createParticleRigidBuffer. +*/ +class PxParticleRigidBuffer : public PxParticleBuffer +{ +public: + /** + \brief Get the particle indices of the first particle for each shape matched rigid body. + \return A device buffer containing the list of particle start indices of each shape matched rigid body. + */ + virtual PxU32* getRigidOffsets() const = 0; + + /** + \brief Get the stiffness coefficients for all shape matched rigid bodies in this buffer. + + Stiffness must be in the range [0, 1]. + + \return A device buffer containing the list of stiffness coefficients for each rigid body. + */ + virtual PxReal* getRigidCoefficients() const = 0; + + /** + \brief Get the local position of each particle relative to the rigid body's center of mass. + \return A pointer to a device buffer containing the local position for each particle. + */ + virtual PxVec4* getRigidLocalPositions() const = 0; + + /** + \brief Get the world-space translations for all rigid bodies in this buffer. + \return A pointer to a device buffer containing the world-space translations for all shape-matched rigid bodies in this buffer. + */ + virtual PxVec4* getRigidTranslations() const = 0; + + /** + \brief Get the world-space rotation of every shape-matched rigid body in this buffer. + + Rotations are specified as quaternions. + + \return A pointer to a device buffer containing the world-space rotation for every shape-matched rigid body in this buffer. + */ + virtual PxVec4* getRigidRotations() const = 0; + + /** + \brief Get the local space normals for each particle relative to the shape of the corresponding rigid body. + + The 4th component of every PxVec4 should be the negative signed distance of the particle inside its shape. + + \return A pointer to a device buffer containing the local-space normals for each particle. + */ + virtual PxVec4* getRigidLocalNormals() const = 0; + + /** + \brief Set the number of shape matched rigid bodies in this buffer. + \param[in] nbRigids The number of shape matched rigid bodies + */ + virtual void setNbRigids(PxU32 nbRigids) = 0; + + /** + \brief Get the number of shape matched rigid bodies in this buffer. + \return The number of shape matched rigid bodies in this buffer. + */ + virtual PxU32 getNbRigids() const = 0; + +protected: + + virtual ~PxParticleRigidBuffer() {} + PX_INLINE PxParticleRigidBuffer(PxU32 uniqueId) : PxParticleBuffer(uniqueId, PxConcreteType::ePARTICLE_RIGID_BUFFER) {} + +private: + PX_NOCOPY(PxParticleRigidBuffer) +}; + +/** +@brief Preprocessor to prepare particle cloths for simulation. + +Preprocessing is done by calling #PxParticleClothPreProcessor::partitionSprings() on an instance of this class. This will allocate the memory in the +output object, partition the springs and fill all the members of the ouput object. The output can then be passed without +any further modifications to #PxParticleClothBuffer::setCloths(). + +See #PxCreateParticleClothPreprocessor, #PxParticleClothDesc, #PxPartitionedParticleCloth +*/ +class PxParticleClothPreProcessor +{ +public: + + /** + \brief Release this object and deallocate all the memory. + */ + virtual void release() = 0; + + /** + \brief Partition the spring constraints for particle cloth simulation. + \param[in] clothDesc Reference to a valid #PxParticleClothDesc. + \param[in] output Reference to a #PxPartitionedParticleCloth object. This is the output of the preprocessing and should be passed to a #PxParticleClothBuffer. + */ + virtual void partitionSprings(const PxParticleClothDesc& clothDesc, PxPartitionedParticleCloth& output) = 0; + +protected: + virtual ~PxParticleClothPreProcessor(){} +}; + + +#if PX_VC +#pragma warning(pop) +#endif + + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** +\brief Create a particle cloth preprocessor. +\param[in] cudaContextManager A cuda context manager. + +See #PxParticleClothDesc, #PxPartitionedParticleCloth. +*/ +PX_C_EXPORT PX_PHYSX_CORE_API physx::PxParticleClothPreProcessor* PX_CALL_CONV PxCreateParticleClothPreProcessor(physx::PxCudaContextManager* cudaContextManager); + + + /** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/PxParticleGpu.h b/Source/ThirdParty/PhysX/PxParticleGpu.h new file mode 100644 index 000000000..3201d0150 --- /dev/null +++ b/Source/ThirdParty/PhysX/PxParticleGpu.h @@ -0,0 +1,192 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_GPU_PARTICLE_SYSTEM_H +#define PX_GPU_PARTICLE_SYSTEM_H +/** \addtogroup physics +@{ */ + +#include "foundation/PxSimpleTypes.h" +#include "foundation/PxVec3.h" + +#include "PxParticleSystem.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +/** +@brief Common material properties for particles. See #PxParticleMaterial. + +Accessed by either integration or particle-rigid collisions +*/ +struct PxsParticleMaterialData +{ + PxReal friction; // 4 + PxReal damping; // 8 + PxReal adhesion; // 12 + PxReal gravityScale; // 16 + PxReal adhesionRadiusScale; // 20 +}; + +#if !PX_DOXYGEN +} // namespace physx +#endif + +#if PX_SUPPORT_GPU_PHYSX + +struct float4; + +PX_CUDA_CALLABLE inline physx::PxU32 PxGetGroup(physx::PxU32 phase) { return phase & physx::PxParticlePhaseFlag::eParticlePhaseGroupMask; } +PX_CUDA_CALLABLE inline bool PxGetFluid(physx::PxU32 phase) { return (phase & physx::PxParticlePhaseFlag::eParticlePhaseFluid) != 0; } +PX_CUDA_CALLABLE inline bool PxGetSelfCollide(physx::PxU32 phase) { return (phase & physx::PxParticlePhaseFlag::eParticlePhaseSelfCollide) != 0; } +PX_CUDA_CALLABLE inline bool PxGetSelfCollideFilter(physx::PxU32 phase) { return (phase & physx::PxParticlePhaseFlag::eParticlePhaseSelfCollideFilter) != 0; } + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +/** +@brief An iterator class to iterate over the neighbors of a particle during particle system simulation. +*/ +class PxNeighborhoodIterator +{ + + const PxU32* PX_RESTRICT mCollisionIndex; //!< Pointer to the current state of the iterator. + PxU32 mMaxParticles; //!< The maximum number of particles of the particle system this iterator is used on. + +public: + PX_CUDA_CALLABLE PxNeighborhoodIterator(const PxU32* PX_RESTRICT collisionIndex, PxU32 maxParticles) : + mCollisionIndex(collisionIndex), mMaxParticles(maxParticles) + { + } + + PX_CUDA_CALLABLE PxU32 getNextIndex() + { + PxU32 result = *mCollisionIndex; + mCollisionIndex += mMaxParticles; + return result; + } + + PX_INLINE PxNeighborhoodIterator(const PxNeighborhoodIterator& params) + { + mCollisionIndex = params.mCollisionIndex; + mMaxParticles = params.mMaxParticles; + } + + PX_INLINE void operator = (const PxNeighborhoodIterator& params) + { + mCollisionIndex = params.mCollisionIndex; + mMaxParticles = params.mMaxParticles; + } +}; + +/** +@brief Structure that holds simulation parameters of a #PxGpuParticleSystem. +*/ +struct PxGpuParticleData +{ + PxVec3 mPeriod; //!< Size of the unit cell for periodic boundary conditions. If 0, the size of the simulation domain is specified by the mGridSize * mParticleContactDistance. + + PxU32 mGridSizeX; //!< Size of the x-dimension of the background simulation grid. Translates to an absolute size of mGridSizeX * mParticleContactDistance. + PxU32 mGridSizeY; //!< Size of the y-dimension of the background simulation grid. Translates to an absolute size of mGridSizeY * mParticleContactDistance. + PxU32 mGridSizeZ; //!< Size of the z-dimension of the background simulation grid. Translates to an absolute size of mGridSizeZ * mParticleContactDistance. + + PxReal mParticleContactDistance; //!< Two particles start interacting if their distance is lower than mParticleContactDistance. + PxReal mParticleContactDistanceInv; //!< 1.f / mParticleContactDistance. + PxReal mParticleContactDistanceSq; //!< mParticleContactDistance * mParticleContactDistance. + + PxU32 mNumParticles; //!< The number of particles in this particle system. + PxU32 mMaxParticles; //!< The maximum number of particles that can be simulated in this particle system. + PxU32 mMaxNeighborhood; //!< The maximum number of particles considered when computing neighborhood based particle interactions. + PxU32 mMaxDiffuseParticles; //!< The maximum number of diffuse particles that can be simulated using this particle system. + PxU32 mNumParticleBuffers; //!< The number of particle buffers that are simulated in this particle system. +}; + +/** +@brief Container class for a GPU particle system. Used to communicate particle system parameters and simulation state +between the internal SDK simulation and the particle system callbacks. + +See #PxParticleSystem, #PxParticleSystemCallback. +*/ +class PxGpuParticleSystem +{ +public: + + /** + @brief Returns the number of cells of the background simulation grid. + + @return PxU32 the number of cells. + */ + PX_FORCE_INLINE PxU32 getNumCells() { return mCommonData.mGridSizeX * mCommonData.mGridSizeY * mCommonData.mGridSizeZ; } + + /* Unsorted particle state buffers */ + float4* mUnsortedPositions_InvMass; //!< GPU pointer to unsorted particle positions and inverse masses. + float4* mUnsortedVelocities; //!< GPU pointer to unsorted particle velocities. + PxU32* mUnsortedPhaseArray; //!< GPU pointer to unsorted particle phase array. See #PxParticlePhase. + + /* Sorted particle state buffers. Sorted by increasing hash value in background grid. */ + float4* mSortedPositions_InvMass; //!< GPU pointer to sorted particle positions + float4* mSortedVelocities; //!< GPU pointer to sorted particle velocities + PxU32* mSortedPhaseArray; //!< GPU pointer to sorted particle phase array + + /* Mappings to/from sorted particle states */ + PxU32* mUnsortedToSortedMapping; //!< GPU pointer to the mapping from unsortedParticle ID to sorted particle ID + PxU32* mSortedToUnsortedMapping; //!< GPU pointer to the mapping from sorted particle ID to unsorted particle ID + + /* Neighborhood information */ + PxU32* mParticleSelfCollisionCount; //!< Per-particle neighborhood count + PxU32* mCollisionIndex; //!< Set of sorted particle indices per neighbor + + PxsParticleMaterialData* mParticleMaterials; //!< GPU pointer to the particle materials used in this particle system. + PxGpuParticleData mCommonData; //!< Structure holding simulation parameters and state for this particle system. See #PxGpuParticleData. + + /** + @brief Get a PxNeighborhoodIterator initialized for usage with this particle system. + + @param particleId An initial particle index for the initialization of the iterator. + + @return An initialized PxNeighborhoodIterator. + */ + PX_CUDA_CALLABLE PxNeighborhoodIterator getIterator(PxU32 particleId) const + { + return PxNeighborhoodIterator(mCollisionIndex + particleId, mCommonData.mMaxParticles); + } +}; + +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif + +/** @} */ +#endif + diff --git a/Source/ThirdParty/PhysX/PxParticleMaterial.h b/Source/ThirdParty/PhysX/PxParticleMaterial.h new file mode 100644 index 000000000..3dd7fa141 --- /dev/null +++ b/Source/ThirdParty/PhysX/PxParticleMaterial.h @@ -0,0 +1,152 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_PARTICLE_MATERIAL_H +#define PX_PARTICLE_MATERIAL_H +/** \addtogroup physics +@{ +*/ + +#include "foundation/PxSimpleTypes.h" + +#include "PxBaseMaterial.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +/** +\brief Material class to represent a set of particle material properties. + +@see #PxPhysics.createPBDMaterial, #PxPhysics.createFLIPMaterial, #PxPhysics.createMPMMaterial +*/ +class PxParticleMaterial : public PxBaseMaterial +{ +public: + + /** + \brief Sets friction + + \param[in] friction Friction. Range: [0, PX_MAX_F32) + + @see #getFriction() + */ + virtual void setFriction(PxReal friction) = 0; + + /** + \brief Retrieves the friction value. + + \return The friction value. + + @see #setFriction() + */ + virtual PxReal getFriction() const = 0; + + /** + \brief Sets velocity damping term + + \param[in] damping Velocity damping term. Range: [0, PX_MAX_F32) + + @see #getDamping + */ + virtual void setDamping(PxReal damping) = 0; + + /** + \brief Retrieves the velocity damping term + \return The velocity damping term. + + @see #setDamping() + */ + virtual PxReal getDamping() const = 0; + + /** + \brief Sets adhesion term + + \param[in] adhesion adhesion coefficient. Range: [0, PX_MAX_F32) + + @see #getAdhesion + */ + virtual void setAdhesion(PxReal adhesion) = 0; + + /** + \brief Retrieves the adhesion term + \return The adhesion term. + + @see #setAdhesion() + */ + virtual PxReal getAdhesion() const = 0; + + /** + \brief Sets gravity scale term + + \param[in] scale gravity scale coefficient. Range: (-PX_MAX_F32, PX_MAX_F32) + + @see #getAdhesion + */ + virtual void setGravityScale(PxReal scale) = 0; + + /** + \brief Retrieves the gravity scale term + \return The gravity scale term. + + @see #setAdhesion() + */ + virtual PxReal getGravityScale() const = 0; + + /** + \brief Sets material adhesion radius scale. This is multiplied by the particle rest offset to compute the fall-off distance + at which point adhesion ceases to operate. + + \param[in] scale Material adhesion radius scale. Range: [0, PX_MAX_F32) + + @see #getAdhesionRadiusScale + */ + virtual void setAdhesionRadiusScale(PxReal scale) = 0; + + /** + \brief Retrieves the adhesion radius scale. + \return The adhesion radius scale. + + @see #setAdhesionRadiusScale() + */ + virtual PxReal getAdhesionRadiusScale() const = 0; + +protected: + PX_INLINE PxParticleMaterial(PxType concreteType, PxBaseFlags baseFlags) : PxBaseMaterial(concreteType, baseFlags) {} + PX_INLINE PxParticleMaterial(PxBaseFlags baseFlags) : PxBaseMaterial(baseFlags) {} + virtual ~PxParticleMaterial() {} + virtual bool isKindOf(const char* name) const { return !::strcmp("PxParticleMaterial", name) || PxBaseMaterial::isKindOf(name); } +}; + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/PxParticleSolverType.h b/Source/ThirdParty/PhysX/PxParticleSolverType.h new file mode 100644 index 000000000..671220ef3 --- /dev/null +++ b/Source/ThirdParty/PhysX/PxParticleSolverType.h @@ -0,0 +1,71 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_PARTICLE_SOLVER_TYPE_H +#define PX_PARTICLE_SOLVER_TYPE_H +/** \addtogroup physics +@{ */ + +#include "foundation/PxPreprocessor.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +#if PX_VC +#pragma warning(push) +#pragma warning(disable : 4435) +#endif + + +/** +\brief Identifies the solver to use for a particle system. +*/ +struct PxParticleSolverType +{ + enum Enum + { + ePBD = 1 << 0, //!< The position based dynamics solver that can handle fluid, granular material, cloth, inflatables etc. See #PxPBDParticleSystem. + eFLIP = 1 << 1, //!< The FLIP fluid solver. See #PxFLIPParticleSystem. + eMPM = 1 << 2, //!< The MPM (material point method) solver that can handle a variety of materials. See #PxMPMParticleSystem. + eCUSTOM = 1 << 3 //!< Custom solver. The user needs to specify the interaction of the particle by providing appropriate functions. Can be used e.g. for molecular dynamics simulations. See #PxCustomParticleSystem. + }; +}; + +#if PX_VC +#pragma warning(pop) +#endif + + +#if !PX_DOXYGEN +} // namespace physx +#endif + + /** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/PxParticleSystem.h b/Source/ThirdParty/PhysX/PxParticleSystem.h new file mode 100644 index 000000000..0cabdeac6 --- /dev/null +++ b/Source/ThirdParty/PhysX/PxParticleSystem.h @@ -0,0 +1,451 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_PARTICLE_SYSTEM_H +#define PX_PARTICLE_SYSTEM_H +/** \addtogroup physics +@{ */ + +#include "foundation/PxSimpleTypes.h" + +#include "PxActor.h" +#include "PxFiltering.h" +#include "PxParticleSystemFlag.h" + +#include "cudamanager/PxCudaTypes.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +#if PX_VC +#pragma warning(push) +#pragma warning(disable : 4435) +#endif + +class PxCudaContextManager; +class PxGpuParticleSystem; + +class PxParticleAndDiffuseBuffer; +class PxParticleBuffer; +class PxParticleMaterial; + +/** +\brief Container to hold a pair of corresponding device and host pointers. These pointers should point to GPU / CPU mirrors of the same data, but +this is not enforced. +*/ +template +struct PxGpuMirroredPointer +{ + Type* mDevicePtr; + Type* mHostPtr; + + PxGpuMirroredPointer(Type* devicePtr, Type* hostPtr) : mDevicePtr(devicePtr), mHostPtr(hostPtr) { } +}; + +/** +\brief Particle system callback base class to schedule work that should be done before, while or after the particle system updates. +A call to fetchResultsParticleSystem() on the PxScene will synchronize the work such that the caller knows that all tasks of this callback completed. +*/ +class PxParticleSystemCallback +{ +public: + /** + \brief Method gets called when dirty data from the particle system is uploated to the gpu + + \param[in] gpuParticleSystem Pointers to the particle systems gpu data available as host accessible pointer and as gpu accessible pointer + \param[in] stream The stream on which all cuda kernel calls get scheduled for execution. A call to fetchResultsParticleSystem() on the + PxScene will synchronize the work such that the caller knows that the task completed. + */ + virtual void onBegin(const PxGpuMirroredPointer& gpuParticleSystem, CUstream stream) = 0; + + /** + \brief Method gets called when the simulation step of the particle system is performed + + \param[in] gpuParticleSystem Pointers to the particle systems gpu data available as host accessible pointer and as gpu accessible pointer + \param[in] stream The stream on which all cuda kernel calls get scheduled for execution. A call to fetchResultsParticleSystem() on the + PxScene will synchronize the work such that the caller knows that the task completed. + */ + virtual void onAdvance(const PxGpuMirroredPointer& gpuParticleSystem, CUstream stream) = 0; + + /** + \brief Method gets called after the particle system simulation step completed + + \param[in] gpuParticleSystem Pointers to the particle systems gpu data available as host accessible pointer and as gpu accessible pointer + \param[in] stream The stream on which all cuda kernel calls get scheduled for execution. A call to fetchResultsParticleSystem() on the + PxScene will synchronize the work such that the caller knows that the task completed. + */ + virtual void onPostSolve(const PxGpuMirroredPointer& gpuParticleSystem, CUstream stream) = 0; + + /** + \brief Destructor + */ + virtual ~PxParticleSystemCallback() {} +}; + +/** +\brief Flags which control the behaviour of a particle system. + +See #PxParticleSystem::setParticleFlag(), #PxParticleSystem::setParticleFlags(), #PxParticleSystem::getParticleFlags() +*/ +struct PxParticleFlag +{ + enum Enum + { + eDISABLE_SELF_COLLISION = 1 << 0, //!< Disables particle self-collision + eDISABLE_RIGID_COLLISION = 1 << 1, //!< Disables particle-rigid body collision + eFULL_DIFFUSE_ADVECTION = 1 << 2 //!< Enables full advection of diffuse particles. By default, diffuse particles are advected only by particles in the cell they are contained. This flag enables full neighbourhood generation (more expensive). + }; +}; + +typedef PxFlags PxParticleFlags; + +/** +\brief The shared base class for all particle systems + +A particle system simulates a bunch of particles that interact with each other. The interactions can be simple collisions +with friction (granular material) ore more complex like fluid interactions, cloth, inflatables etc. + +*/ +class PxParticleSystem : public PxActor +{ +public: + + /** + \brief Sets the solver iteration counts for the body. + + The solver iteration count determines how accurately joints and contacts are resolved. + If you are having trouble with jointed bodies oscillating and behaving erratically, then + setting a higher position iteration count may improve their stability. + + If intersecting bodies are being depenetrated too violently, increase the number of velocity + iterations. More velocity iterations will drive the relative exit velocity of the intersecting + objects closer to the correct value given the restitution. + + Default: 4 position iterations, 1 velocity iteration + + \param[in] minPositionIters Number of position iterations the solver should perform for this body. Range: [1,255] + \param[in] minVelocityIters Number of velocity iterations the solver should perform for this body. Range: [1,255] + + See #getSolverIterationCounts() + */ + virtual void setSolverIterationCounts(PxU32 minPositionIters, PxU32 minVelocityIters = 1) = 0; + + /** + \brief Retrieves the solver iteration counts. + + See #setSolverIterationCounts() + */ + virtual void getSolverIterationCounts(PxU32& minPositionIters, PxU32& minVelocityIters) const = 0; + + /** + \brief Retrieves the collision filter settings. + + \return The filter data + */ + virtual PxFilterData getSimulationFilterData() const = 0; + + /** + \brief Set collision filter settings + + Allows to control with which objects the particle system collides + + \param[in] data The filter data + */ + virtual void setSimulationFilterData(const PxFilterData& data) = 0; + + /** + \brief Set particle flag + + Allows to control self collision etc. + + \param[in] flag The flag to set + \param[in] val The new value of the flag + */ + virtual void setParticleFlag(PxParticleFlag::Enum flag, bool val) = 0; + + /** + \brief Set particle flags + + Allows to control self collision etc. + + \param[in] flags The flags to set + */ + virtual void setParticleFlags(PxParticleFlags flags) = 0; + + /** + \brief Retrieves the particle flags. + + \return The particle flags + */ + virtual PxParticleFlags getParticleFlags() const = 0; + + /** + \brief Set the maximal depenetration velocity particles can reach + + Allows to limit the particles' maximal depenetration velocity to avoid that collision responses lead to very high particle velocities + + \param[in] maxDepenetrationVelocity The maximal depenetration velocity + */ + virtual void setMaxDepenetrationVelocity(PxReal maxDepenetrationVelocity) = 0; + + /** + \brief Retrieves maximal depenetration velocity a particle can have. + + \return The maximal depenetration velocity + */ + virtual PxReal getMaxDepenetrationVelocity() = 0; + + /** + \brief Set the maximal velocity particles can reach + + Allows to limit the particles' maximal velocity to control the maximal distance a particle can move per frame + + \param[in] maxVelocity The maximal velocity + */ + virtual void setMaxVelocity(PxReal maxVelocity) = 0; + + /** + \brief Retrieves maximal velocity a particle can have. + + \return The maximal velocity + */ + virtual PxReal getMaxVelocity() = 0; + + + /** + \brief Return the cuda context manager + + \return The cuda context manager + */ + virtual PxCudaContextManager* getCudaContextManager() const = 0; + + /** + \brief Set the rest offset for the collision between particles and rigids or soft bodies. + + A particle and a rigid or soft body will come to rest at a distance equal to the sum of their restOffset values. + + \param[in] restOffset Range: (0, contactOffset) + */ + virtual void setRestOffset(PxReal restOffset) = 0; + + /** + \brief Return the rest offset + \return the rest offset + + See #setRestOffset() + */ + virtual PxReal getRestOffset() const = 0; + + /** + \brief Set the contact offset for the collision between particles and rigids or soft bodies + + The contact offset needs to be larger than the rest offset. + Contact constraints are generated for a particle and a rigid or softbody below the distance equal to the sum of their contacOffset values. + + \param[in] contactOffset Range: (restOffset, PX_MAX_F32) + */ + virtual void setContactOffset(PxReal contactOffset) = 0; + + /** + \brief Return the contact offset + \return the contact offset + + See #setContactOffset() + */ + virtual PxReal getContactOffset() const = 0; + + /** + \brief Set the contact offset for the interactions between particles + + The particle contact offset needs to be larger than the fluid rest offset and larger than the solid rest offset. + Interactions for two particles are computed if their distance is below twice the particleContactOffset value. + + \param[in] particleContactOffset Range: (Max(solidRestOffset, fluidRestOffset), PX_MAX_F32) + */ + virtual void setParticleContactOffset(PxReal particleContactOffset) = 0; + + /** + \brief Return the particle contact offset + \return the particle contact offset + + See #setParticleContactOffset() + */ + virtual PxReal getParticleContactOffset() const = 0; + + /** + \brief Set the solid rest offset + + Two solid particles (or a solid and a fluid particle) will come to rest at a distance equal to twice the solidRestOffset value. + + \param[in] solidRestOffset Range: (0, particleContactOffset) + */ + virtual void setSolidRestOffset(PxReal solidRestOffset) = 0; + + /** + \brief Return the solid rest offset + \return the solid rest offset + + See #setSolidRestOffset() + */ + virtual PxReal getSolidRestOffset() const = 0; + + + /** + \brief Creates a rigid attachment between a particle and a rigid actor. + + This method creates a symbolic attachment between the particle system and a rigid body for the purpose of island management. + The actual attachments will be contained in the particle buffers. + + Be aware that destroying the rigid body before destroying the attachment is illegal and may cause a crash. + The particle system keeps track of these attachments but the rigid body does not. + + \param[in] actor The rigid actor used for the attachment + */ + virtual void addRigidAttachment(PxRigidActor* actor) = 0; + + /** + \brief Removes a rigid attachment between a particle and a rigid body. + + This method destroys a symbolic attachment between the particle system and a rigid body for the purpose of island management. + + Be aware that destroying the rigid body before destroying the attachment is illegal and may cause a crash. + The particle system keeps track of these attachments but the rigid body does not. + + \param[in] actor The rigid body actor used for the attachment + */ + virtual void removeRigidAttachment(PxRigidActor* actor) = 0; + + + /** + \brief Enable continuous collision detection for particles + + \param[in] enable Boolean indicates whether continuous collision detection is enabled. + */ + virtual void enableCCD(bool enable) = 0; + + + /** + \brief Creates combined particle flag with particle material and particle phase flags. + + \param[in] material A material instance to associate with the new particle group. + \param[in] flags The particle phase flags. + \return The combined particle group index and phase flags. + + See #PxParticlePhaseFlag + */ + virtual PxU32 createPhase(PxParticleMaterial* material, PxParticlePhaseFlags flags) = 0; + + + /** + \brief Returns number of particle materials + \return The number of particle materials + */ + virtual PxU32 getNbParticleMaterials() const = 0; + + + /** + \brief Sets a user notify object which receives special simulation events when they occur. + + \note Do not set the callback while the simulation is running. Calls to this method while the simulation is running will be ignored. + \note A call to fetchResultsParticleSystem() on the PxScene will synchronize the work such that the caller knows that all worke done in the callback completed. + + \param[in] callback User notification callback. See PxSimulationEventCallback. + + See #PxParticleSystemCallback, #getParticleSystemCallback() + */ + virtual void setParticleSystemCallback(PxParticleSystemCallback* callback) = 0; + + /** + \brief Retrieves the simulationEventCallback pointer set with setSimulationEventCallback(). + \return The current user notify pointer. See PxSimulationEventCallback. + + See #PxParticleSystemCallback, #setParticleSystemCallback() + */ + virtual PxParticleSystemCallback* getParticleSystemCallback() const = 0; + + /** + \brief Sets periodic boundary wrap value + \param[in] boundary The periodic boundary wrap value + + See #getPeriodicBoundary() + */ + virtual void setPeriodicBoundary(const PxVec3& boundary) = 0; + + /** + \brief Gets periodic boundary wrap value + \return boundary The periodic boundary wrap value + + See #setPeriodicBoundary() + */ + virtual PxVec3 getPeriodicBoundary() const = 0; + + /** + \brief Add an existing particle buffer to the particle system. + \param[in] particleBuffer a PxParticleBuffer*. + + See #PxParticleBuffer. + */ + virtual void addParticleBuffer(PxParticleBuffer* particleBuffer) = 0; + + /** + \brief Remove particle buffer from the particle system. + \param[in] particleBuffer a PxParticleBuffer*. + + See #PxParticleBuffer. + */ + virtual void removeParticleBuffer(PxParticleBuffer* particleBuffer) = 0; + + /** + \brief Returns the GPU particle system index. + \return The GPU index, if the particle system is in a scene and PxSceneFlag::eSUPPRESS_READBACK is set, or 0xFFFFFFFF otherwise. + */ + virtual PxU32 getGpuParticleSystemIndex() = 0; + +protected: + + virtual ~PxParticleSystem() {} + + PX_INLINE PxParticleSystem(PxType concreteType, PxBaseFlags baseFlags) : PxActor(concreteType, baseFlags) {} + PX_INLINE PxParticleSystem(PxBaseFlags baseFlags) : PxActor(baseFlags) {} + virtual bool isKindOf(const char* name) const PX_OVERRIDE { return !::strcmp("PxParticleSystem", name) || PxActor::isKindOf(name); } +}; + + +#if PX_VC +#pragma warning(pop) +#endif + + +#if !PX_DOXYGEN +} // namespace physx +#endif + + /** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/PxParticleSystemFlag.h b/Source/ThirdParty/PhysX/PxParticleSystemFlag.h new file mode 100644 index 000000000..1544e490d --- /dev/null +++ b/Source/ThirdParty/PhysX/PxParticleSystemFlag.h @@ -0,0 +1,101 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_PARTICLE_SYSTEM_FLAG_H +#define PX_PARTICLE_SYSTEM_FLAG_H + +#include "foundation/PxFlags.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +/** +\brief Identifies dirty particle buffers that need to be updated in the particle system. + +This flag can be used mark the device user buffers that are dirty and need to be written to the particle system. +*/ +struct PxParticleBufferFlag +{ + enum Enum + { + eNONE = 0, //!< No data specified + + eUPDATE_POSITION = 1 << 0, //!< Specifies the position (first 3 floats) and inverse mass (last float) data (array of PxVec4 * number of particles) + eUPDATE_VELOCITY = 1 << 1, //!< Specifies the velocity (first 3 floats) data (array of PxVec4 * number of particles) + eUPDATE_PHASE = 1 << 2, //!< Specifies the per-particle phase flag data (array of PxU32 * number of particles) + eUPDATE_RESTPOSITION = 1 << 3, //!< Specifies the rest position (first 3 floats) data for cloth buffers + eUPDATE_CLOTH = 1 << 5, //!< Specifies the cloth buffer (see PxParticleClothBuffer) + eUPDATE_RIGID = 1 << 6, //!< Specifies the rigid buffer (see PxParticleRigidBuffer) + eUPDATE_DIFFUSE_PARAM = 1 << 7, //!< Specifies the diffuse particle parameter buffer (see PxDiffuseParticleParams) + eUPDATE_ATTACHMENTS = 1 << 8, //!< Specifies the attachments. + + eALL = + eUPDATE_POSITION | eUPDATE_VELOCITY | eUPDATE_PHASE | eUPDATE_RESTPOSITION | eUPDATE_CLOTH | eUPDATE_RIGID | eUPDATE_DIFFUSE_PARAM | eUPDATE_ATTACHMENTS + }; +}; + +typedef PxFlags PxParticleBufferFlags; + +/** +\brief A pair of particle buffer unique id and GPU particle system index. + +@see PxScene::applyParticleBufferData +*/ +struct PxGpuParticleBufferIndexPair +{ + PxU32 systemIndex; // gpu particle system index + PxU32 bufferIndex; // particle buffer unique id +}; + +/** +\brief Identifies per-particle behavior for a PxParticleSystem. + +See #PxParticleSystem::createPhase(). +*/ +struct PxParticlePhaseFlag +{ + enum Enum + { + eParticlePhaseGroupMask = 0x000fffff, //!< Bits [ 0, 19] represent the particle group for controlling collisions + eParticlePhaseFlagsMask = 0xfff00000, //!< Bits [20, 23] hold flags about how the particle behave + + eParticlePhaseSelfCollide = 1 << 20, //!< If set this particle will interact with particles of the same group + eParticlePhaseSelfCollideFilter = 1 << 21, //!< If set this particle will ignore collisions with particles closer than the radius in the rest pose, this flag should not be specified unless valid rest positions have been specified using setRestParticles() + eParticlePhaseFluid = 1 << 22 //!< If set this particle will generate fluid density constraints for its overlapping neighbors + }; +}; + +typedef PxFlags PxParticlePhaseFlags; + +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif diff --git a/Source/ThirdParty/PhysX/PxPhysXConfig.h b/Source/ThirdParty/PhysX/PxPhysXConfig.h index ea329bb25..a27531e40 100644 --- a/Source/ThirdParty/PhysX/PxPhysXConfig.h +++ b/Source/ThirdParty/PhysX/PxPhysXConfig.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_NX -#define PX_PHYSICS_NX +#ifndef PX_PHYSICS_CONFIG_H +#define PX_PHYSICS_CONFIG_H /** Configuration include file for PhysX SDK */ @@ -44,32 +42,6 @@ namespace physx { #endif -class PxPhysics; -class PxShape; - -class PxActor; -class PxRigidActor; -class PxRigidStatic; -class PxRigidDynamic; -class PxConstraint; -class PxConstraintDesc; - -class PxArticulation; -class PxArticulationReducedCoordinate; -class PxArticulationBase; -class PxArticulationLink; -class PxArticulationJoint; -class PxArticulationJointReducedCoordinate; -class PxArticulationJointBase; - -class PxMaterial; - -class PxScene; -class PxSceneDesc; -class PxTolerancesScale; - -class PxAggregate; - #if !PX_DOXYGEN } // namespace physx #endif diff --git a/Source/ThirdParty/PhysX/PxPhysics.h b/Source/ThirdParty/PhysX/PxPhysics.h index f8efe3f9a..21fe137f1 100644 --- a/Source/ThirdParty/PhysX/PxPhysics.h +++ b/Source/ThirdParty/PhysX/PxPhysics.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PX_PHYSICS_NX_PHYSICS -#define PX_PHYSICS_NX_PHYSICS +#ifndef PX_PHYSICS_H +#define PX_PHYSICS_H /** \addtogroup physics @{ @@ -38,14 +37,26 @@ #include "PxDeletionListener.h" #include "foundation/PxTransform.h" #include "PxShape.h" +#include "PxAggregate.h" +#include "PxBuffer.h" +#include "PxParticleSystem.h" +#include "foundation/PxPreprocessor.h" +#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION +#include "PxFEMCloth.h" +#include "PxHairSystem.h" +#endif #if !PX_DOXYGEN namespace physx { #endif +class PxScene; +class PxSceneDesc; +class PxTolerancesScale; class PxPvd; -class PxPhysicsInsertionCallback; +class PxOmniPvd; +class PxInsertionCallback; class PxRigidActor; class PxConstraintConnector; @@ -53,20 +64,28 @@ struct PxConstraintShaderTable; class PxGeometry; class PxFoundation; -class PxSerializationRegistry; class PxPruningStructure; -class PxBVHStructure; +class PxBVH; +/** + * @deprecated + */ +typedef PX_DEPRECATED PxBVH PxBVHStructure; + +class PxParticleClothBuffer; +class PxParticleRigidBuffer; + +class PxSoftBodyMesh; /** \brief Abstract singleton factory class used for instancing objects in the Physics SDK. -In addition you can use PxPhysics to set global parameters which will effect all scenes and create +In addition you can use PxPhysics to set global parameters which will effect all scenes and create objects that can be shared across multiple scenes. You can get an instance of this class by calling PxCreateBasePhysics() or PxCreatePhysics() with pre-registered modules. -@see PxCreatePhysics() PxCreateBasePhysics() PxScene PxVisualizationParameter +@see PxCreatePhysics() PxCreateBasePhysics() PxScene */ class PxPhysics { @@ -75,10 +94,10 @@ public: /** @name Basics */ //@{ - + virtual ~PxPhysics() {} - - /** + + /** \brief Destroys the instance it is called on. Use this release method to destroy an instance of this class. Be sure @@ -86,15 +105,15 @@ public: Avoid release calls while a scene is simulating (in between simulate() and fetchResults() calls). Note that this must be called once for each prior call to PxCreatePhysics, as - there is a reference counter. Also note that you mustn't destroy the allocator or the error callback (if available) until after the - reference count reaches 0 and the SDK is actually removed. + there is a reference counter. Also note that you mustn't destroy the PxFoundation instance (holding the allocator, error callback etc.) + until after the reference count reaches 0 and the SDK is actually removed. - Releasing an SDK will also release any scenes, triangle meshes, convex meshes, heightfields and shapes - created through it, provided the user hasn't already done so. + Releasing an SDK will also release any objects created through it (scenes, triangle meshes, convex meshes, heightfields, shapes etc.), + provided the user hasn't already done so. - \note This function is required to be called to release foundation usage. + \note Releasing the PxPhysics instance is a prerequisite to releasing the PxFoundation instance. - @see PxCreatePhysics() + @see PxCreatePhysics() PxFoundation */ virtual void release() = 0; @@ -102,24 +121,62 @@ public: \brief Retrieves the Foundation instance. \return A reference to the Foundation object. */ - virtual PxFoundation& getFoundation() = 0; - - /** - \brief Creates an aggregate with the specified maximum size and selfCollision property. + virtual PxFoundation& getFoundation() = 0; - \param [in] maxSize The maximum number of actors that may be placed in the aggregate. - \param [in] enableSelfCollision Whether the aggregate supports self-collision + /** + \brief Retrieves the PxOmniPvd instance if there is one registered with PxPhysics. + \return A pointer to a PxOmniPvd object. + */ + virtual PxOmniPvd* getOmniPvd() = 0; + + /** + \brief Creates an aggregate with the specified maximum size and filtering hint. + + The previous API used "bool enableSelfCollision" which should now silently evaluates + to a PxAggregateType::eGENERIC aggregate with its self-collision bit. + + Use PxAggregateType::eSTATIC or PxAggregateType::eKINEMATIC for aggregates that will + only contain static or kinematic actors. This provides faster filtering when used in + combination with PxPairFilteringMode. + + \param [in] maxActor The maximum number of actors that may be placed in the aggregate. + \param [in] maxShape The maximum number of shapes that may be placed in the aggregate. + \param [in] filterHint The aggregate's filtering hint. \return The new aggregate. - @see PxAggregate + @see PxAggregate PxAggregateFilterHint PxAggregateType PxPairFilteringMode */ - virtual PxAggregate* createAggregate(PxU32 maxSize, bool enableSelfCollision) = 0; + virtual PxAggregate* createAggregate(PxU32 maxActor, PxU32 maxShape, PxAggregateFilterHint filterHint) = 0; /** - \brief Returns the simulation tolerance parameters. - \return The current simulation tolerance parameters. + \brief Creates an aggregate with the specified maximum size and filtering hint. + + The previous API used "bool enableSelfCollision" which should now silently evaluates + to a PxAggregateType::eGENERIC aggregate with its self-collision bit. + + Use PxAggregateType::eSTATIC or PxAggregateType::eKINEMATIC for aggregates that will + only contain static or kinematic actors. This provides faster filtering when used in + combination with PxPairFilteringMode. + + \note This variation of the method is not compatible with GPU rigid bodies. + + \param [in] maxActor The maximum number of actors that may be placed in the aggregate. + \param [in] filterHint The aggregate's filtering hint. + \return The new aggregate. + + @see PxAggregate PxAggregateFilterHint PxAggregateType PxPairFilteringMode + @deprecated */ - virtual const PxTolerancesScale& getTolerancesScale() const = 0; + PX_FORCE_INLINE PX_DEPRECATED PxAggregate* createAggregate(PxU32 maxActor, PxAggregateFilterHint filterHint) + { + return createAggregate(maxActor, PX_MAX_U32, filterHint); + } + + /** + \brief Returns the simulation tolerance parameters. + \return The current simulation tolerance parameters. + */ + virtual const PxTolerancesScale& getTolerancesScale() const = 0; //@} /** @name Meshes @@ -136,8 +193,8 @@ public: @see PxTriangleMesh PxMeshPreprocessingFlag PxTriangleMesh.release() PxInputStream PxTriangleMeshFlag */ - virtual PxTriangleMesh* createTriangleMesh(PxInputStream& stream) = 0; - + virtual PxTriangleMesh* createTriangleMesh(PxInputStream& stream) = 0; + /** \brief Return the number of triangle meshes that currently exist. @@ -145,23 +202,76 @@ public: @see getTriangleMeshes() */ - virtual PxU32 getNbTriangleMeshes() const = 0; + virtual PxU32 getNbTriangleMeshes() const = 0; /** \brief Writes the array of triangle mesh pointers to a user buffer. - + Returns the number of pointers written. The ordering of the triangle meshes in the array is not specified. \param [out] userBuffer The buffer to receive triangle mesh pointers. \param [in] bufferSize The number of triangle mesh pointers which can be stored in the buffer. - \param [in] startIndex Index of first mesh pointer to be retrieved + \param [in] startIndex Index of first mesh pointer to be retrieved. \return The number of triangle mesh pointers written to userBuffer, this should be less or equal to bufferSize. @see getNbTriangleMeshes() PxTriangleMesh */ - virtual PxU32 getTriangleMeshes(PxTriangleMesh** userBuffer, PxU32 bufferSize, PxU32 startIndex=0) const = 0; + virtual PxU32 getTriangleMeshes(PxTriangleMesh** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0; + + + //@} + /** @name Tetrahedron Meshes + */ + //@{ + + /** + \brief Creates a tetrahedron mesh object. + + This can then be instanced into #PxShape objects. + + \param[in] stream The tetrahedron mesh stream. + \return The new tetrahedron mesh. + + @see PxTetrahedronMesh PxMeshPreprocessingFlag PxTetrahedronMesh.release() PxInputStream PxTriangleMeshFlag + */ + virtual PxTetrahedronMesh* createTetrahedronMesh(PxInputStream& stream) = 0; + + /** + \brief Creates a softbody mesh object. + + \param[in] stream The softbody mesh stream. + \return The new softbody mesh. + + @see createTetrahedronMesh + */ + virtual PxSoftBodyMesh* createSoftBodyMesh(PxInputStream& stream) = 0; + + /** + \brief Return the number of tetrahedron meshes that currently exist. + + \return Number of tetrahedron meshes. + + @see getTetrahedronMeshes() + */ + virtual PxU32 getNbTetrahedronMeshes() const = 0; + + /** + \brief Writes the array of tetrahedron mesh pointers to a user buffer. + + Returns the number of pointers written. + + The ordering of the tetrahedron meshes in the array is not specified. + + \param[out] userBuffer The buffer to receive tetrahedron mesh pointers. + \param[in] bufferSize The number of tetrahedron mesh pointers which can be stored in the buffer. + \param[in] startIndex Index of first mesh pointer to be retrieved. + \return The number of tetrahedron mesh pointers written to userBuffer, this should be less or equal to bufferSize. + + @see getNbTetrahedronMeshes() PxTetrahedronMesh + */ + virtual PxU32 getTetrahedronMeshes(PxTetrahedronMesh** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0; /** \brief Creates a heightfield object from previously cooked stream. @@ -173,7 +283,7 @@ public: @see PxHeightField PxHeightField.release() PxInputStream PxRegisterHeightFields */ - virtual PxHeightField* createHeightField(PxInputStream& stream) = 0; + virtual PxHeightField* createHeightField(PxInputStream& stream) = 0; /** \brief Return the number of heightfields that currently exist. @@ -182,23 +292,23 @@ public: @see getHeightFields() */ - virtual PxU32 getNbHeightFields() const = 0; + virtual PxU32 getNbHeightFields() const = 0; /** \brief Writes the array of heightfield pointers to a user buffer. - + Returns the number of pointers written. The ordering of the heightfields in the array is not specified. \param [out] userBuffer The buffer to receive heightfield pointers. \param [in] bufferSize The number of heightfield pointers which can be stored in the buffer. - \param [in] startIndex Index of first heightfield pointer to be retrieved + \param [in] startIndex Index of first heightfield pointer to be retrieved. \return The number of heightfield pointers written to userBuffer, this should be less or equal to bufferSize. @see getNbHeightFields() PxHeightField */ - virtual PxU32 getHeightFields(PxHeightField** userBuffer, PxU32 bufferSize, PxU32 startIndex=0) const = 0; + virtual PxU32 getHeightFields(PxHeightField** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0; /** \brief Creates a convex mesh object. @@ -210,7 +320,7 @@ public: @see PxConvexMesh PxConvexMesh.release() PxInputStream createTriangleMesh() PxConvexMeshGeometry PxShape */ - virtual PxConvexMesh* createConvexMesh(PxInputStream &stream) = 0; + virtual PxConvexMesh* createConvexMesh(PxInputStream& stream) = 0; /** \brief Return the number of convex meshes that currently exist. @@ -219,58 +329,82 @@ public: @see getConvexMeshes() */ - virtual PxU32 getNbConvexMeshes() const = 0; + virtual PxU32 getNbConvexMeshes() const = 0; /** \brief Writes the array of convex mesh pointers to a user buffer. - + Returns the number of pointers written. The ordering of the convex meshes in the array is not specified. \param [out] userBuffer The buffer to receive convex mesh pointers. \param [in] bufferSize The number of convex mesh pointers which can be stored in the buffer. - \param [in] startIndex Index of first convex mesh pointer to be retrieved + \param [in] startIndex Index of first convex mesh pointer to be retrieved. \return The number of convex mesh pointers written to userBuffer, this should be less or equal to bufferSize. @see getNbConvexMeshes() PxConvexMesh */ - virtual PxU32 getConvexMeshes(PxConvexMesh** userBuffer, PxU32 bufferSize, PxU32 startIndex=0) const = 0; + virtual PxU32 getConvexMeshes(PxConvexMesh** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0; /** - \brief Creates a bounding volume hierarchy structure. - - \param [in] stream The stream to load the BVH structure from. - \return The new BVH structure. + \brief Creates a bounding volume hierarchy. - @see PxBVHStructure PxInputStream + \param [in] stream The stream to load the BVH from. + \return The new BVH. + + @see PxBVH PxInputStream */ - virtual PxBVHStructure* createBVHStructure(PxInputStream &stream) = 0; + virtual PxBVH* createBVH(PxInputStream& stream) = 0; /** - \brief Return the number of bounding volume hierarchy structures that currently exist. + * @deprecated + */ + PX_DEPRECATED PX_FORCE_INLINE PxBVH* createBVHStructure(PxInputStream& stream) + { + return createBVH(stream); + } - \return Number of bounding volume hierarchy structures. + /** + \brief Return the number of bounding volume hierarchies that currently exist. - @see getBVHStructures() + \return Number of bounding volume hierarchies. + + @see PxBVH getBVHs() */ - virtual PxU32 getNbBVHStructures() const = 0; + virtual PxU32 getNbBVHs() const = 0; /** - \brief Writes the array of bounding volume hierarchy structure pointers to a user buffer. - + * @deprecated + */ + PX_DEPRECATED PX_FORCE_INLINE PxU32 getNbBVHStructures() const + { + return getNbBVHs(); + } + + /** + \brief Writes the array of bounding volume hierarchy pointers to a user buffer. + Returns the number of pointers written. - The ordering of the BVH structures in the array is not specified. + The ordering of the BVHs in the array is not specified. - \param [out] userBuffer The buffer to receive BVH structure pointers. - \param [in] bufferSize The number of BVH structure pointers which can be stored in the buffer. - \param [in] startIndex Index of first BVH structure pointer to be retrieved - \return The number of BVH structure pointers written to userBuffer, this should be less or equal to bufferSize. + \param [out] userBuffer The buffer to receive BVH pointers. + \param [in] bufferSize The number of BVH pointers which can be stored in the buffer. + \param [in] startIndex Index of first BVH pointer to be retrieved. + \return The number of BVH pointers written to userBuffer, this should be less or equal to bufferSize. - @see getNbBVHStructures() PxBVHStructure + @see getNbBVHs() PxBVH */ - virtual PxU32 getBVHStructures(PxBVHStructure** userBuffer, PxU32 bufferSize, PxU32 startIndex=0) const = 0; + virtual PxU32 getBVHs(PxBVH** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0; + + /** + * @deprecated + */ + PX_DEPRECATED PX_FORCE_INLINE PxU32 getBVHStructures(PxBVHStructure** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const + { + return getBVHs(userBuffer, bufferSize, startIndex); + } //@} /** @name Scenes @@ -288,33 +422,33 @@ public: @see PxScene PxScene.release() PxSceneDesc */ - virtual PxScene* createScene(const PxSceneDesc& sceneDesc) = 0; + virtual PxScene* createScene(const PxSceneDesc& sceneDesc) = 0; /** \brief Gets number of created scenes. \return The number of scenes created. - @see getScene() + @see getScenes() */ - virtual PxU32 getNbScenes() const = 0; + virtual PxU32 getNbScenes() const = 0; /** \brief Writes the array of scene pointers to a user buffer. - + Returns the number of pointers written. The ordering of the scene pointers in the array is not specified. \param [out] userBuffer The buffer to receive scene pointers. \param [in] bufferSize The number of scene pointers which can be stored in the buffer. - \param [in] startIndex Index of first scene pointer to be retrieved + \param [in] startIndex Index of first scene pointer to be retrieved. \return The number of scene pointers written to userBuffer, this should be less or equal to bufferSize. @see getNbScenes() PxScene */ - virtual PxU32 getScenes(PxScene** userBuffer, PxU32 bufferSize, PxU32 startIndex=0) const = 0; - + virtual PxU32 getScenes(PxScene** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0; + //@} /** @name Actors */ @@ -323,22 +457,22 @@ public: /** \brief Creates a static rigid actor with the specified pose and all other fields initialized to their default values. - - \param [in] pose The initial pose of the actor. Must be a valid transform + + \param [in] pose The initial pose of the actor. Must be a valid transform. @see PxRigidStatic */ - virtual PxRigidStatic* createRigidStatic(const PxTransform& pose) = 0; + virtual PxRigidStatic* createRigidStatic(const PxTransform& pose) = 0; /** \brief Creates a dynamic rigid actor with the specified pose and all other fields initialized to their default values. - - \param [in] pose The initial pose of the actor. Must be a valid transform + + \param [in] pose The initial pose of the actor. Must be a valid transform. @see PxRigidDynamic */ - virtual PxRigidDynamic* createRigidDynamic(const PxTransform& pose) = 0; + virtual PxRigidDynamic* createRigidDynamic(const PxTransform& pose) = 0; /** \brief Creates a pruning structure from actors. @@ -353,39 +487,90 @@ public: \return Pruning structure created from given actors, or NULL if any of the actors did not comply with the above requirements. @see PxActor PxPruningStructure */ - virtual PxPruningStructure* createPruningStructure(PxRigidActor*const* actors, PxU32 nbActors) = 0; + virtual PxPruningStructure* createPruningStructure(PxRigidActor*const* actors, PxU32 nbActors) = 0; //@} /** @name Shapes */ //@{ - + /** \brief Creates a shape which may be attached to multiple actors - + The shape will be created with a reference count of 1. \param [in] geometry The geometry for the shape \param [in] material The material for the shape \param [in] isExclusive Whether this shape is exclusive to a single actor or maybe be shared \param [in] shapeFlags The PxShapeFlags to be set + \return The shape - Shared shapes are not mutable when they are attached to an actor + \note Shared shapes are not mutable when they are attached to an actor @see PxShape */ - PX_FORCE_INLINE PxShape* createShape( const PxGeometry& geometry, - const PxMaterial& material, - bool isExclusive = false, - PxShapeFlags shapeFlags = PxShapeFlag::eVISUALIZATION | PxShapeFlag::eSCENE_QUERY_SHAPE | PxShapeFlag::eSIMULATION_SHAPE) + PX_FORCE_INLINE PxShape* createShape( const PxGeometry& geometry, + const PxMaterial& material, + bool isExclusive = false, + PxShapeFlags shapeFlags = PxShapeFlag::eVISUALIZATION | PxShapeFlag::eSCENE_QUERY_SHAPE | PxShapeFlag::eSIMULATION_SHAPE) { PxMaterial* materialPtr = const_cast(&material); return createShape(geometry, &materialPtr, 1, isExclusive, shapeFlags); } + /** + \brief Creates a shape which may be attached to one or more softbody actors + + The shape will be created with a reference count of 1. + + \param [in] geometry The geometry for the shape + \param [in] material The material for the shape + \param [in] isExclusive Whether this shape is exclusive to a single actor or maybe be shared + \param [in] shapeFlags The PxShapeFlags to be set + \return The shape + + \note Shared shapes are not mutable when they are attached to an actor + + @see PxShape + */ + PX_FORCE_INLINE PxShape* createShape( const PxGeometry& geometry, + const PxFEMSoftBodyMaterial& material, + bool isExclusive = false, + PxShapeFlags shapeFlags = PxShapeFlag::eVISUALIZATION | PxShapeFlag::eSCENE_QUERY_SHAPE | PxShapeFlag::eSIMULATION_SHAPE) + { + PxFEMSoftBodyMaterial* materialPtr = const_cast(&material); + return createShape(geometry, &materialPtr, 1, isExclusive, shapeFlags); + } + +#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION + /** + \brief Creates a shape which may be attached to one or more FEMCloth actors + + The shape will be created with a reference count of 1. + + \param [in] geometry The geometry for the shape + \param [in] material The material for the shape + \param [in] isExclusive Whether this shape is exclusive to a single actor or maybe be shared + \param [in] shapeFlags The PxShapeFlags to be set + \return The shape + + \note Shared shapes are not mutable when they are attached to an actor + + @see PxShape + */ + PX_FORCE_INLINE PxShape* createShape( const PxGeometry& geometry, + const PxFEMClothMaterial& material, + bool isExclusive = false, + PxShapeFlags shapeFlags = PxShapeFlag::eVISUALIZATION | PxShapeFlag::eSCENE_QUERY_SHAPE | PxShapeFlag::eSIMULATION_SHAPE) + { + PxFEMClothMaterial* materialPtr = const_cast(&material); + return createShape(geometry, &materialPtr, 1, isExclusive, shapeFlags); + } +#endif + /** \brief Creates a shape which may be attached to multiple actors - + The shape will be created with a reference count of 1. \param [in] geometry The geometry for the shape @@ -393,16 +578,30 @@ public: \param [in] materialCount The number of materials \param [in] isExclusive Whether this shape is exclusive to a single actor or may be shared \param [in] shapeFlags The PxShapeFlags to be set + \return The shape - Shared shapes are not mutable when they are attached to an actor + \note Shared shapes are not mutable when they are attached to an actor + \note Shapes created from *SDF* triangle-mesh geometries do not support more than one material. @see PxShape */ - virtual PxShape* createShape(const PxGeometry& geometry, - PxMaterial*const * materials, - PxU16 materialCount, - bool isExclusive = false, - PxShapeFlags shapeFlags = PxShapeFlag::eVISUALIZATION | PxShapeFlag::eSCENE_QUERY_SHAPE | PxShapeFlag::eSIMULATION_SHAPE) = 0; + virtual PxShape* createShape( const PxGeometry& geometry, + PxMaterial*const * materials, + PxU16 materialCount, + bool isExclusive = false, + PxShapeFlags shapeFlags = PxShapeFlag::eVISUALIZATION | PxShapeFlag::eSCENE_QUERY_SHAPE | PxShapeFlag::eSIMULATION_SHAPE) = 0; + + virtual PxShape* createShape( const PxGeometry& geometry, + PxFEMSoftBodyMaterial*const * materials, + PxU16 materialCount, + bool isExclusive = false, + PxShapeFlags shapeFlags = PxShapeFlag::eVISUALIZATION | PxShapeFlag::eSCENE_QUERY_SHAPE | PxShapeFlag::eSIMULATION_SHAPE) = 0; + + virtual PxShape* createShape( const PxGeometry& geometry, + PxFEMClothMaterial*const * materials, + PxU16 materialCount, + bool isExclusive = false, + PxShapeFlags shapeFlags = PxShapeFlag::eVISUALIZATION | PxShapeFlag::eSCENE_QUERY_SHAPE | PxShapeFlag::eSIMULATION_SHAPE) = 0; /** \brief Return the number of shapes that currently exist. @@ -411,11 +610,11 @@ public: @see getShapes() */ - virtual PxU32 getNbShapes() const = 0; + virtual PxU32 getNbShapes() const = 0; /** \brief Writes the array of shape pointers to a user buffer. - + Returns the number of pointers written. The ordering of the shapes in the array is not specified. @@ -427,7 +626,7 @@ public: @see getNbShapes() PxShape */ - virtual PxU32 getShapes(PxShape** userBuffer, PxU32 bufferSize, PxU32 startIndex=0) const = 0; + virtual PxU32 getShapes(PxShape** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0; //@} /** @name Constraints and Articulations @@ -439,81 +638,470 @@ public: \note A constraint shader will get added automatically to the scene the two linked actors belong to. Either, but not both, of actor0 and actor1 may be NULL to denote attachment to the world. - + \param [in] actor0 The first actor \param [in] actor1 The second actor \param [in] connector The connector object, which the SDK uses to communicate with the infrastructure for the constraint \param [in] shaders The shader functions for the constraint \param [in] dataSize The size of the data block for the shader - \return The new shader. + \return The new constraint shader. @see PxConstraint */ - virtual PxConstraint* createConstraint(PxRigidActor* actor0, PxRigidActor* actor1, PxConstraintConnector& connector, const PxConstraintShaderTable& shaders, PxU32 dataSize) = 0; + virtual PxConstraint* createConstraint(PxRigidActor* actor0, PxRigidActor* actor1, PxConstraintConnector& connector, const PxConstraintShaderTable& shaders, PxU32 dataSize) = 0; /** - \brief Creates an articulation with all fields initialized to their default values. - - \return the new articulation - - @see PxArticulation, PxRegisterArticulations - */ - virtual PxArticulation* createArticulation() = 0; - - /** - \brief Creates a reduced coordinate articulation with all fields initialized to their default values. + \brief Creates a reduced-coordinate articulation with all fields initialized to their default values. \return the new articulation @see PxArticulationReducedCoordinate, PxRegisterArticulationsReducedCoordinate */ - virtual PxArticulationReducedCoordinate* createArticulationReducedCoordinate() = 0; + virtual PxArticulationReducedCoordinate* createArticulationReducedCoordinate() = 0; + /** + \brief Creates a FEM-based cloth with all fields initialized to their default values. + \warning Feature under development, only for internal usage. + + \param[in] cudaContextManager The PxCudaContextManager this instance is tied to. + \return the new FEM-cloth + + @see PxFEMCloth + */ + virtual PxFEMCloth* createFEMCloth(PxCudaContextManager& cudaContextManager) = 0; + + /** + \brief Creates a FEM-based soft body with all fields initialized to their default values. + + \param[in] cudaContextManager The PxCudaContextManager this instance is tied to. + \return the new soft body + + @see PxSoftBody + */ + virtual PxSoftBody* createSoftBody(PxCudaContextManager& cudaContextManager) = 0; + + /** + \brief Creates a hair system with all fields initialized to their default values. + \warning Feature under development, only for internal usage. + + \param[in] cudaContextManager The PxCudaContextManager this instance is tied to. + \return the new hair system + + @see PxHairSystem + */ + virtual PxHairSystem* createHairSystem(PxCudaContextManager& cudaContextManager) = 0; + + /** + \brief Creates a particle system with a position-based dynamics (PBD) solver. + + A PBD particle system can be used to simulate particle systems with fluid and granular particles. It also allows simulating cloth using + mass-spring constraints and rigid bodies by shape matching the bodies with particles. + + \param[in] cudaContextManager The PxCudaContextManager this instance is tied to. + \param[in] maxNeighborhood The maximum number of particles considered in neighborhood-based particle interaction calculations (e.g. fluid density constraints). + \return the new particle system + + @see PxPBDParticleSystem + */ + virtual PxPBDParticleSystem* createPBDParticleSystem(PxCudaContextManager& cudaContextManager, PxU32 maxNeighborhood = 96) = 0; + + /** + \brief Creates a particle system with a fluid-implicit particle solver (FLIP). + \warning Feature under development, only for internal usage. + + \param[in] cudaContextManager The PxCudaContextManager this instance is tied to. + \return the new particle system + + @see PxFLIPParticleSystem + */ + virtual PxFLIPParticleSystem* createFLIPParticleSystem(PxCudaContextManager& cudaContextManager) = 0; + + /** + \brief Creates a particle system with a material-point-method solver (MPM). + \warning Feature under development, only for internal usage. + + A MPM particle system can be used to simulate fluid dynamics and deformable body effects using particles. + + \param[in] cudaContextManager The PxCudaContextManager this instance is tied to. + \return the new particle system + + @see PxMPMParticleSystem + */ + virtual PxMPMParticleSystem* createMPMParticleSystem(PxCudaContextManager& cudaContextManager) = 0; + + /** + \brief Creates a customizable particle system to simulate effects that are not supported by PhysX natively (e.g. molecular dynamics). + \warning Feature under development, only for internal usage. + + \param[in] cudaContextManager The PxCudaContextManager this instance is tied to. + \param[in] maxNeighborhood The maximum number of particles considered in neighborhood-based particle interaction calculations (e.g. fluid density constraints). + \return the new particle system + + @see PxCustomParticleSystem + */ + virtual PxCustomParticleSystem* createCustomParticleSystem(PxCudaContextManager& cudaContextManager, PxU32 maxNeighborhood) = 0; + + /** + \brief Create a buffer for reading and writing data across host and device memory spaces. + + \param[in] byteSize The size of the buffer in bytes. + \param[in] bufferType The memory space of the buffer. + \param[in] cudaContextManager The PxCudaContextManager this buffer is tied to. + \return PxBuffer instance. + + @see PxBuffer + */ + virtual PxBuffer* createBuffer(PxU64 byteSize, PxBufferType::Enum bufferType, PxCudaContextManager* cudaContextManager) = 0; + + /** + \brief Create particle buffer to simulate fluid/granular material. + + \param[in] maxParticles The maximum number of particles in this buffer. + \param[in] maxVolumes The maximum number of volumes in this buffer. See PxParticleVolume. + \param[in] cudaContextManager The PxCudaContextManager this buffer is tied to. + \return PxParticleBuffer instance + + @see PxParticleBuffer + */ + virtual PxParticleBuffer* createParticleBuffer(PxU32 maxParticles, PxU32 maxVolumes, PxCudaContextManager* cudaContextManager) = 0; + + /** + \brief Create a particle buffer for fluid dynamics with diffuse particles. Diffuse particles are used to simulate fluid effects + such as foam, spray and bubbles. + + \param[in] maxParticles The maximum number of particles in this buffer. + \param[in] maxVolumes The maximum number of volumes in this buffer. See #PxParticleVolume. + \param[in] maxDiffuseParticles The max number of diffuse particles int this buffer. + \param[in] cudaContextManager The PxCudaContextManager this buffer is tied to. + \return PxParticleAndDiffuseBuffer instance + + @see PxParticleAndDiffuseBuffer, PxDiffuseParticleParams + */ + virtual PxParticleAndDiffuseBuffer* createParticleAndDiffuseBuffer(PxU32 maxParticles, PxU32 maxVolumes, PxU32 maxDiffuseParticles, PxCudaContextManager* cudaContextManager) = 0; + + /** + \brief Create a particle buffer to simulate particle cloth. + + \param[in] maxParticles The maximum number of particles in this buffer. + \param[in] maxNumVolumes The maximum number of volumes in this buffer. See #PxParticleVolume. + \param[in] maxNumCloths The maximum number of cloths in this buffer. See #PxParticleCloth. + \param[in] maxNumTriangles The maximum number of triangles for aerodynamics. + \param[in] maxNumSprings The maximum number of springs to connect particles. See #PxParticleSpring. + \param[in] cudaContextManager The PxCudaContextManager this buffer is tied to. + \return PxParticleClothBuffer instance + + @see PxParticleClothBuffer + */ + virtual PxParticleClothBuffer* createParticleClothBuffer(PxU32 maxParticles, PxU32 maxNumVolumes, PxU32 maxNumCloths, PxU32 maxNumTriangles, PxU32 maxNumSprings, PxCudaContextManager* cudaContextManager) = 0; + + /** + \brief Create a particle buffer to simulate rigid bodies using shape matching with particles. + + \param[in] maxParticles The maximum number of particles in this buffer. + \param[in] maxNumVolumes The maximum number of volumes in this buffer. See #PxParticleVolume. + \param[in] maxNumRigids The maximum number of rigid bodies this buffer is used to simulate. + \param[in] cudaContextManager The PxCudaContextManager this buffer is tied to. + \return PxParticleRigidBuffer instance + + @see PxParticleRigidBuffer + */ + virtual PxParticleRigidBuffer* createParticleRigidBuffer(PxU32 maxParticles, PxU32 maxNumVolumes, PxU32 maxNumRigids, PxCudaContextManager* cudaContextManager) = 0; + //@} /** @name Materials */ //@{ /** - \brief Creates a new material with default properties. + \brief Creates a new rigid body material with certain default properties. - \return The new material. + \return The new rigid body material. \param [in] staticFriction The coefficient of static friction \param [in] dynamicFriction The coefficient of dynamic friction \param [in] restitution The coefficient of restitution - @see PxMaterial + @see PxMaterial */ - virtual PxMaterial* createMaterial(PxReal staticFriction, PxReal dynamicFriction, PxReal restitution) = 0; - + virtual PxMaterial* createMaterial(PxReal staticFriction, PxReal dynamicFriction, PxReal restitution) = 0; /** - \brief Return the number of materials that currently exist. + \brief Return the number of rigid body materials that currently exist. - \return Number of materials. + \return Number of rigid body materials. @see getMaterials() */ - virtual PxU32 getNbMaterials() const = 0; + virtual PxU32 getNbMaterials() const = 0; /** - \brief Writes the array of material pointers to a user buffer. - + \brief Writes the array of rigid body material pointers to a user buffer. + Returns the number of pointers written. The ordering of the materials in the array is not specified. \param [out] userBuffer The buffer to receive material pointers. \param [in] bufferSize The number of material pointers which can be stored in the buffer. - \param [in] startIndex Index of first material pointer to be retrieved + \param [in] startIndex Index of first material pointer to be retrieved. \return The number of material pointers written to userBuffer, this should be less or equal to bufferSize. @see getNbMaterials() PxMaterial */ - virtual PxU32 getMaterials(PxMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex=0) const = 0; + virtual PxU32 getMaterials(PxMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0; + + /** + \brief Creates a new FEM soft body material with certain default properties. + + \return The new FEM material. + + \param [in] youngs The young's modulus + \param [in] poissons The poissons's ratio + \param [in] dynamicFriction The dynamic friction coefficient + + @see PxFEMSoftBodyMaterial + */ + virtual PxFEMSoftBodyMaterial* createFEMSoftBodyMaterial(PxReal youngs, PxReal poissons, PxReal dynamicFriction) = 0; + + /** + \brief Return the number of FEM soft body materials that currently exist. + + \return Number of FEM materials. + + @see getFEMSoftBodyMaterials() + */ + virtual PxU32 getNbFEMSoftBodyMaterials() const = 0; + + /** + \brief Writes the array of FEM soft body material pointers to a user buffer. + + Returns the number of pointers written. + + The ordering of the materials in the array is not specified. + + \param [out] userBuffer The buffer to receive material pointers. + \param [in] bufferSize The number of material pointers which can be stored in the buffer. + \param [in] startIndex Index of first material pointer to be retrieved. + \return The number of material pointers written to userBuffer, this should be less or equal to bufferSize. + + @see getNbFEMSoftBodyMaterials() PxFEMSoftBodyMaterial + */ + virtual PxU32 getFEMSoftBodyMaterials(PxFEMSoftBodyMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0; + + /** + \brief Creates a new FEM cloth material with certain default properties. + \warning Feature under development, only for internal usage. + + \return The new FEM material. + + \param [in] youngs The young's modulus + \param [in] poissons The poissons's ratio + \param [in] dynamicFriction The dynamic friction coefficient + + @see PxFEMClothMaterial + */ + virtual PxFEMClothMaterial* createFEMClothMaterial(PxReal youngs, PxReal poissons, PxReal dynamicFriction) = 0; + + /** + \brief Return the number of FEM cloth materials that currently exist. + + \return Number of FEM cloth materials. + + @see getFEMClothMaterials() + */ + virtual PxU32 getNbFEMClothMaterials() const = 0; + + /** + \brief Writes the array of FEM cloth material pointers to a user buffer. + + Returns the number of pointers written. + + The ordering of the materials in the array is not specified. + + \param [out] userBuffer The buffer to receive material pointers. + \param [in] bufferSize The number of material pointers which can be stored in the buffer. + \param [in] startIndex Index of first material pointer to be retrieved. + \return The number of material pointers written to userBuffer, this should be less or equal to bufferSize. + + @see getNbFEMClothMaterials() PxFEMClothMaterial + */ + virtual PxU32 getFEMClothMaterials(PxFEMClothMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0; + + /** + \brief Creates a new PBD material with certain default properties. + + \param [in] friction The friction parameter + \param [in] damping The velocity damping parameter + \param [in] adhesion The adhesion parameter + \param [in] viscosity The viscosity parameter + \param [in] vorticityConfinement The vorticity confinement coefficient + \param [in] surfaceTension The surface tension coefficient + \param [in] cohesion The cohesion parameter + \param [in] lift The lift parameter + \param [in] drag The drag parameter + \param [in] cflCoefficient The Courant-Friedrichs-Lewy(cfl) coefficient + \param [in] gravityScale The gravity scale + \return The new PBD material. + + @see PxPBDMaterial + */ + virtual PxPBDMaterial* createPBDMaterial(PxReal friction, PxReal damping, PxReal adhesion, PxReal viscosity, PxReal vorticityConfinement, PxReal surfaceTension, PxReal cohesion, PxReal lift, PxReal drag, PxReal cflCoefficient = 1.f, PxReal gravityScale = 1.f) = 0; + + /** + \brief Return the number of PBD materials that currently exist. + + \return Number of PBD materials. + + @see getPBDMaterials() + */ + virtual PxU32 getNbPBDMaterials() const = 0; + + /** + \brief Writes the array of PBD material pointers to a user buffer. + + Returns the number of pointers written. + + The ordering of the materials in the array is not specified. + + \param [out] userBuffer The buffer to receive material pointers. + \param [in] bufferSize The number of material pointers which can be stored in the buffer. + \param [in] startIndex Index of first material pointer to be retrieved. + \return The number of material pointers written to userBuffer, this should be less or equal to bufferSize. + + @see getNbPBDMaterials() PxPBDMaterial + */ + virtual PxU32 getPBDMaterials(PxPBDMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0; + + /** + \brief Creates a new FLIP material with certain default properties. + \warning Feature under development, only for internal usage. + + \param [in] friction The friction parameter + \param [in] damping The velocity damping parameter + \param [in] adhesion The maximum velocity magnitude of particles + \param [in] viscosity The viscosity parameter + \param [in] gravityScale The gravity scale + \return The new FLIP material. + + @see PxFLIPMaterial + */ + virtual PxFLIPMaterial* createFLIPMaterial(PxReal friction, PxReal damping, PxReal adhesion, PxReal viscosity, PxReal gravityScale = 1.f) = 0; + + /** + \brief Return the number of FLIP materials that currently exist. + \warning Feature under development, only for internal usage. + + \return Number of FLIP materials. + + @see getFLIPMaterials() + */ + virtual PxU32 getNbFLIPMaterials() const = 0; + + /** + \brief Writes the array of FLIP material pointers to a user buffer. + \warning Feature under development, only for internal usage. + + Returns the number of pointers written. + + The ordering of the materials in the array is not specified. + + \param [out] userBuffer The buffer to receive material pointers. + \param [in] bufferSize The number of material pointers which can be stored in the buffer. + \param [in] startIndex Index of first material pointer to be retrieved. + \return The number of material pointers written to userBuffer, this should be less or equal to bufferSize. + + @see getNbFLIPMaterials() PxFLIPMaterial + */ + virtual PxU32 getFLIPMaterials(PxFLIPMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0; + + /** + \brief Creates a new MPM material with certain default properties. + \warning Feature under development, only for internal usage. + + \param [in] friction The friction parameter + \param [in] damping The velocity damping parameter + \param [in] adhesion The maximum velocity magnitude of particles + \param [in] isPlastic True if plastic + \param [in] youngsModulus The Young's modulus + \param [in] poissons The Poissons's ratio + \param [in] hardening The hardening parameter + \param [in] criticalCompression The critical compression parameter + \param [in] criticalStretch The critical stretch parameter + \param [in] tensileDamageSensitivity The tensile damage sensitivity parameter + \param [in] compressiveDamageSensitivity The compressive damage sensitivity parameter + \param [in] attractiveForceResidual The attractive force residual parameter + \param [in] gravityScale The gravity scale + \return The new MPM material. + + @see PxMPMMaterial + */ + virtual PxMPMMaterial* createMPMMaterial(PxReal friction, PxReal damping, PxReal adhesion, bool isPlastic, PxReal youngsModulus, PxReal poissons, PxReal hardening, PxReal criticalCompression, PxReal criticalStretch, PxReal tensileDamageSensitivity, PxReal compressiveDamageSensitivity, PxReal attractiveForceResidual, PxReal gravityScale = 1.0f) = 0; + + /** + \brief Return the number of MPM materials that currently exist. + \warning Feature under development, only for internal usage. + + \return Number of MPM materials. + + @see getMPMMaterials() + */ + virtual PxU32 getNbMPMMaterials() const = 0; + + /** + \brief Writes the array of MPM material pointers to a user buffer. + \warning Feature under development, only for internal usage. + + Returns the number of pointers written. + + The ordering of the materials in the array is not specified. + + \param [out] userBuffer The buffer to receive material pointers. + \param [in] bufferSize The number of material pointers which can be stored in the buffer. + \param [in] startIndex Index of first material pointer to be retrieved. + \return The number of material pointers written to userBuffer, this should be less or equal to bufferSize. + + @see getNbMPMMaterials() PxMPMMaterial + */ + virtual PxU32 getMPMMaterials(PxMPMMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0; + + /** + \brief Creates a new material for custom particle systems. + \warning Feature under development, only for internal usage. + + \param[in] gpuBuffer A pointer to a GPU buffer containing material parameters. + \return the new material. + */ + virtual PxCustomMaterial* createCustomMaterial(void* gpuBuffer) = 0; + + /** + \brief Return the number of custom materials that currently exist. + \warning Feature under development, only for internal usage. + + \return Number of custom materials. + + @see getCustomMaterials() + */ + virtual PxU32 getNbCustomMaterials() const = 0; + + /** + \brief Writes the array of custom material pointers to a user buffer. + \warning Feature under development, only for internal usage. + + Returns the number of pointers written. + + The ordering of the materials in the array is not specified. + + \param [out] userBuffer The buffer to receive material pointers. + \param [in] bufferSize The number of material pointers which can be stored in the buffer. + \param [in] startIndex Index of first material pointer to be retrieved. + \return The number of material pointers written to userBuffer, this should be less or equal to bufferSize. + + @see getNbCustomMaterials() PxCustomMaterial + */ + virtual PxU32 getCustomMaterials(PxCustomMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0; + //@} /** @name Deletion Listeners @@ -538,11 +1126,11 @@ public: virtual void registerDeletionListener(PxDeletionListener& observer, const PxDeletionEventFlags& deletionEvents, bool restrictedObjectSet = false) = 0; /** - \brief Unregister a deletion listener. + \brief Unregister a deletion listener. It is illegal to register or unregister a deletion listener while deletions are being processed. - \param [in] observer Observer object to send notifications to + \param [in] observer Observer object to stop sending notifications to. @see PxDeletionListener registerDeletionListener */ @@ -555,7 +1143,7 @@ public: \note It is illegal to register or unregister objects while deletions are being processed. - \note The deletion listener has to be registered through #registerDeletionListener() and configured to support restricted objects sets prior to this method being used. + \note The deletion listener has to be registered through #registerDeletionListener() and configured to support restricted object sets prior to this method being used. \param [in] observer Observer object to send notifications to. \param [in] observables List of objects for which to receive deletion events. Only PhysX core objects are supported. In the case of PxJoint objects, the underlying PxConstraint can be used to get the events. @@ -572,7 +1160,7 @@ public: \note It is illegal to register or unregister objects while deletions are being processed. - \note The deletion listener has to be registered through #registerDeletionListener() and configured to support restricted objects sets prior to this method being used. + \note The deletion listener has to be registered through #registerDeletionListener() and configured to support restricted object sets prior to this method being used. \param [in] observer Observer object to stop sending notifications to. \param [in] observables List of objects for which to not receive deletion events anymore. @@ -583,14 +1171,14 @@ public: virtual void unregisterDeletionListenerObjects(PxDeletionListener& observer, const PxBase* const* observables, PxU32 observableCount) = 0; /** - \brief Gets PxPhysics object insertion interface. + \brief Gets PxPhysics object insertion interface. - The insertion interface is needed ie. for PxCooking::createTriangleMesh, this allows runtime mesh creation. This is not advised to do, please - use offline cooking if possible. + The insertion interface is needed for PxCreateTriangleMesh, PxCooking::createTriangleMesh etc., this allows runtime mesh creation. - @see PxCooking::createTriangleMesh PxCooking::createHeightfield + @see PxCreateTriangleMesh PxCreateHeightField PxCreateTetrahedronMesh PxCreateBVH + PxCooking::createTriangleMesh PxCooking::createHeightfield PxCooking::createTetrahedronMesh PxCooking::createBVH */ - virtual PxPhysicsInsertionCallback& getPhysicsInsertionCallback() = 0; + virtual PxInsertionCallback& getPhysicsInsertionCallback() = 0; //@} }; @@ -600,106 +1188,107 @@ public: #endif /** -\brief Enables the usage of the articulations feature. This function is called automatically inside PxCreatePhysics(). -On resource constrained platforms, it is possible to call PxCreateBasePhysics() and then NOT call this function -to save on code memory if your application does not use articulations. In this case the linker should strip out -the relevant implementation code from the library. If you need to use articulations but not some other optional -component, you shoud call PxCreateBasePhysics() followed by this call. -*/ -PX_C_EXPORT PX_PHYSX_CORE_API void PX_CALL_CONV PxRegisterArticulations(physx::PxPhysics& physics); - - -/** -\brief Enables the usage of the reduced coordinate articulations feature. This function is called automatically inside PxCreatePhysics(). +\brief Enables the usage of the reduced coordinate articulations feature. This function is called automatically inside PxCreatePhysics(). On resource constrained platforms, it is possible to call PxCreateBasePhysics() and then NOT call this function -to save on code memory if your application does not use articulations. In this case the linker should strip out -the relevant implementation code from the library. If you need to use articulations but not some other optional +to save on code memory if your application does not use reduced coordinate articulations. In this case the linker should strip out +the relevant implementation code from the library. If you need to use reduced coordinate articulations but not some other optional component, you shoud call PxCreateBasePhysics() followed by this call. + +@deprecated */ -PX_C_EXPORT PX_PHYSX_CORE_API void PX_CALL_CONV PxRegisterArticulationsReducedCoordinate(physx::PxPhysics& physics); +PX_DEPRECATED PX_C_EXPORT PX_PHYSX_CORE_API void PX_CALL_CONV PxRegisterArticulationsReducedCoordinate(physx::PxPhysics& physics); /** -\brief Enables the usage of the heightfield feature. +\brief Enables the usage of the heightfield feature. This call will link the default 'unified' implementation of heightfields which is identical to the narrow phase of triangle meshes. This function is called automatically inside PxCreatePhysics(). On resource constrained platforms, it is possible to call PxCreateBasePhysics() and then NOT call this function -to save on code memory if your application does not use heightfields. In this case the linker should strip out -the relevant implementation code from the library. If you need to use heightfield but not some other optional +to save on code memory if your application does not use heightfields. In this case the linker should strip out +the relevant implementation code from the library. If you need to use heightfield but not some other optional component, you shoud call PxCreateBasePhysics() followed by this call. You must call this function at a time where no ::PxScene instance exists, typically before calling PxPhysics::createScene(). This is to prevent a change to the heightfield implementation code at runtime which would have undefined results. -Calling PxCreateBasePhysics() and then attempting to create a heightfield shape without first calling +Calling PxCreateBasePhysics() and then attempting to create a heightfield shape without first calling ::PxRegisterHeightFields(), will result in an error. + +@deprecated */ -PX_C_EXPORT PX_PHYSX_CORE_API void PX_CALL_CONV PxRegisterHeightFields(physx::PxPhysics& physics); +PX_DEPRECATED PX_C_EXPORT PX_PHYSX_CORE_API void PX_CALL_CONV PxRegisterHeightFields(physx::PxPhysics& physics); /** \brief Creates an instance of the physics SDK with minimal additional components registered Creates an instance of this class. May not be a class member to avoid name mangling. Pass the constant #PX_PHYSICS_VERSION as the argument. -There may be only one instance of this class per process. Calling this method after an instance +There may be only one instance of this class per process. Calling this method after an instance has been created already will result in an error message and NULL will be returned. -\param version Version number we are expecting(should be #PX_PHYSICS_VERSION) +\param version Version number we are expecting (should be #PX_PHYSICS_VERSION) \param foundation Foundation instance (see PxFoundation) \param scale values used to determine default tolerances for objects at creation time -\param trackOutstandingAllocations true if you want to track memory allocations +\param trackOutstandingAllocations true if you want to track memory allocations so a debugger connection partway through your physics simulation will get - an accurate map of everything that has been allocated so far. This could have a memory + an accurate map of everything that has been allocated so far. This could have a memory and performance impact on your simulation hence it defaults to off. \param pvd When pvd points to a valid PxPvd instance (PhysX Visual Debugger), a connection to the specified PxPvd instance is created. If pvd is NULL no connection will be attempted. +\param omniPvd When omniPvd points to a valid PxOmniPvd instance PhysX will sample its internal structures to the defined OmniPvd output streams + set in the PxOmniPvd object. \return PxPhysics instance on success, NULL if operation failed -@see PxPhysics, PxFoundation, PxTolerancesScale, PxPvd +@see PxPhysics, PxFoundation, PxTolerancesScale, PxPvd, PxOmniPvd + +@deprecated */ -PX_C_EXPORT PX_PHYSX_CORE_API physx::PxPhysics* PX_CALL_CONV PxCreateBasePhysics(physx::PxU32 version, - physx::PxFoundation& foundation, - const physx::PxTolerancesScale& scale, - bool trackOutstandingAllocations = false, - physx::PxPvd* pvd = NULL); +PX_DEPRECATED PX_C_EXPORT PX_PHYSX_CORE_API physx::PxPhysics* PX_CALL_CONV PxCreateBasePhysics( physx::PxU32 version, + physx::PxFoundation& foundation, + const physx::PxTolerancesScale& scale, + bool trackOutstandingAllocations = false, + physx::PxPvd* pvd = NULL, + physx::PxOmniPvd* omniPvd = NULL); /** \brief Creates an instance of the physics SDK. Creates an instance of this class. May not be a class member to avoid name mangling. Pass the constant #PX_PHYSICS_VERSION as the argument. -There may be only one instance of this class per process. Calling this method after an instance +There may be only one instance of this class per process. Calling this method after an instance has been created already will result in an error message and NULL will be returned. -Calling this will register all optional code modules (Articulations and HeightFields), preparing them for use. -If you do not need some of these modules, consider calling PxCreateBasePhysics() instead and registering needed +Calling this will register all optional code modules (Articulations and HeightFields), preparing them for use. +If you do not need some of these modules, consider calling PxCreateBasePhysics() instead and registering needed modules manually. -\param version Version number we are expecting(should be #PX_PHYSICS_VERSION) +\param version Version number we are expecting (should be #PX_PHYSICS_VERSION) \param foundation Foundation instance (see PxFoundation) \param scale values used to determine default tolerances for objects at creation time -\param trackOutstandingAllocations true if you want to track memory allocations +\param trackOutstandingAllocations true if you want to track memory allocations so a debugger connection partway through your physics simulation will get - an accurate map of everything that has been allocated so far. This could have a memory + an accurate map of everything that has been allocated so far. This could have a memory and performance impact on your simulation hence it defaults to off. \param pvd When pvd points to a valid PxPvd instance (PhysX Visual Debugger), a connection to the specified PxPvd instance is created. If pvd is NULL no connection will be attempted. +\param omniPvd When omniPvd points to a valid PxOmniPvd instance PhysX will sample its internal structures to the defined OmniPvd output streams + set in the PxOmniPvd object. \return PxPhysics instance on success, NULL if operation failed -@see PxPhysics, PxCreateBasePhysics, PxRegisterArticulations, PxRegisterArticulationsReducedCoordinate, PxRegisterHeightFields +@see PxPhysics, PxCreateBasePhysics, PxRegisterArticulationsReducedCoordinate, PxRegisterHeightFields */ PX_INLINE physx::PxPhysics* PxCreatePhysics(physx::PxU32 version, physx::PxFoundation& foundation, - const physx::PxTolerancesScale& scale, + const physx::PxTolerancesScale& scale, bool trackOutstandingAllocations = false, - physx::PxPvd* pvd = NULL ) + physx::PxPvd* pvd = NULL, + physx::PxOmniPvd* omniPvd = NULL) { - physx::PxPhysics* physics = PxCreateBasePhysics(version, foundation, scale, trackOutstandingAllocations, pvd); - if(!physics) + physx::PxPhysics* physics = PxCreateBasePhysics(version, foundation, scale, trackOutstandingAllocations, pvd, omniPvd); + if (!physics) return NULL; - PxRegisterArticulations(*physics); PxRegisterArticulationsReducedCoordinate(*physics); PxRegisterHeightFields(*physics); @@ -710,7 +1299,7 @@ PX_INLINE physx::PxPhysics* PxCreatePhysics(physx::PxU32 version, /** \brief Retrieves the Physics SDK after it has been created. -Before using this function the user must call #PxCreatePhysics(). +Before using this function the user must call #PxCreatePhysics() or #PxCreateBasePhysics(). \note The behavior of this method is undefined if the Physics SDK instance has not been created already. */ diff --git a/Source/ThirdParty/PhysX/PxPhysicsAPI.h b/Source/ThirdParty/PhysX/PxPhysicsAPI.h index 1fbfb0aff..d66780805 100644 --- a/Source/ThirdParty/PhysX/PxPhysicsAPI.h +++ b/Source/ThirdParty/PhysX/PxPhysicsAPI.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_NXPHYSICS_API -#define PX_PHYSICS_NXPHYSICS_API +#ifndef PX_PHYSICS_API_H +#define PX_PHYSICS_API_H /** \addtogroup physics @{ */ @@ -43,29 +41,65 @@ Alternatively, one can instead directly #include a subset of the below files. // Foundation SDK #include "foundation/Px.h" +#include "foundation/PxAlignedMalloc.h" +#include "foundation/PxAlloca.h" #include "foundation/PxAllocatorCallback.h" +#include "foundation/PxArray.h" #include "foundation/PxAssert.h" +#include "foundation/PxAtomic.h" +#include "foundation/PxBasicTemplates.h" #include "foundation/PxBitAndData.h" +#include "foundation/PxBitMap.h" +#include "foundation/PxBitUtils.h" #include "foundation/PxBounds3.h" +#include "foundation/PxBroadcast.h" #include "foundation/PxErrorCallback.h" #include "foundation/PxErrors.h" #include "foundation/PxFlags.h" +#include "foundation/PxFoundation.h" +#include "foundation/PxFoundationConfig.h" +#include "foundation/PxFPU.h" +#include "foundation/PxHash.h" +#include "foundation/PxHashMap.h" +#include "foundation/PxHashSet.h" +#include "foundation/PxInlineAllocator.h" +#include "foundation/PxInlineArray.h" #include "foundation/PxIntrinsics.h" #include "foundation/PxIO.h" #include "foundation/PxMat33.h" #include "foundation/PxMat44.h" #include "foundation/PxMath.h" +#include "foundation/PxMathIntrinsics.h" #include "foundation/PxMathUtils.h" +#include "foundation/PxMemory.h" +#include "foundation/PxMutex.h" +#include "foundation/PxPhysicsVersion.h" #include "foundation/PxPlane.h" +#include "foundation/PxPool.h" #include "foundation/PxPreprocessor.h" +#include "foundation/PxProfiler.h" #include "foundation/PxQuat.h" #include "foundation/PxSimpleTypes.h" +#include "foundation/PxSList.h" +#include "foundation/PxSocket.h" +#include "foundation/PxSort.h" #include "foundation/PxStrideIterator.h" +#include "foundation/PxString.h" +#include "foundation/PxSync.h" +#include "foundation/PxTempAllocator.h" +#include "foundation/PxThread.h" +#include "foundation/PxTime.h" #include "foundation/PxTransform.h" #include "foundation/PxUnionCast.h" +#include "foundation/PxUserAllocated.h" +#include "foundation/PxUtilities.h" #include "foundation/PxVec2.h" #include "foundation/PxVec3.h" #include "foundation/PxVec4.h" +#include "foundation/PxVecMath.h" +#include "foundation/PxVecQuat.h" +#include "foundation/PxVecTransform.h" + //Not physics specific utilities and common code #include "common/PxCoreUtilityTypes.h" @@ -79,7 +113,7 @@ Alternatively, one can instead directly #include a subset of the below files. #include "common/PxMetaData.h" #include "common/PxMetaDataFlags.h" #include "common/PxSerialFramework.h" -#include "common/PxPhysicsInsertionCallback.h" +#include "common/PxInsertionCallback.h" //Task Manager #include "task/PxTask.h" @@ -91,7 +125,8 @@ Alternatively, one can instead directly #include a subset of the below files. //Geometry Library #include "geometry/PxBoxGeometry.h" -#include "geometry/PxBVHStructure.h" +#include "geometry/PxBVH.h" +#include "geometry/PxBVHBuildStrategy.h" #include "geometry/PxCapsuleGeometry.h" #include "geometry/PxConvexMesh.h" #include "geometry/PxConvexMeshGeometry.h" @@ -111,31 +146,33 @@ Alternatively, one can instead directly #include a subset of the below files. #include "geometry/PxTriangle.h" #include "geometry/PxTriangleMesh.h" #include "geometry/PxTriangleMeshGeometry.h" - +#include "geometry/PxTetrahedron.h" +#include "geometry/PxTetrahedronMesh.h" +#include "geometry/PxTetrahedronMeshGeometry.h" // PhysX Core SDK #include "PxActor.h" #include "PxAggregate.h" -#include "PxArticulation.h" #include "PxArticulationReducedCoordinate.h" -#include "PxArticulationJoint.h" #include "PxArticulationJointReducedCoordinate.h" #include "PxArticulationLink.h" -#include "PxBatchQuery.h" -#include "PxBatchQueryDesc.h" #include "PxClient.h" +#include "PxConeLimitedConstraint.h" #include "PxConstraint.h" #include "PxConstraintDesc.h" #include "PxContact.h" #include "PxContactModifyCallback.h" #include "PxDeletionListener.h" +#include "PxFEMSoftBodyMaterial.h" #include "PxFiltering.h" #include "PxForceMode.h" -#include "PxFoundation.h" #include "PxLockedData.h" #include "PxMaterial.h" +#include "PxParticleBuffer.h" +#include "PxParticleSystem.h" +#include "PxPBDParticleSystem.h" +#include "PxPBDMaterial.h" #include "PxPhysics.h" -#include "PxPhysicsVersion.h" #include "PxPhysXConfig.h" #include "PxQueryFiltering.h" #include "PxQueryReport.h" @@ -149,8 +186,19 @@ Alternatively, one can instead directly #include a subset of the below files. #include "PxShape.h" #include "PxSimulationEventCallback.h" #include "PxSimulationStatistics.h" +#include "PxSoftBody.h" #include "PxVisualizationParameter.h" #include "PxPruningStructure.h" +#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION +#include "PxCustomParticleSystem.h" +#include "PxFEMCloth.h" +#include "PxFEMClothMaterial.h" +#include "PxFLIPParticleSystem.h" +#include "PxFLIPMaterial.h" +#include "PxHairSystem.h" +#include "PxMPMMaterial.h" +#include "PxMPMParticleSystem.h" +#endif //Character Controller #include "characterkinematic/PxBoxController.h" @@ -172,21 +220,7 @@ Alternatively, one can instead directly #include a subset of the below files. //Extensions to the SDK #include "extensions/PxDefaultStreams.h" -#include "extensions/PxDistanceJoint.h" #include "extensions/PxExtensionsAPI.h" -#include "extensions/PxFixedJoint.h" -#include "extensions/PxJoint.h" -#include "extensions/PxJointLimit.h" -#include "extensions/PxPrismaticJoint.h" -#include "extensions/PxRevoluteJoint.h" -#include "extensions/PxRigidBodyExt.h" -#include "extensions/PxShapeExt.h" -#include "extensions/PxSimpleFactory.h" -#include "extensions/PxSmoothNormals.h" -#include "extensions/PxSphericalJoint.h" -#include "extensions/PxStringTableExt.h" -#include "extensions/PxTriangleMeshExt.h" -#include "extensions/PxConvexMeshExt.h" //Serialization #include "extensions/PxSerialization.h" @@ -194,6 +228,7 @@ Alternatively, one can instead directly #include a subset of the below files. #include "extensions/PxRepXSerializer.h" //Vehicle Simulation +#include "vehicle2/PxVehicleAPI.h" #include "vehicle/PxVehicleComponents.h" #include "vehicle/PxVehicleDrive.h" #include "vehicle/PxVehicleDrive4W.h" @@ -202,6 +237,7 @@ Alternatively, one can instead directly #include a subset of the below files. #include "vehicle/PxVehicleShaders.h" #include "vehicle/PxVehicleTireFriction.h" #include "vehicle/PxVehicleUpdate.h" +#include "vehicle/PxVehicleUtil.h" #include "vehicle/PxVehicleUtilControl.h" #include "vehicle/PxVehicleUtilSetup.h" #include "vehicle/PxVehicleUtilTelemetry.h" diff --git a/Source/ThirdParty/PhysX/PxPhysicsSerialization.h b/Source/ThirdParty/PhysX/PxPhysicsSerialization.h index f9d657b98..e9383ab51 100644 --- a/Source/ThirdParty/PhysX/PxPhysicsSerialization.h +++ b/Source/ThirdParty/PhysX/PxPhysicsSerialization.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_PX_PHYSICS_SERIALIZATION -#define PX_PHYSICS_PX_PHYSICS_SERIALIZATION +#ifndef PX_PHYSICS_SERIALIZATION_H +#define PX_PHYSICS_SERIALIZATION_H #include "common/PxSerialFramework.h" #include "PxPhysXConfig.h" @@ -37,10 +35,13 @@ #if !PX_DOXYGEN /** \brief Retrieves the PhysX SDK metadata. + +\deprecated Binary conversion and binary meta data are deprecated. + This function is used to implement PxSerialization.dumpBinaryMetaData() and is not intended to be needed otherwise. @see PxSerialization.dumpBinaryMetaData() */ -PX_C_EXPORT PX_PHYSX_CORE_API void PX_CALL_CONV PxGetPhysicsBinaryMetaData(physx::PxOutputStream& stream); +PX_DEPRECATED PX_C_EXPORT PX_PHYSX_CORE_API void PX_CALL_CONV PxGetPhysicsBinaryMetaData(physx::PxOutputStream& stream); /** \brief Registers physics classes for serialization. @@ -71,4 +72,5 @@ PX_C_EXPORT PX_PHYSX_CORE_API void PX_CALL_CONV PxAddCollectionToPhysics(const p #endif // !PX_DOXYGEN -#endif // PX_PHYSICS_PX_PHYSICS_SERIALIZATION +#endif + diff --git a/Source/ThirdParty/PhysX/PxPruningStructure.h b/Source/ThirdParty/PhysX/PxPruningStructure.h index 562b5fffc..86019b1a3 100644 --- a/Source/ThirdParty/PhysX/PxPruningStructure.h +++ b/Source/ThirdParty/PhysX/PxPruningStructure.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_NX_PRUNING_STRUCTURE -#define PX_PHYSICS_NX_PRUNING_STRUCTURE +#ifndef PX_PRUNING_STRUCTURE_H +#define PX_PRUNING_STRUCTURE_H /** \addtogroup physics @{ */ @@ -58,7 +56,7 @@ doing queries against the newly added actors. This applies to both static and dy invalidate the pruning structure. Same happens if shape scene query flags change or shape gets removed from an actor. @see PxScene::addActors PxCollection -*/ +*/ class PxPruningStructure : public PxBase { public: @@ -92,6 +90,30 @@ public: */ virtual PxU32 getNbRigidActors() const = 0; + /** + \brief Gets the merge data for static actors + + This is mainly called by the PxSceneQuerySystem::merge() function to merge a PxPruningStructure + with the internal data-structures of the scene-query system. + + \return Implementation-dependent merge data for static actors. + + @see PxSceneQuerySystem::merge() + */ + virtual const void* getStaticMergeData() const = 0; + + /** + \brief Gets the merge data for dynamic actors + + This is mainly called by the PxSceneQuerySystem::merge() function to merge a PxPruningStructure + with the internal data-structures of the scene-query system. + + \return Implementation-dependent merge data for dynamic actors. + + @see PxSceneQuerySystem::merge() + */ + virtual const void* getDynamicMergeData() const = 0; + virtual const char* getConcreteTypeName() const { return "PxPruningStructure"; } protected: PX_INLINE PxPruningStructure(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags) {} @@ -106,4 +128,5 @@ protected: #endif /** @} */ -#endif // PX_PHYSICS_NX_PRUNING_STRUCTURE +#endif + diff --git a/Source/ThirdParty/PhysX/PxQueryFiltering.h b/Source/ThirdParty/PhysX/PxQueryFiltering.h index 816ed9085..1ed8002c9 100644 --- a/Source/ThirdParty/PhysX/PxQueryFiltering.h +++ b/Source/ThirdParty/PhysX/PxQueryFiltering.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_NX_SCENE_QUERY_FILTERING -#define PX_PHYSICS_NX_SCENE_QUERY_FILTERING +#ifndef PX_QUERY_FILTERING_H +#define PX_QUERY_FILTERING_H /** \addtogroup scenequery @{ */ @@ -48,7 +46,6 @@ class PxShape; class PxRigidActor; struct PxQueryHit; - /** \brief Filtering flags for scene queries. @@ -58,25 +55,33 @@ struct PxQueryFlag { enum Enum { - eSTATIC = (1<<0), //!< Traverse static shapes + eSTATIC = (1<<0), //!< Traverse static shapes - eDYNAMIC = (1<<1), //!< Traverse dynamic shapes + eDYNAMIC = (1<<1), //!< Traverse dynamic shapes - ePREFILTER = (1<<2), //!< Run the pre-intersection-test filter (see #PxQueryFilterCallback::preFilter()) + ePREFILTER = (1<<2), //!< Run the pre-intersection-test filter (see #PxQueryFilterCallback::preFilter()) - ePOSTFILTER = (1<<3), //!< Run the post-intersection-test filter (see #PxQueryFilterCallback::postFilter()) + ePOSTFILTER = (1<<3), //!< Run the post-intersection-test filter (see #PxQueryFilterCallback::postFilter()) - eANY_HIT = (1<<4), //!< Abort traversal as soon as any hit is found and return it via callback.block. - //!< Helps query performance. Both eTOUCH and eBLOCK hitTypes are considered hits with this flag. + eANY_HIT = (1<<4), //!< Abort traversal as soon as any hit is found and return it via callback.block. + //!< Helps query performance. Both eTOUCH and eBLOCK hitTypes are considered hits with this flag. - eNO_BLOCK = (1<<5), //!< All hits are reported as touching. Overrides eBLOCK returned from user filters with eTOUCH. - //!< This is also an optimization hint that may improve query performance. + eNO_BLOCK = (1<<5), //!< All hits are reported as touching. Overrides eBLOCK returned from user filters with eTOUCH. + //!< This is also an optimization hint that may improve query performance. + + eBATCH_QUERY_LEGACY_BEHAVIOUR = (1<<6), //!< Run with legacy batch query filter behavior. Raising this flag ensures that + //!< the hardcoded filter equation is neglected. This guarantees that any provided PxQueryFilterCallback + //!< will be utilised, as specified by the ePREFILTER and ePOSTFILTER flags. - eRESERVED = (1<<15) //!< Reserved for internal use + eDISABLE_HARDCODED_FILTER = (1<<6), //!< Same as eBATCH_QUERY_LEGACY_BEHAVIOUR, more explicit name making it clearer that this can also be used + //!< with regular/non-batched queries if needed. + + eRESERVED = (1<<15) //!< Reserved for internal use }; }; PX_COMPILE_TIME_ASSERT(PxQueryFlag::eSTATIC==(1<<0)); PX_COMPILE_TIME_ASSERT(PxQueryFlag::eDYNAMIC==(1<<1)); +PX_COMPILE_TIME_ASSERT(PxQueryFlag::eBATCH_QUERY_LEGACY_BEHAVIOUR==PxQueryFlag::eDISABLE_HARDCODED_FILTER); /** \brief Flags typedef for the set of bits defined in PxQueryFlag. @@ -127,7 +132,7 @@ queryFilterData is zero, the shape is skipped to type #PxQueryHitType::eBLOCK when the value of PxHitCallback::nbTouches provided with the query is zero and to type #PxQueryHitType::eTOUCH when PxHitCallback::nbTouches is positive. -@see PxScene.raycast PxScene.sweep PxScene.overlap PxBatchQuery.raycast PxBatchQuery.sweep PxBatchQuery.overlap PxQueryFlag::eANY_HIT +@see PxScene.raycast PxScene.sweep PxScene.overlap PxQueryFlag::eANY_HIT */ struct PxQueryFilterData { @@ -173,10 +178,10 @@ public: /** \brief This filter callback is executed before the exact intersection test if PxQueryFlag::ePREFILTER flag was set. - \param[in] filterData custom filter data specified as the query's filterData.data parameter. - \param[in] shape A shape that has not yet passed the exact intersection test. - \param[in] actor The shape's actor. - \param[in,out] queryFlags scene query flags from the query's function call (only flags from PxHitFlag::eMODIFIABLE_FLAGS bitmask can be modified) + \param[in] filterData custom filter data specified as the query's filterData.data parameter. + \param[in] shape A shape that has not yet passed the exact intersection test. + \param[in] actor The shape's actor. + \param[in,out] queryFlags scene query flags from the query's function call (only flags from PxHitFlag::eMODIFIABLE_FLAGS bitmask can be modified) \return the updated type for this hit (see #PxQueryHitType) */ virtual PxQueryHitType::Enum preFilter( @@ -185,11 +190,33 @@ public: /** \brief This filter callback is executed if the exact intersection test returned true and PxQueryFlag::ePOSTFILTER flag was set. - \param[in] filterData custom filter data of the query - \param[in] hit Scene query hit information. faceIndex member is not valid for overlap queries. For sweep and raycast queries the hit information can be cast to #PxSweepHit and #PxRaycastHit respectively. + \param[in] filterData custom filter data of the query + \param[in] hit Scene query hit information. faceIndex member is not valid for overlap queries. For sweep and raycast queries the hit information can be cast to #PxSweepHit and #PxRaycastHit respectively. + \return the updated hit type for this hit (see #PxQueryHitType) + @deprecated + */ + PX_DEPRECATED virtual PxQueryHitType::Enum postFilter(const PxFilterData& filterData, const PxQueryHit& hit) + { + PX_UNUSED(filterData); + PX_UNUSED(hit); + return PxQueryHitType::eBLOCK; + } + + /** + \brief This filter callback is executed if the exact intersection test returned true and PxQueryFlag::ePOSTFILTER flag was set. + + \param[in] filterData custom filter data of the query + \param[in] hit Scene query hit information. faceIndex member is not valid for overlap queries. For sweep and raycast queries the hit information can be cast to #PxSweepHit and #PxRaycastHit respectively. + \param[in] shape Hit shape + \param[in] actor Hit actor \return the updated hit type for this hit (see #PxQueryHitType) */ - virtual PxQueryHitType::Enum postFilter(const PxFilterData& filterData, const PxQueryHit& hit) = 0; + virtual PxQueryHitType::Enum postFilter(const PxFilterData& filterData, const PxQueryHit& hit, const PxShape* shape, const PxRigidActor* actor) + { + PX_UNUSED(shape); + PX_UNUSED(actor); + return postFilter(filterData, hit); + } /** \brief virtual destructor @@ -197,76 +224,6 @@ public: virtual ~PxQueryFilterCallback() {} }; -/** -\brief Batched query pre-filter shader. - -Custom filtering logic for batched query intersection candidates. If an intersection candidate object passes the data based filter (see #PxQueryFilterData), -filtering shader runs if specified in filtering flags (see #PxQueryFilterData.flags) - -\li If #PxQueryFlag::ePREFILTER is set, the preFilter shader runs before exact intersection tests. -If the shader returns #PxQueryHitType::eTOUCH or #PxQueryHitType::eBLOCK, exact testing is performed to -determine the intersection location. - -The preFilter shader may overwrite the copy of queryFlags it receives as an argument to specify any of #PxHitFlag::eMODIFIABLE_FLAGS -on a per-shape basis. Changes apply only to the shape being filtered, and changes to other flags are ignored. - -\li If #PxQueryFlag::ePREFILTER is not set, precise intersection testing is performed using the original query's filterData.flags. - -Filtering calls are not guaranteed to be sorted along the ray or sweep direction. - -\deprecated The batched query feature has been deprecated in PhysX version 3.4 - -@see PxBatchQueryDesc.preFilterShader PxQueryFilterCallback.preFilter PxBatchQueryPostFilterShader - -*/ - -/** -\param[in] queryFilterData Query filter data -\param[in] objectFilterData Object filter data -\param[in] constantBlock Global constant filter data (see #PxBatchQuery) -\param[in] constantBlockSize Size of global filter data (see #PxBatchQuery) -\param[in,out] hitFlags Per-object modifiable hit flags (only flags from PxHitFlag::eMODIFIABLE_FLAGS mask can be modified) -\return the updated hit type for this hit (see #PxQueryHitType) - -@see PxBatchQueryPostFilterShader -*/ -typedef PX_DEPRECATED PxQueryHitType::Enum (*PxBatchQueryPreFilterShader)( - PxFilterData queryFilterData, PxFilterData objectFilterData, - const void* constantBlock, PxU32 constantBlockSize, - PxHitFlags& hitFlags); - -/** -\brief Batched query post-filter shader. - -Custom filtering logic for batched query intersection candidates. If an intersection candidate object passes the data based filter (see #PxQueryFilterData), -the filtering shader run on request (see #PxQueryFilterData.flags) - -\li If #PxQueryFlag::ePOSTFILTER is set, the postFilter shader is called for each intersection to determine the touch/block status. -This overrides any touch/block status previously returned from the preFilter function for this shape. - -Filtering shaders are not in order along the query direction, rather they are processed in the order in which -candidate shapes for testing are found by PhysX' scene traversal algorithms. - -\deprecated The batched query feature has been deprecated in PhysX version 3.4 - -@see PxBatchQueryDesc.postFilterShader PxQueryFilterCallback.postFilter PxBatchQueryPreFilterShader -*/ - -/** -\param[in] queryFilterData Query filter data -\param[in] objectFilterData Object filter data -\param[in] constantBlock Global constant filter data (see #PxBatchQuery) -\param[in] constantBlockSize Size of global filter data (see #PxBatchQuery) -\param[in] hit Hit data from the prior exact intersection test. -\return the new hit type for this hit (see #PxQueryHitType) - -@see PxBatchQueryPreFilterShader -*/ - -typedef PX_DEPRECATED PxQueryHitType::Enum (*PxBatchQueryPostFilterShader)( - PxFilterData queryFilterData, PxFilterData objectFilterData, - const void* constantBlock, PxU32 constantBlockSize, - const PxQueryHit& hit); #if !PX_DOXYGEN } // namespace physx diff --git a/Source/ThirdParty/PhysX/PxQueryReport.h b/Source/ThirdParty/PhysX/PxQueryReport.h index f48741ab2..a508d1c26 100644 --- a/Source/ThirdParty/PhysX/PxQueryReport.h +++ b/Source/ThirdParty/PhysX/PxQueryReport.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,19 +22,20 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_NX_SCENEQUERYREPORT -#define PX_PHYSICS_NX_SCENEQUERYREPORT +#ifndef PX_QUERY_REPORT_H +#define PX_QUERY_REPORT_H /** \addtogroup scenequery @{ */ #include "foundation/PxVec3.h" #include "foundation/PxFlags.h" #include "foundation/PxAssert.h" +#include "geometry/PxGeometryHit.h" +#include "geometry/PxGeometryQueryContext.h" #include "PxPhysXConfig.h" #if !PX_DOXYGEN @@ -46,54 +46,6 @@ namespace physx class PxShape; class PxRigidActor; -/** -\brief Scene query and geometry query behavior flags. - -PxHitFlags are used for 3 different purposes: - -1) To request hit fields to be filled in by scene queries (such as hit position, normal, face index or UVs). -2) Once query is completed, to indicate which fields are valid (note that a query may produce more valid fields than requested). -3) To specify additional options for the narrow phase and mid-phase intersection routines. - -All these flags apply to both scene queries and geometry queries (PxGeometryQuery). - -@see PxRaycastHit PxSweepHit PxOverlapHit PxScene.raycast PxScene.sweep PxScene.overlap PxGeometryQuery PxFindFaceIndex -*/ -struct PxHitFlag -{ - enum Enum - { - ePOSITION = (1<<0), //!< "position" member of #PxQueryHit is valid - eNORMAL = (1<<1), //!< "normal" member of #PxQueryHit is valid - eUV = (1<<3), //!< "u" and "v" barycentric coordinates of #PxQueryHit are valid. Not applicable to sweep queries. - eASSUME_NO_INITIAL_OVERLAP = (1<<4), //!< Performance hint flag for sweeps when it is known upfront there's no initial overlap. - //!< NOTE: using this flag may cause undefined results if shapes are initially overlapping. - eMESH_MULTIPLE = (1<<5), //!< Report all hits for meshes rather than just the first. Not applicable to sweep queries. - eMESH_ANY = (1<<6), //!< Report any first hit for meshes. If neither eMESH_MULTIPLE nor eMESH_ANY is specified, - //!< a single closest hit will be reported for meshes. - eMESH_BOTH_SIDES = (1<<7), //!< Report hits with back faces of mesh triangles. Also report hits for raycast - //!< originating on mesh surface and facing away from the surface normal. Not applicable to sweep queries. - //!< Please refer to the user guide for heightfield-specific differences. - ePRECISE_SWEEP = (1<<8), //!< Use more accurate but slower narrow phase sweep tests. - //!< May provide better compatibility with PhysX 3.2 sweep behavior. - eMTD = (1<<9), //!< Report the minimum translation depth, normal and contact point. - eFACE_INDEX = (1<<10), //!< "face index" member of #PxQueryHit is valid - - eDEFAULT = ePOSITION|eNORMAL|eFACE_INDEX, - - /** \brief Only this subset of flags can be modified by pre-filter. Other modifications will be discarded. */ - eMODIFIABLE_FLAGS = eMESH_MULTIPLE|eMESH_BOTH_SIDES|eASSUME_NO_INITIAL_OVERLAP|ePRECISE_SWEEP - }; -}; - - -/** -\brief collection of set bits defined in PxHitFlag. - -@see PxHitFlag -*/ -PX_FLAGS_TYPEDEF(PxHitFlag, PxU16) - /** \brief Combines a shape pointer and the actor the shape belongs to into one memory location. @@ -110,100 +62,10 @@ struct PxActorShape PxShape* shape; }; - -/** -\brief Scene query hit information. -*/ -struct PxQueryHit : public PxActorShape -{ - PX_INLINE PxQueryHit() : faceIndex(0xFFFFffff) {} - - /** - Face index of touched triangle, for triangle meshes, convex meshes and height fields. - - \note This index will default to 0xFFFFffff value for overlap queries. - \note Please refer to the user guide for more details for sweep queries. - \note This index is remapped by mesh cooking. Use #PxTriangleMesh::getTrianglesRemap() to convert to original mesh index. - \note For convex meshes use #PxConvexMesh::getPolygonData() to retrieve touched polygon data. - */ - PxU32 faceIndex; -}; - -/** -\brief Scene query hit information for raycasts and sweeps returning hit position and normal information. - -::PxHitFlag flags can be passed to scene query functions, as an optimization, to cause the SDK to -only generate specific members of this structure. -*/ -struct PxLocationHit : public PxQueryHit -{ - PX_INLINE PxLocationHit() : flags(0), position(PxVec3(0)), normal(PxVec3(0)), distance(PX_MAX_REAL) {} - - /** - \note For raycast hits: true for shapes overlapping with raycast origin. - \note For sweep hits: true for shapes overlapping at zero sweep distance. - - @see PxRaycastHit PxSweepHit - */ - PX_INLINE bool hadInitialOverlap() const { return (distance <= 0.0f); } - - // the following fields are set in accordance with the #PxHitFlags - PxHitFlags flags; //!< Hit flags specifying which members contain valid values. - PxVec3 position; //!< World-space hit position (flag: #PxHitFlag::ePOSITION) - PxVec3 normal; //!< World-space hit normal (flag: #PxHitFlag::eNORMAL) - - /** - \brief Distance to hit. - \note If the eMTD flag is used, distance will be a negative value if shapes are overlapping indicating the penetration depth. - \note Otherwise, this value will be >= 0 */ - PxF32 distance; -}; - - -/** -\brief Stores results of raycast queries. - -::PxHitFlag flags can be passed to raycast function, as an optimization, to cause the SDK to only compute specified members of this -structure. - -Some members like barycentric coordinates are currently only computed for triangle meshes and height fields, but next versions -might provide them in other cases. The client code should check #flags to make sure returned values are valid. - -@see PxScene.raycast PxBatchQuery.raycast -*/ -struct PxRaycastHit : public PxLocationHit -{ - PX_INLINE PxRaycastHit() : u(0.0f), v(0.0f) {} - - // the following fields are set in accordance with the #PxHitFlags - - PxReal u, v; //!< barycentric coordinates of hit point, for triangle mesh and height field (flag: #PxHitFlag::eUV) -#if !PX_P64_FAMILY - PxU32 padTo16Bytes[3]; -#endif -}; - - -/** -\brief Stores results of overlap queries. - -@see PxScene.overlap PxBatchQuery.overlap -*/ -struct PxOverlapHit: public PxQueryHit { PxU32 padTo16Bytes; }; - - -/** -\brief Stores results of sweep queries. - -@see PxScene.sweep PxBatchQuery.sweep -*/ -struct PxSweepHit : public PxLocationHit -{ - PX_INLINE PxSweepHit() {} - - PxU32 padTo16Bytes; -}; - +// Extends geom hits with Px object pointers +struct PxRaycastHit : PxGeomRaycastHit, PxActorShape {}; +struct PxOverlapHit : PxGeomOverlapHit, PxActorShape {}; +struct PxSweepHit : PxGeomSweepHit, PxActorShape {}; /** \brief Describes query behavior after returning a partial query result via a callback. @@ -215,7 +77,6 @@ If callback returns false, traversal will stop, callback will not be issued agai */ typedef bool PxAgain; - /** \brief This callback class facilitates reporting scene query hits (intersections) to the user. @@ -230,7 +91,7 @@ User overrides the virtual processTouches function to receive hits in (possibly @see PxHitBuffer PxRaycastHit PxSweepHit PxOverlapHit PxRaycastCallback PxOverlapCallback PxSweepCallback */ template -struct PxHitCallback +struct PxHitCallback : PxQueryThreadContext { HitType block; //!< Holds the closest blocking hit result for the query. Invalid if hasBlock is false. bool hasBlock; //!< Set to true if there was a blocking hit during query. @@ -293,7 +154,6 @@ struct PxHitCallback PX_FORCE_INLINE bool hasAnyHits() { return (hasBlock || (nbTouches > 0)); } }; - /** \brief Returns scene query hits (intersections) to the user in a preallocated buffer. @@ -340,7 +200,6 @@ protected: virtual PxAgain processTouches(const HitType* buffer, PxU32 nbHits) { PX_UNUSED(buffer); PX_UNUSED(nbHits); return false; } }; - /** \brief Raycast query callback. */ typedef PxHitCallback PxRaycastCallback; @@ -383,6 +242,41 @@ struct PxSweepBufferN : public PxHitBuffer PxSweepBufferN() : PxHitBuffer(hits, N) {} }; +/** +\brief single hit cache for scene queries. + +If a cache object is supplied to a scene query, the cached actor/shape pair is checked for intersection first. +\note Filters are not executed for the cached shape. +\note If intersection is found, the hit is treated as blocking. +\note Typically actor and shape from the last PxHitCallback.block query result is used as a cached actor/shape pair. +\note Using past touching hits as cache will produce incorrect behavior since the cached hit will always be treated as blocking. +\note Cache is only used if no touch buffer was provided, for single nearest blocking hit queries and queries using eANY_HIT flag. +\note if non-zero touch buffer was provided, cache will be ignored + +\note It is the user's responsibility to ensure that the shape and actor are valid, so care must be taken +when deleting shapes to invalidate cached references. + +The faceIndex field is an additional hint for a mesh or height field which is not currently used. + +@see PxScene.raycast +*/ +struct PxQueryCache +{ + /** + \brief constructor sets to default + */ + PX_INLINE PxQueryCache() : shape(NULL), actor(NULL), faceIndex(0xffffffff) {} + + /** + \brief constructor to set properties + */ + PX_INLINE PxQueryCache(PxShape* s, PxU32 findex) : shape(s), actor(NULL), faceIndex(findex) {} + + PxShape* shape; //!< Shape to test for intersection first + PxRigidActor* actor; //!< Actor to which the shape belongs + PxU32 faceIndex; //!< Triangle index to test first - NOT CURRENTLY SUPPORTED +}; + #if !PX_DOXYGEN } // namespace physx #endif diff --git a/Source/ThirdParty/PhysX/PxRigidActor.h b/Source/ThirdParty/PhysX/PxRigidActor.h index 09852863f..1c3d8ae96 100644 --- a/Source/ThirdParty/PhysX/PxRigidActor.h +++ b/Source/ThirdParty/PhysX/PxRigidActor.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_NX_RIGIDACTOR -#define PX_PHYSICS_NX_RIGIDACTOR +#ifndef PX_RIGID_ACTOR_H +#define PX_RIGID_ACTOR_H /** \addtogroup physics @{ */ @@ -43,9 +41,6 @@ namespace physx #endif class PxConstraint; -class PxMaterial; -class PxGeometry; -class PxBVHStructure; /** \brief PxRigidActor represents a base class shared between dynamic and static rigid bodies in the physics SDK. @@ -54,13 +49,12 @@ PxRigidActor objects specify the geometry of the object by defining a set of att @see PxActor */ - class PxRigidActor : public PxActor { public: /** \brief Deletes the rigid actor object. - + Also releases any shapes associated with the actor. Releasing an actor will affect any objects that are connected to the actor (constraint shaders like joints etc.). @@ -76,6 +70,14 @@ public: */ virtual void release() = 0; + /** + \brief Returns the internal actor index. + + \warning This is only defined for actors that have been added to a scene. + + \return The internal actor index, or 0xffffffff if the actor is not part of a scene. + */ + virtual PxU32 getInternalActorIndex() const = 0; /************************************************************************************************/ /** @name Global Pose Manipulation @@ -86,6 +88,9 @@ public: The getGlobalPose() method retrieves the actor's current actor space to world space transformation. + \note It is not allowed to use this method while the simulation is running (except during PxScene::collide(), + in PxContactModifyCallback or in contact report callbacks). + \return Global pose of object. @see PxRigidDynamic.setGlobalPose() PxRigidStatic.setGlobalPose() @@ -95,19 +100,19 @@ public: /** \brief Method for setting an actor's pose in the world. - This method instantaneously changes the actor space to world space transformation. + This method instantaneously changes the actor space to world space transformation. - This method is mainly for dynamic rigid bodies (see #PxRigidDynamic). Calling this method on static actors is - likely to result in a performance penalty, since internal optimization structures for static actors may need to be - recomputed. In addition, moving static actors will not interact correctly with dynamic actors or joints. - - To directly control an actor's position and have it correctly interact with dynamic bodies and joints, create a dynamic + This method is mainly for dynamic rigid bodies (see #PxRigidDynamic). Calling this method on static actors is + likely to result in a performance penalty, since internal optimization structures for static actors may need to be + recomputed. In addition, moving static actors will not interact correctly with dynamic actors or joints. + + To directly control an actor's position and have it correctly interact with dynamic bodies and joints, create a dynamic body with the PxRigidBodyFlag::eKINEMATIC flag, then use the setKinematicTarget() commands to define its path. Even when moving dynamic actors, exercise restraint in making use of this method. Where possible, avoid: - + \li moving actors into other actors, thus causing overlap (an invalid physical state) - + \li moving an actor that is connected by a joint to another away from the other (thus causing joint error) Sleeping: This call wakes dynamic actors if they are sleeping and the autowake parameter is true (default). @@ -119,12 +124,12 @@ public: */ virtual void setGlobalPose(const PxTransform& pose, bool autowake = true) = 0; - /************************************************************************************************/ /** @name Shapes */ - /** attach a shared shape to an actor + /** + \brief Attach a shape to an actor This call will increment the reference count of the shape. @@ -135,7 +140,6 @@ public: Attaching a triangle mesh, heightfield or plane geometry shape configured as eSIMULATION_SHAPE is not supported for non-kinematic PxRigidDynamic instances. - Sleeping: Does NOT wake the actor up automatically. \param[in] shape the shape to attach. @@ -144,20 +148,18 @@ public: */ virtual bool attachShape(PxShape& shape) = 0; - - /** detach a shape from an actor. + /** + \brief Detach a shape from an actor. This will also decrement the reference count of the PxShape, and if the reference count is zero, will cause it to be deleted. Sleeping: Does NOT wake the actor up automatically. \param[in] shape the shape to detach. - \param[in] wakeOnLostTouch Specifies whether touching objects from the previous frame should get woken up in the next frame. Only applies to PxArticulation and PxRigidActor types. - + \param[in] wakeOnLostTouch Specifies whether touching objects from the previous frame should get woken up in the next frame. Only applies to PxArticulationReducedCoordinate and PxRigidActor types. */ virtual void detachShape(PxShape& shape, bool wakeOnLostTouch = true) = 0; - /** \brief Returns the number of shapes assigned to the actor. @@ -169,7 +171,6 @@ public: */ virtual PxU32 getNbShapes() const = 0; - /** \brief Retrieve all the shape pointers belonging to the actor. @@ -188,7 +189,6 @@ public: */ virtual PxU32 getShapes(PxShape** userBuffer, PxU32 bufferSize, PxU32 startIndex=0) const = 0; - /************************************************************************************************/ /** @name Constraints */ @@ -204,7 +204,6 @@ public: */ virtual PxU32 getNbConstraints() const = 0; - /** \brief Retrieve all the constraint shader pointers belonging to the actor. @@ -228,7 +227,6 @@ protected: virtual bool isKindOf(const char* name) const { return !::strcmp("PxRigidActor", name) || PxActor::isKindOf(name); } }; - #if !PX_DOXYGEN } // namespace physx #endif diff --git a/Source/ThirdParty/PhysX/PxRigidBody.h b/Source/ThirdParty/PhysX/PxRigidBody.h index 1d9feee02..4d0ecafa5 100644 --- a/Source/ThirdParty/PhysX/PxRigidBody.h +++ b/Source/ThirdParty/PhysX/PxRigidBody.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,37 +22,34 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_NX_RIGIDBODY -#define PX_PHYSICS_NX_RIGIDBODY +#ifndef PX_RIGID_BODY_H +#define PX_RIGID_BODY_H /** \addtogroup physics @{ */ #include "PxRigidActor.h" #include "PxForceMode.h" +#include "PxNodeIndex.h" #if !PX_DOXYGEN namespace physx { #endif - /** \brief Collection of flags describing the behavior of a rigid body. @see PxRigidBody.setRigidBodyFlag(), PxRigidBody.getRigidBodyFlags() */ - struct PxRigidBodyFlag { enum Enum { - /** \brief Enables kinematic mode for the actor. @@ -75,7 +71,7 @@ struct PxRigidBodyFlag @see PxRigidDynamic.setKinematicTarget() */ - eKINEMATIC = (1<<0), //!< Enable kinematic mode for the body. + eKINEMATIC = (1<<0), //!< Enable kinematic mode for the body. /** \brief Use the kinematic target transform for scene queries. @@ -86,7 +82,7 @@ struct PxRigidBodyFlag @see PxRigidDynamic.setKinematicTarget() */ - eUSE_KINEMATIC_TARGET_FOR_SCENE_QUERIES = (1<<1), + eUSE_KINEMATIC_TARGET_FOR_SCENE_QUERIES = (1<<1), /** \brief Enables swept integration for the actor. @@ -96,9 +92,8 @@ struct PxRigidBodyFlag individual interactions. \note kinematic actors are incompatible with CCD so this flag will be cleared automatically when raised on a kinematic actor - */ - eENABLE_CCD = (1<<2), //!< Enable CCD for the body. + eENABLE_CCD = (1<<2), //!< Enable CCD for the body. /** \brief Enabled CCD in swept integration for the actor. @@ -109,7 +104,15 @@ struct PxRigidBodyFlag \note This flag requires PxRigidBodyFlag::eENABLE_CCD to be raised to have any effect. */ - eENABLE_CCD_FRICTION = (1<<3), + eENABLE_CCD_FRICTION = (1<<3), + + /** + \brief Register a rigid body to dynamically adjust contact offset based on velocity. This can be used to achieve a CCD effect. + + If both eENABLE_CCD and eENABLE_SPECULATIVE_CCD are set on the same body, then angular motions are handled by speculative + contacts (eENABLE_SPECULATIVE_CCD) while linear motions are handled by sweeps (eENABLE_CCD). + */ + eENABLE_SPECULATIVE_CCD = (1<<4), /** \brief Register a rigid body for reporting pose changes by the simulation at an early stage. @@ -121,22 +124,60 @@ struct PxRigidBodyFlag @see PxSimulationEventCallback::onAdvance() */ - eENABLE_POSE_INTEGRATION_PREVIEW = (1 << 4), - - /** - \brief Register a rigid body to dynamicly adjust contact offset based on velocity. This can be used to achieve a CCD effect. - */ - eENABLE_SPECULATIVE_CCD = (1 << 5), + eENABLE_POSE_INTEGRATION_PREVIEW = (1<<5), /** \brief Permit CCD to limit maxContactImpulse. This is useful for use-cases like a destruction system but can cause visual artefacts so is not enabled by default. */ - eENABLE_CCD_MAX_CONTACT_IMPULSE = (1 << 6), + eENABLE_CCD_MAX_CONTACT_IMPULSE = (1<<6), /** - \brief Carries over forces/accelerations between frames, rather than clearning them + \brief Carries over forces/accelerations between frames, rather than clearing them */ - eRETAIN_ACCELERATIONS = (1<<7) + eRETAIN_ACCELERATIONS = (1<<7), + + /** + \brief Forces kinematic-kinematic pairs notifications for this actor. + + This flag overrides the global scene-level PxPairFilteringMode setting for kinematic actors. + This is equivalent to having PxPairFilteringMode::eKEEP for pairs involving this actor. + + A particular use case is when you have a large amount of kinematic actors, but you are only + interested in interactions between a few of them. In this case it is best to use + PxSceneDesc.kineKineFilteringMode = PxPairFilteringMode::eKILL, and then raise the + eFORCE_KINE_KINE_NOTIFICATIONS flag on the small set of kinematic actors that need + notifications. + + \note This has no effect if PxRigidBodyFlag::eKINEMATIC is not set. + + \warning Changing this flag at runtime will not have an effect until you remove and re-add the actor to the scene. + + @see PxPairFilteringMode PxSceneDesc.kineKineFilteringMode + */ + eFORCE_KINE_KINE_NOTIFICATIONS = (1<<8), + + /** + \brief Forces static-kinematic pairs notifications for this actor. + + Similar to eFORCE_KINE_KINE_NOTIFICATIONS, but for static-kinematic interactions. + + \note This has no effect if PxRigidBodyFlag::eKINEMATIC is not set. + + \warning Changing this flag at runtime will not have an effect until you remove and re-add the actor to the scene. + + @see PxPairFilteringMode PxSceneDesc.staticKineFilteringMode + */ + eFORCE_STATIC_KINE_NOTIFICATIONS = (1<<9), + + /** + \brief Enables computation of gyroscopic forces on the rigid body. + */ + eENABLE_GYROSCOPIC_FORCES = (1<<10), + + /** + \brief Reserved for internal usage + */ + eRESERVED = (1<<15) }; }; @@ -145,8 +186,8 @@ struct PxRigidBodyFlag @see PxRigidBodyFlag */ -typedef PxFlags PxRigidBodyFlags; -PX_FLAGS_OPERATORS(PxRigidBodyFlag::Enum,PxU8) +typedef PxFlags PxRigidBodyFlags; +PX_FLAGS_OPERATORS(PxRigidBodyFlag::Enum,PxU16) /** \brief PxRigidBody is a base class shared between dynamic rigid body objects. @@ -177,8 +218,7 @@ public: @see getCMassLocalPose() PxRigidBodyDesc.massLocalPose */ - virtual void setCMassLocalPose(const PxTransform& pose) = 0; - + virtual void setCMassLocalPose(const PxTransform& pose) = 0; /** \brief Retrieves the center of mass pose relative to the actor frame. @@ -189,7 +229,6 @@ public: */ virtual PxTransform getCMassLocalPose() const = 0; - /** \brief Sets the mass of a dynamic actor. @@ -209,7 +248,7 @@ public: @see getMass() PxRigidBodyDesc.mass setMassSpaceInertiaTensor() */ - virtual void setMass(PxReal mass) = 0; + virtual void setMass(PxReal mass) = 0; /** \brief Retrieves the mass of the actor. @@ -220,7 +259,7 @@ public: @see setMass() PxRigidBodyDesc.mass setMassSpaceInertiaTensor() */ - virtual PxReal getMass() const = 0; + virtual PxReal getMass() const = 0; /** \brief Retrieves the inverse mass of the actor. @@ -229,7 +268,7 @@ public: @see setMass() PxRigidBodyDesc.mass setMassSpaceInertiaTensor() */ - virtual PxReal getInvMass() const = 0; + virtual PxReal getInvMass() const = 0; /** \brief Sets the inertia tensor, using a parameter specified in mass space coordinates. @@ -252,7 +291,7 @@ public: @see PxRigidBodyDesc.massSpaceInertia getMassSpaceInertia() setMass() setCMassLocalPose() */ - virtual void setMassSpaceInertiaTensor(const PxVec3& m) = 0; + virtual void setMassSpaceInertiaTensor(const PxVec3& m) = 0; /** \brief Retrieves the diagonal inertia tensor of the actor relative to the mass coordinate frame. @@ -265,7 +304,7 @@ public: @see PxRigidBodyDesc.massSpaceInertia setMassSpaceInertiaTensor() setMass() setCMassLocalPose() */ - virtual PxVec3 getMassSpaceInertiaTensor() const = 0; + virtual PxVec3 getMassSpaceInertiaTensor() const = 0; /** \brief Retrieves the diagonal inverse inertia tensor of the actor relative to the mass coordinate frame. @@ -278,7 +317,7 @@ public: @see PxRigidBodyDesc.massSpaceInertia setMassSpaceInertiaTensor() setMass() setCMassLocalPose() */ - virtual PxVec3 getMassSpaceInvInertiaTensor() const = 0; + virtual PxVec3 getMassSpaceInvInertiaTensor() const = 0; /************************************************************************************************/ /** @name Damping @@ -295,7 +334,7 @@ public: @see getLinearDamping() setAngularDamping() */ - virtual void setLinearDamping(PxReal linDamp) = 0; + virtual void setLinearDamping(PxReal linDamp) = 0; /** \brief Retrieves the linear damping coefficient. @@ -304,7 +343,7 @@ public: @see setLinearDamping() getAngularDamping() */ - virtual PxReal getLinearDamping() const = 0; + virtual PxReal getLinearDamping() const = 0; /** \brief Sets the angular damping coefficient. @@ -319,7 +358,7 @@ public: @see getAngularDamping() setLinearDamping() */ - virtual void setAngularDamping(PxReal angDamp) = 0; + virtual void setAngularDamping(PxReal angDamp) = 0; /** \brief Retrieves the angular damping coefficient. @@ -328,76 +367,62 @@ public: @see setAngularDamping() getLinearDamping() */ - virtual PxReal getAngularDamping() const = 0; + virtual PxReal getAngularDamping() const = 0; /************************************************************************************************/ /** @name Velocity */ - /** \brief Retrieves the linear velocity of an actor. + \note It is not allowed to use this method while the simulation is running (except during PxScene::collide(), + in PxContactModifyCallback or in contact report callbacks). + \return The linear velocity of the actor. @see PxRigidDynamic.setLinearVelocity() getAngularVelocity() */ - virtual PxVec3 getLinearVelocity() const = 0; - - /** - \brief Sets the linear velocity of the actor. - - Note that if you continuously set the velocity of an actor yourself, - forces such as gravity or friction will not be able to manifest themselves, because forces directly - influence only the velocity/momentum of an actor. - - Default: (0.0, 0.0, 0.0) - - Sleeping: This call wakes the actor if it is sleeping, the autowake parameter is true (default) or the - new velocity is non-zero - - \note It is invalid to use this method if PxActorFlag::eDISABLE_SIMULATION is set. - - \param[in] linVel New linear velocity of actor. Range: velocity vector - \param[in] autowake Whether to wake the object up if it is asleep and the velocity is non-zero. If true and the current wake counter value is smaller than #PxSceneDesc::wakeCounterResetValue it will get increased to the reset value. - - @see getLinearVelocity() setAngularVelocity() - */ - virtual void setLinearVelocity(const PxVec3& linVel, bool autowake = true ) = 0; - - + virtual PxVec3 getLinearVelocity() const = 0; /** \brief Retrieves the angular velocity of the actor. + \note It is not allowed to use this method while the simulation is running (except during PxScene::collide(), + in PxContactModifyCallback or in contact report callbacks). + \return The angular velocity of the actor. @see PxRigidDynamic.setAngularVelocity() getLinearVelocity() */ - virtual PxVec3 getAngularVelocity() const = 0; - + virtual PxVec3 getAngularVelocity() const = 0; /** - \brief Sets the angular velocity of the actor. - - Note that if you continuously set the angular velocity of an actor yourself, - forces such as friction will not be able to rotate the actor, because forces directly influence only the velocity/momentum. + \brief Lets you set the maximum linear velocity permitted for this actor. - Default: (0.0, 0.0, 0.0) + With this function, you can set the maximum linear velocity permitted for this rigid body. + Higher angular velocities are clamped to this value. - Sleeping: This call wakes the actor if it is sleeping, the autowake parameter is true (default) or the - new velocity is non-zero + Note: The angular velocity is clamped to the set value before the solver, which means that + the limit may still be momentarily exceeded. - \note It is invalid to use this method if PxActorFlag::eDISABLE_SIMULATION is set. + Default: PX_MAX_F32 - \param[in] angVel New angular velocity of actor. Range: angular velocity vector - \param[in] autowake Whether to wake the object up if it is asleep and the velocity is non-zero. If true and the current wake - counter value is smaller than #PxSceneDesc::wakeCounterResetValue it will get increased to the reset value. + \param[in] maxLinVel Max allowable linear velocity for actor. Range: [0, PX_MAX_F32) - @see getAngularVelocity() setLinearVelocity() + @see getMaxAngularVelocity() */ - virtual void setAngularVelocity(const PxVec3& angVel, bool autowake = true ) = 0; + virtual void setMaxLinearVelocity(PxReal maxLinVel) = 0; + + /** + \brief Retrieves the maximum angular velocity permitted for this actor. + + \return The maximum allowed angular velocity for this actor. + + @see setMaxLinearVelocity + */ + virtual PxReal getMaxLinearVelocity() const = 0; /** \brief Lets you set the maximum angular velocity permitted for this actor. @@ -417,7 +442,7 @@ public: @see getMaxAngularVelocity() */ - virtual void setMaxAngularVelocity(PxReal maxAngVel) = 0; + virtual void setMaxAngularVelocity(PxReal maxAngVel) = 0; /** \brief Retrieves the maximum angular velocity permitted for this actor. @@ -426,35 +451,7 @@ public: @see setMaxAngularVelocity */ - virtual PxReal getMaxAngularVelocity() const = 0; - - - /** - \brief Lets you set the maximum linear velocity permitted for this actor. - - With this function, you can set the maximum linear velocity permitted for this rigid body. - Higher angular velocities are clamped to this value. - - Note: The angular velocity is clamped to the set value before the solver, which means that - the limit may still be momentarily exceeded. - - Default: PX_MAX_F32 - - \param[in] maxLinVel Max allowable linear velocity for actor. Range: [0, PX_MAX_F32) - - @see getMaxAngularVelocity() - */ - virtual void setMaxLinearVelocity(PxReal maxLinVel) = 0; - - /** - \brief Retrieves the maximum angular velocity permitted for this actor. - - \return The maximum allowed angular velocity for this actor. - - @see setMaxLinearVelocity - */ - virtual PxReal getMaxLinearVelocity() const = 0; - + virtual PxReal getMaxAngularVelocity() const = 0; /************************************************************************************************/ /** @name Forces @@ -472,7 +469,6 @@ public: accumulators and are just short hand for multiplying the vector parameter by inverse mass and then using PxForceMode::eACCELERATION and PxForceMode::eVELOCITY_CHANGE respectively. - \note It is invalid to use this method if the actor has not been added to a scene already or if PxActorFlag::eDISABLE_SIMULATION is set. \note The force modes PxForceMode::eIMPULSE and PxForceMode::eVELOCITY_CHANGE can not be applied to articulation links. @@ -482,15 +478,16 @@ public: \note see #PxRigidBodyExt::computeVelocityDeltaFromImpulse for details of how to compute the change in linear velocity that will arise from the application of an impulsive force, where an impulsive force is applied force multiplied by a timestep. - Sleeping: This call wakes the actor if it is sleeping and the autowake parameter is true (default) or the force is non-zero. + Sleeping: This call wakes the actor if it is sleeping, and the autowake parameter is true (default) or the force is non-zero. \param[in] force Force/Impulse to apply defined in the global frame. \param[in] mode The mode to use when applying the force/impulse(see #PxForceMode) - \param[in] autowake Specify if the call should wake up the actor if it is currently asleep. If true and the current wake counter value is smaller than #PxSceneDesc::wakeCounterResetValue it will get increased to the reset value. + \param[in] autowake Specify if the call should wake up the actor if it is currently asleep. If true and the current wake counter value + is smaller than #PxSceneDesc::wakeCounterResetValue it will get increased to the reset value. @see PxForceMode addTorque */ - virtual void addForce(const PxVec3& force, PxForceMode::Enum mode = PxForceMode::eFORCE, bool autowake = true) = 0; + virtual void addForce(const PxVec3& force, PxForceMode::Enum mode = PxForceMode::eFORCE, bool autowake = true) = 0; /** \brief Applies an impulsive torque defined in the global coordinate frame to the actor. @@ -502,7 +499,6 @@ public: also modify these same accumulators and are just short hand for multiplying the vector parameter by inverse inertia and then using PxForceMode::eACCELERATION and PxForceMode::eVELOCITY_CHANGE respectively. - \note It is invalid to use this method if the actor has not been added to a scene already or if PxActorFlag::eDISABLE_SIMULATION is set. \note The force modes PxForceMode::eIMPULSE and PxForceMode::eVELOCITY_CHANGE can not be applied to articulation links. @@ -512,15 +508,16 @@ public: \note see #PxRigidBodyExt::computeVelocityDeltaFromImpulse for details of how to compute the change in angular velocity that will arise from the application of an impulsive torque, where an impulsive torque is an applied torque multiplied by a timestep. - Sleeping: This call wakes the actor if it is sleeping and the autowake parameter is true (default) or the torque is non-zero. + Sleeping: This call wakes the actor if it is sleeping, and the autowake parameter is true (default) or the torque is non-zero. \param[in] torque Torque to apply defined in the global frame. Range: torque vector \param[in] mode The mode to use when applying the force/impulse(see #PxForceMode). - \param[in] autowake whether to wake up the object if it is asleep. If true and the current wake counter value is smaller than #PxSceneDesc::wakeCounterResetValue it will get increased to the reset value. + \param[in] autowake Specify if the call should wake up the actor if it is currently asleep. If true and the current wake counter value + is smaller than #PxSceneDesc::wakeCounterResetValue it will get increased to the reset value. @see PxForceMode addForce() */ - virtual void addTorque(const PxVec3& torque, PxForceMode::Enum mode = PxForceMode::eFORCE, bool autowake = true) = 0; + virtual void addTorque(const PxVec3& torque, PxForceMode::Enum mode = PxForceMode::eFORCE, bool autowake = true) = 0; /** \brief Clears the accumulated forces (sets the accumulated force back to zero). @@ -541,7 +538,7 @@ public: @see PxForceMode addForce */ - virtual void clearForce(PxForceMode::Enum mode = PxForceMode::eFORCE) = 0; + virtual void clearForce(PxForceMode::Enum mode = PxForceMode::eFORCE) = 0; /** \brief Clears the impulsive torque defined in the global coordinate frame to the actor. @@ -562,8 +559,7 @@ public: @see PxForceMode addTorque */ - virtual void clearTorque(PxForceMode::Enum mode = PxForceMode::eFORCE) = 0; - + virtual void clearTorque(PxForceMode::Enum mode = PxForceMode::eFORCE) = 0; /** \brief Sets the impulsive force and torque defined in the global coordinate frame to the actor. @@ -576,7 +572,7 @@ public: @see PxForceMode addTorque */ - virtual void setForceAndTorque(const PxVec3& force, const PxVec3& torque, PxForceMode::Enum mode = PxForceMode::eFORCE) = 0; + virtual void setForceAndTorque(const PxVec3& force, const PxVec3& torque, PxForceMode::Enum mode = PxForceMode::eFORCE) = 0; /** \brief Raises or clears a particular rigid body flag. @@ -592,9 +588,8 @@ public: @see PxRigidBodyFlag getRigidBodyFlags() */ - - virtual void setRigidBodyFlag(PxRigidBodyFlag::Enum flag, bool value) = 0; - virtual void setRigidBodyFlags(PxRigidBodyFlags inFlags) = 0; + virtual void setRigidBodyFlag(PxRigidBodyFlag::Enum flag, bool value) = 0; + virtual void setRigidBodyFlags(PxRigidBodyFlags inFlags) = 0; /** \brief Reads the PxRigidBody flags. @@ -627,7 +622,6 @@ public: \param[in] advanceCoefficient The CCD min advance coefficient. Range: [0, 1] Default: 0.15 */ - virtual void setMinCCDAdvanceCoefficient(PxReal advanceCoefficient) = 0; /** @@ -636,12 +630,9 @@ public: \return The value of the CCD min advance coefficient. @see setMinCCDAdvanceCoefficient - */ - virtual PxReal getMinCCDAdvanceCoefficient() const = 0; - /** \brief Sets the maximum depenetration velocity permitted to be introduced by the solver. This value controls how much velocity the solver can introduce to correct for penetrations in contacts. @@ -656,7 +647,6 @@ public: */ virtual PxReal getMaxDepenetrationVelocity() const = 0; - /** \brief Sets a limit on the impulse that may be applied at a contact. The maximum impulse at a contact between two dynamic or kinematic bodies will be the minimum of the two limit values. For a collision between a static and a dynamic body, the impulse is limited @@ -678,21 +668,40 @@ public: virtual PxReal getMaxContactImpulse() const = 0; /** - \brief Returns the island node index that only for internal use only + \brief Sets a distance scale whereby the angular influence of a contact on the normal constraint in a contact is + zeroed if normal.cross(offset) falls below this tolerance. Rather than acting as an absolute value, this tolerance + is scaled by the ratio rXn.dot(angVel)/normal.dot(linVel) such that contacts that have relatively larger angular velocity + than linear normal velocity (e.g. rolling wheels) achieve larger slop values as the angular velocity increases. - \return The island node index that only for internal use only + \param[in] slopCoefficient the Slop coefficient. Range: [0, PX_MAX_F32] Default: 0 + + @see getContactSlopCoefficient */ - virtual PxU32 getInternalIslandNodeIndex() const = 0; + virtual void setContactSlopCoefficient(PxReal slopCoefficient) = 0; + /** + \brief Returns the contact slop coefficient. + + \return The contact slop coefficient. + + @see setContactSlopCoefficient + */ + virtual PxReal getContactSlopCoefficient() const = 0; + + /** + \brief Returns the island node index + + \return The island node index. + */ + virtual PxNodeIndex getInternalIslandNodeIndex() const = 0; protected: - PX_INLINE PxRigidBody(PxType concreteType, PxBaseFlags baseFlags) : PxRigidActor(concreteType, baseFlags) {} - PX_INLINE PxRigidBody(PxBaseFlags baseFlags) : PxRigidActor(baseFlags) {} - virtual ~PxRigidBody() {} - virtual bool isKindOf(const char* name)const { return !::strcmp("PxRigidBody", name) || PxRigidActor::isKindOf(name); } + PX_INLINE PxRigidBody(PxType concreteType, PxBaseFlags baseFlags) : PxRigidActor(concreteType, baseFlags) {} + PX_INLINE PxRigidBody(PxBaseFlags baseFlags) : PxRigidActor(baseFlags) {} + virtual ~PxRigidBody() {} + virtual bool isKindOf(const char* name) const { return !::strcmp("PxRigidBody", name) || PxRigidActor::isKindOf(name); } }; - #if !PX_DOXYGEN } // namespace physx #endif diff --git a/Source/ThirdParty/PhysX/PxRigidDynamic.h b/Source/ThirdParty/PhysX/PxRigidDynamic.h index 84cb66060..fa46bc6ba 100644 --- a/Source/ThirdParty/PhysX/PxRigidDynamic.h +++ b/Source/ThirdParty/PhysX/PxRigidDynamic.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_NX_RIGIDDYNAMIC -#define PX_PHYSICS_NX_RIGIDDYNAMIC +#ifndef PX_RIGID_DYNAMIC_H +#define PX_RIGID_DYNAMIC_H /** \addtogroup physics @{ */ @@ -155,12 +153,14 @@ public: If an actor is asleep after the call to PxScene::fetchResults() returns, it is guaranteed that the pose of the actor was not changed. You can use this information to avoid updating the transforms of associated objects. - \note A kinematic actor is asleep unless a target pose has been set (in which case it will stay awake until the end of the next - simulation step where no target pose has been set anymore). The wake counter will get set to zero or to the reset value + \note A kinematic actor is asleep unless a target pose has been set (in which case it will stay awake until two consecutive + simulation steps without a target pose being set have passed). The wake counter will get set to zero or to the reset value #PxSceneDesc::wakeCounterResetValue in the case where a target pose has been set to be consistent with the definitions above. \note It is invalid to use this method if the actor has not been added to a scene already. + \note It is not allowed to use this method while the simulation is running. + \return True if the actor is sleeping. @see isSleeping() wakeUp() putToSleep() getSleepThreshold() @@ -244,8 +244,72 @@ public: virtual void setRigidDynamicLockFlag(PxRigidDynamicLockFlag::Enum flag, bool value) = 0; virtual void setRigidDynamicLockFlags(PxRigidDynamicLockFlags flags) = 0; + /** + \brief Retrieves the linear velocity of an actor. + \note It is not allowed to use this method while the simulation is running (except during PxScene::collide(), + in PxContactModifyCallback or in contact report callbacks). + \return The linear velocity of the actor. + + @see PxRigidDynamic.setLinearVelocity() getAngularVelocity() + */ + virtual PxVec3 getLinearVelocity() const = 0; + + /** + \brief Sets the linear velocity of the actor. + + Note that if you continuously set the velocity of an actor yourself, + forces such as gravity or friction will not be able to manifest themselves, because forces directly + influence only the velocity/momentum of an actor. + + Default: (0.0, 0.0, 0.0) + + Sleeping: This call wakes the actor if it is sleeping, and the autowake parameter is true (default) or the + new velocity is non-zero. + + \note It is invalid to use this method if PxActorFlag::eDISABLE_SIMULATION is set. + + \param[in] linVel New linear velocity of actor. Range: velocity vector + \param[in] autowake Whether to wake the object up if it is asleep. If true and the current wake counter value is + smaller than #PxSceneDesc::wakeCounterResetValue it will get increased to the reset value. + + @see getLinearVelocity() setAngularVelocity() + */ + virtual void setLinearVelocity(const PxVec3& linVel, bool autowake = true) = 0; + + /** + \brief Retrieves the angular velocity of the actor. + + \note It is not allowed to use this method while the simulation is running (except during PxScene::collide(), + in PxContactModifyCallback or in contact report callbacks). + + \return The angular velocity of the actor. + + @see PxRigidDynamic.setAngularVelocity() getLinearVelocity() + */ + virtual PxVec3 getAngularVelocity() const = 0; + + /** + \brief Sets the angular velocity of the actor. + + Note that if you continuously set the angular velocity of an actor yourself, + forces such as friction will not be able to rotate the actor, because forces directly influence only the velocity/momentum. + + Default: (0.0, 0.0, 0.0) + + Sleeping: This call wakes the actor if it is sleeping, and the autowake parameter is true (default) or the + new velocity is non-zero. + + \note It is invalid to use this method if PxActorFlag::eDISABLE_SIMULATION is set. + + \param[in] angVel New angular velocity of actor. Range: angular velocity vector + \param[in] autowake Whether to wake the object up if it is asleep. If true and the current wake counter value is + smaller than #PxSceneDesc::wakeCounterResetValue it will get increased to the reset value. + + @see getAngularVelocity() setLinearVelocity() + */ + virtual void setAngularVelocity(const PxVec3& angVel, bool autowake = true) = 0; /** \brief Sets the wake counter for the actor. @@ -271,6 +335,8 @@ public: /** \brief Returns the wake counter of the actor. + \note It is not allowed to use this method while the simulation is running. + \return The wake counter of the actor. @see isSleeping() setWakeCounter() @@ -325,7 +391,7 @@ public: Default: 4 position iterations, 1 velocity iteration \param[in] minPositionIters Number of position iterations the solver should perform for this body. Range: [1,255] - \param[in] minVelocityIters Number of velocity iterations the solver should perform for this body. Range: [1,255] + \param[in] minVelocityIters Number of velocity iterations the solver should perform for this body. Range: [0,255] @see getSolverIterationCounts() */ @@ -373,7 +439,7 @@ public: virtual const char* getConcreteTypeName() const { return "PxRigidDynamic"; } protected: - PX_INLINE PxRigidDynamic(PxType concreteType, PxBaseFlags baseFlags) : PxRigidBody(concreteType, baseFlags) {} + PX_INLINE PxRigidDynamic(PxType concreteType, PxBaseFlags baseFlags) : PxRigidBody(concreteType, baseFlags) { } PX_INLINE PxRigidDynamic(PxBaseFlags baseFlags) : PxRigidBody(baseFlags) {} virtual ~PxRigidDynamic() {} virtual bool isKindOf(const char* name) const { return !::strcmp("PxRigidDynamic", name) || PxRigidBody::isKindOf(name); } diff --git a/Source/ThirdParty/PhysX/PxRigidStatic.h b/Source/ThirdParty/PhysX/PxRigidStatic.h index e5fbd650a..57c6ebe02 100644 --- a/Source/ThirdParty/PhysX/PxRigidStatic.h +++ b/Source/ThirdParty/PhysX/PxRigidStatic.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_NX_RIGIDSTATIC -#define PX_PHYSICS_NX_RIGIDSTATIC +#ifndef PX_RIGID_STATIC_H +#define PX_RIGID_STATIC_H /** \addtogroup physics @{ */ @@ -63,7 +61,7 @@ public: protected: PX_INLINE PxRigidStatic(PxType concreteType, PxBaseFlags baseFlags) : PxRigidActor(concreteType, baseFlags) {} - PX_INLINE PxRigidStatic(PxBaseFlags baseFlags) : PxRigidActor(baseFlags) {} + PX_INLINE PxRigidStatic(PxBaseFlags baseFlags) : PxRigidActor(baseFlags){} virtual ~PxRigidStatic() {} virtual bool isKindOf(const char* name) const { return !::strcmp("PxRigidStatic", name) || PxRigidActor::isKindOf(name); } diff --git a/Source/ThirdParty/PhysX/PxScene.h b/Source/ThirdParty/PhysX/PxScene.h index ebe579f06..a99d5cdf5 100644 --- a/Source/ThirdParty/PhysX/PxScene.h +++ b/Source/ThirdParty/PhysX/PxScene.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,24 +22,28 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_NX_SCENE -#define PX_PHYSICS_NX_SCENE +#ifndef PX_SCENE_H +#define PX_SCENE_H /** \addtogroup physics @{ */ -#include "PxVisualizationParameter.h" +#include "PxSceneQuerySystem.h" #include "PxSceneDesc.h" +#include "PxVisualizationParameter.h" #include "PxSimulationStatistics.h" -#include "PxQueryReport.h" -#include "PxQueryFiltering.h" #include "PxClient.h" #include "task/PxTask.h" +#include "PxArticulationFlag.h" +#include "PxSoftBodyFlag.h" +#include "PxHairSystemFlag.h" +#include "PxActorData.h" +#include "PxParticleSystemFlag.h" +#include "PxParticleSolverType.h" #include "pvd/PxPvdSceneClient.h" @@ -49,29 +52,25 @@ namespace physx { #endif -class PxRigidStatic; -class PxRigidDynamic; +class PxCollection; class PxConstraint; -class PxMaterial; class PxSimulationEventCallback; class PxPhysics; -class PxBatchQueryDesc; -class PxBatchQuery; class PxAggregate; class PxRenderBuffer; +class PxArticulationReducedCoordinate; +class PxParticleSystem; -class PxSphereGeometry; -class PxBoxGeometry; -class PxCapsuleGeometry; - -class PxPruningStructure; -class PxBVHStructure; struct PxContactPairHeader; typedef PxU8 PxDominanceGroup; class PxPvdSceneClient; +class PxSoftBody; +class PxFEMCloth; +class PxHairSystem; + /** \brief Expresses the dominance relationship of a contact. For the time being only three settings are permitted: @@ -92,7 +91,7 @@ struct PxDominanceGroupPair /** \brief Identifies each type of actor for retrieving actors from a scene. -\note #PxArticulationLink objects are not supported. Use the #PxArticulation object to retrieve all its links. +\note #PxArticulationLink objects are not supported. Use the #PxArticulationReducedCoordinate object to retrieve all its links. @see PxScene::getActors(), PxScene::getNbActors() */ @@ -122,39 +121,48 @@ struct PxActorTypeFlag typedef PxFlags PxActorTypeFlags; PX_FLAGS_OPERATORS(PxActorTypeFlag::Enum,PxU16) +class PxActor; + /** -\brief single hit cache for scene queries. +\brief Broad-phase callback to receive broad-phase related events. -If a cache object is supplied to a scene query, the cached actor/shape pair is checked for intersection first. -\note Filters are not executed for the cached shape. -\note If intersection is found, the hit is treated as blocking. -\note Typically actor and shape from the last PxHitCallback.block query result is used as a cached actor/shape pair. -\note Using past touching hits as cache will produce incorrect behavior since the cached hit will always be treated as blocking. -\note Cache is only used if no touch buffer was provided, for single nearest blocking hit queries and queries using eANY_HIT flag. -\note if non-zero touch buffer was provided, cache will be ignored +Each broadphase callback object is associated with a PxClientID. It is possible to register different +callbacks for different clients. The callback functions are called this way: +- for shapes/actors, the callback assigned to the actors' clients are used +- for aggregates, the callbacks assigned to clients from aggregated actors are used -\note It is the user's responsibility to ensure that the shape and actor are valid, so care must be taken -when deleting shapes to invalidate cached references. +\note SDK state should not be modified from within the callbacks. In particular objects should not +be created or destroyed. If state modification is needed then the changes should be stored to a buffer +and performed after the simulation step. -The faceIndex field is an additional hint for a mesh or height field which is not currently used. +Threading: It is not necessary to make this class thread safe as it will only be called in the context of the +user thread. -@see PxScene.raycast +@see PxSceneDesc PxScene.setBroadPhaseCallback() PxScene.getBroadPhaseCallback() */ -struct PxQueryCache +class PxBroadPhaseCallback { - /** - \brief constructor sets to default - */ - PX_INLINE PxQueryCache() : shape(NULL), actor(NULL), faceIndex(0xffffffff) {} + public: + virtual ~PxBroadPhaseCallback() {} /** - \brief constructor to set properties - */ - PX_INLINE PxQueryCache(PxShape* s, PxU32 findex) : shape(s), actor(NULL), faceIndex(findex) {} + \brief Out-of-bounds notification. + + This function is called when an object leaves the broad-phase. - PxShape* shape; //!< Shape to test for intersection first - PxRigidActor* actor; //!< Actor to which the shape belongs - PxU32 faceIndex; //!< Triangle index to test first - NOT CURRENTLY SUPPORTED + \param[in] shape Shape that left the broad-phase bounds + \param[in] actor Owner actor + */ + virtual void onObjectOutOfBounds(PxShape& shape, PxActor& actor) = 0; + + /** + \brief Out-of-bounds notification. + + This function is called when an aggregate leaves the broad-phase. + + \param[in] aggregate Aggregate that left the broad-phase bounds + */ + virtual void onObjectOutOfBounds(PxAggregate& aggregate) = 0; }; /** @@ -166,7 +174,7 @@ struct PxQueryCache @see PxSceneDesc PxPhysics.createScene() release() */ -class PxScene +class PxScene : public PxSceneSQSystem { protected: @@ -176,8 +184,8 @@ class PxScene */ //@{ - PxScene(): userData(0) {} - virtual ~PxScene() {} + PxScene() : userData(NULL) {} + virtual ~PxScene() {} public: @@ -212,7 +220,6 @@ class PxScene */ virtual PxSceneFlags getFlags() const = 0; - /** \brief Set new scene limits. @@ -232,7 +239,6 @@ class PxScene */ virtual PxSceneLimits getLimits() const = 0; - /** \brief Call this method to retrieve the Physics SDK. @@ -249,43 +255,45 @@ class PxScene */ virtual PxU32 getTimestamp() const = 0; - //@} /************************************************************************************************/ - /** @name Add/Remove Contained Objects + /** @name Add/Remove Articulations */ //@{ /** \brief Adds an articulation to this scene. - \note If the articulation is already assigned to a scene (see #PxArticulation::getScene), the call is ignored and an error is issued. + \note If the articulation is already assigned to a scene (see #PxArticulationReducedCoordinate::getScene), the call is ignored and an error is issued. - \param[in] articulation Articulation to add to scene. See #PxArticulation + \param[in] articulation The articulation to add to the scene. + \return True if success - @see PxArticulation + @see PxArticulationReducedCoordinate */ - virtual void addArticulation(PxArticulationBase& articulation) = 0; + virtual bool addArticulation(PxArticulationReducedCoordinate& articulation) = 0; /** \brief Removes an articulation from this scene. - \note If the articulation is not part of this scene (see #PxArticulation::getScene), the call is ignored and an error is issued. + \note If the articulation is not part of this scene (see #PxArticulationReducedCoordinate::getScene), the call is ignored and an error is issued. \note If the articulation is in an aggregate it will be removed from the aggregate. - \param[in] articulation Articulation to remove from scene. See #PxArticulation - \param[in] wakeOnLostTouch Specifies whether touching objects from the previous frame should get woken up in the next frame. Only applies to PxArticulation and PxRigidActor types. + \param[in] articulation The articulation to remove from the scene. + \param[in] wakeOnLostTouch Specifies whether touching objects from the previous frame should get woken up in the next frame. + Only applies to PxArticulationReducedCoordinate and PxRigidActor types. - @see PxArticulation, PxAggregate + @see PxArticulationReducedCoordinate, PxAggregate */ - virtual void removeArticulation(PxArticulationBase& articulation, bool wakeOnLostTouch = true) = 0; - + virtual void removeArticulation(PxArticulationReducedCoordinate& articulation, bool wakeOnLostTouch = true) = 0; //@} /************************************************************************************************/ - + /** @name Add/Remove Actors + */ + //@{ /** \brief Adds an actor to this scene. @@ -297,47 +305,52 @@ class PxScene \note If the actor is a PxRigidActor then each assigned PxConstraint object will get added to the scene automatically if it connects to another actor that is part of the scene already. - \note When BVHStructure is provided the actor shapes are grouped together. + \note When a BVH is provided the actor shapes are grouped together. The scene query pruning structure inside PhysX SDK will store/update one bound per actor. The scene queries against such an actor will query actor - bounds and then make a local space query against the provided BVH structure, which is in - actor's local space. + bounds and then make a local space query against the provided BVH, which is in actor's local space. - \param[in] actor Actor to add to scene. - \param[in] bvhStructure BVHStructure for actor shapes. + \param[in] actor Actor to add to scene. + \param[in] bvh BVH for actor shapes. + \return True if success - @see PxActor, PxConstraint::isValid(), PxBVHStructure + @see PxActor, PxConstraint::isValid(), PxBVH */ - virtual void addActor(PxActor& actor, const PxBVHStructure* bvhStructure = NULL) = 0; + virtual bool addActor(PxActor& actor, const PxBVH* bvh = NULL) = 0; /** - \brief Adds actors to this scene. + \brief Adds actors to this scene. Only supports actors of type PxRigidStatic and PxRigidDynamic. + + \note This method only supports actors of type PxRigidStatic and PxRigidDynamic. For other actors, use addActor() instead. + For articulation links, use addArticulation(). \note If one of the actors is already assigned to a scene (see #PxActor::getScene), the call is ignored and an error is issued. - \note You can not add individual articulation links (see #PxArticulationLink) to the scene. Use #addArticulation() instead. - \note If an actor in the array contains an invalid constraint, in checked builds the call is ignored and an error is issued. \note If an actor in the array is a PxRigidActor then each assigned PxConstraint object will get added to the scene automatically if it connects to another actor that is part of the scene already. - \note this method is optimized for high performance, and does not support buffering. It may not be called during simulation. + \note this method is optimized for high performance. \param[in] actors Array of actors to add to scene. \param[in] nbActors Number of actors in the array. + \return True if success @see PxActor, PxConstraint::isValid() */ - virtual void addActors(PxActor*const* actors, PxU32 nbActors) = 0; + virtual bool addActors(PxActor*const* actors, PxU32 nbActors) = 0; /** - \brief Adds a pruning structure together with its actors to this scene. + \brief Adds a pruning structure together with its actors to this scene. Only supports actors of type PxRigidStatic and PxRigidDynamic. + + \note This method only supports actors of type PxRigidStatic and PxRigidDynamic. For other actors, use addActor() instead. + For articulation links, use addArticulation(). \note If an actor in the pruning structure contains an invalid constraint, in checked builds the call is ignored and an error is issued. \note For all actors in the pruning structure each assigned PxConstraint object will get added to the scene automatically if it connects to another actor that is part of the scene already. - \note This method is optimized for high performance, and does not support buffering. It may not be called during simulation. + \note This method is optimized for high performance. \note Merging a PxPruningStructure into an active scene query optimization AABB tree might unbalance the tree. A typical use case for PxPruningStructure is a large world scenario where blocks of closely positioned actors get streamed in. The merge process finds the @@ -345,10 +358,11 @@ class PxScene for actors scattered throughout the world will result in an unbalanced tree. \param[in] pruningStructure Pruning structure for a set of actors. + \return True if success @see PxPhysics::createPruningStructure, PxPruningStructure */ - virtual void addActors(const PxPruningStructure& pruningStructure) = 0; + virtual bool addActors(const PxPruningStructure& pruningStructure) = 0; /** \brief Removes an actor from this scene. @@ -362,14 +376,17 @@ class PxScene \note If the actor is in an aggregate it will be removed from the aggregate. \param[in] actor Actor to remove from scene. - \param[in] wakeOnLostTouch Specifies whether touching objects from the previous frame should get woken up in the next frame. Only applies to PxArticulation and PxRigidActor types. + \param[in] wakeOnLostTouch Specifies whether touching objects from the previous frame should get woken up in the next frame. Only applies to PxArticulationReducedCoordinate and PxRigidActor types. @see PxActor, PxAggregate */ virtual void removeActor(PxActor& actor, bool wakeOnLostTouch = true) = 0; /** - \brief Removes actors from this scene. + \brief Removes actors from this scene. Only supports actors of type PxRigidStatic and PxRigidDynamic. + + \note This method only supports actors of type PxRigidStatic and PxRigidDynamic. For other actors, use removeActor() instead. + For articulation links, use removeArticulation(). \note If some actor is not part of this scene (see #PxActor::getScene), the actor remove is ignored and an error is issued. @@ -379,7 +396,7 @@ class PxScene \param[in] actors Array of actors to add to scene. \param[in] nbActors Number of actors in the array. - \param[in] wakeOnLostTouch Specifies whether touching objects from the previous frame should get woken up in the next frame. Only applies to PxArticulation and PxRigidActor types. + \param[in] wakeOnLostTouch Specifies whether touching objects from the previous frame should get woken up in the next frame. Only applies to PxArticulationReducedCooridnate and PxRigidActor types. @see PxActor */ @@ -394,10 +411,11 @@ class PxScene \note If the aggregate already contains actors, those actors are added to the scene as well. \param[in] aggregate Aggregate to add to scene. + \return True if success @see PxAggregate, PxConstraint::isValid() */ - virtual void addAggregate(PxAggregate& aggregate) = 0; + virtual bool addAggregate(PxAggregate& aggregate) = 0; /** \brief Removes an aggregate from this scene. @@ -407,7 +425,7 @@ class PxScene \note If the aggregate contains actors, those actors are removed from the scene as well. \param[in] aggregate Aggregate to remove from scene. - \param[in] wakeOnLostTouch Specifies whether touching objects from the previous frame should get woken up in the next frame. Only applies to PxArticulation and PxRigidActor types. + \param[in] wakeOnLostTouch Specifies whether touching objects from the previous frame should get woken up in the next frame. Only applies to PxArticulationReducedCoordinate and PxRigidActor types. @see PxAggregate */ @@ -416,16 +434,17 @@ class PxScene /** \brief Adds objects in the collection to this scene. - This function adds the following types of objects to this scene: PxActor, PxAggregate, PxArticulation. + This function adds the following types of objects to this scene: PxRigidActor (except PxArticulationLink), PxAggregate, PxArticulationReducedCoordinate. This method is typically used after deserializing the collection in order to populate the scene with deserialized objects. \note If the collection contains an actor with an invalid constraint, in checked builds the call is ignored and an error is issued. \param[in] collection Objects to add to this scene. See #PxCollection + \return True if success @see PxCollection, PxConstraint::isValid() */ - virtual void addCollection(const PxCollection& collection) = 0; + virtual bool addCollection(const PxCollection& collection) = 0; //@} /************************************************************************************************/ @@ -434,7 +453,7 @@ class PxScene //@{ /** - \brief Retrieve the number of actors of certain types in the scene. + \brief Retrieve the number of actors of certain types in the scene. For supported types, see PxActorTypeFlags. \param[in] types Combination of actor types. \return the number of actors. @@ -444,7 +463,7 @@ class PxScene virtual PxU32 getNbActors(PxActorTypeFlags types) const = 0; /** - \brief Retrieve an array of all the actors of certain types in the scene. + \brief Retrieve an array of all the actors of certain types in the scene. For supported types, see PxActorTypeFlags. \param[in] types Combination of actor types to retrieve. \param[out] userBuffer The buffer to receive actor pointers. @@ -458,7 +477,7 @@ class PxScene /** \brief Queries the PxScene for a list of the PxActors whose transforms have been - updated during the previous simulation step + updated during the previous simulation step. Only includes actors of type PxRigidDynamic and PxArticulationLink. \note PxSceneFlag::eENABLE_ACTIVE_ACTORS must be set. @@ -472,6 +491,90 @@ class PxScene */ virtual PxActor** getActiveActors(PxU32& nbActorsOut) = 0; + /** + \brief Retrieve the number of soft bodies in the scene. + + \return the number of soft bodies. + + @see getActors() + */ + virtual PxU32 getNbSoftBodies() const = 0; + + /** + \brief Retrieve an array of all the soft bodies in the scene. + + \param[out] userBuffer The buffer to receive actor pointers. + \param[in] bufferSize Size of provided user buffer. + \param[in] startIndex Index of first actor pointer to be retrieved + \return Number of actors written to the buffer. + + @see getNbActors() + */ + virtual PxU32 getSoftBodies(PxSoftBody** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0; + + /** + \brief Retrieve the number of particle systems of the requested type in the scene. + + \param[in] type The particle system type. See PxParticleSolverType. Only one type can be requested per function call. + \return the number particle systems. + + See getParticleSystems(), PxParticleSolverType + */ + virtual PxU32 getNbParticleSystems(PxParticleSolverType::Enum type) const = 0; + + /** + \brief Retrieve an array of all the particle systems of the requested type in the scene. + + \param[in] type The particle system type. See PxParticleSolverType. Only one type can be requested per function call. + \param[out] userBuffer The buffer to receive particle system pointers. + \param[in] bufferSize Size of provided user buffer. + \param[in] startIndex Index of first particle system pointer to be retrieved + \return Number of particle systems written to the buffer. + + See getNbParticleSystems(), PxParticleSolverType + */ + virtual PxU32 getParticleSystems(PxParticleSolverType::Enum type, PxParticleSystem** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0; + + /** + \brief Retrieve the number of FEM cloths in the scene. + \warning Feature under development, only for internal usage. + + \return the number of FEM cloths. + + See getFEMCloths() + */ + virtual PxU32 getNbFEMCloths() const = 0; + + /** + \brief Retrieve an array of all the FEM cloths in the scene. + \warning Feature under development, only for internal usage. + + \param[out] userBuffer The buffer to write the FEM cloth pointers to + \param[in] bufferSize Size of the provided user buffer + \param[in] startIndex Index of first FEM cloth pointer to be retrieved + \return Number of FEM cloths written to the buffer + */ + virtual PxU32 getFEMCloths(PxFEMCloth** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0; + + /** + \brief Retrieve the number of hair systems in the scene. + \warning Feature under development, only for internal usage. + \return the number of hair systems + @see getActors() + */ + virtual PxU32 getNbHairSystems() const = 0; + + /** + \brief Retrieve an array of all the hair systems in the scene. + \warning Feature under development, only for internal usage. + + \param[out] userBuffer The buffer to write the actor pointers to + \param[in] bufferSize Size of the provided user buffer + \param[in] startIndex Index of first actor pointer to be retrieved + \return Number of actors written to the buffer + */ + virtual PxU32 getHairSystems(PxHairSystem** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0; + /** \brief Returns the number of articulations in the scene. @@ -491,7 +594,7 @@ class PxScene @see getNbArticulations() */ - virtual PxU32 getArticulations(PxArticulationBase** userBuffer, PxU32 bufferSize, PxU32 startIndex=0) const = 0; + virtual PxU32 getArticulations(PxArticulationReducedCoordinate** userBuffer, PxU32 bufferSize, PxU32 startIndex=0) const = 0; /** \brief Returns the number of constraint shaders in the scene. @@ -514,7 +617,6 @@ class PxScene */ virtual PxU32 getConstraints(PxConstraint** userBuffer, PxU32 bufferSize, PxU32 startIndex=0) const = 0; - /** \brief Returns the number of aggregates in the scene. @@ -810,13 +912,16 @@ class PxScene \note It is invalid to use this method if PxActorFlag::eDISABLE_SIMULATION is set. + \note Do not use this method while the simulation is running. + Sleeping: Does wake up the actor. \param[in] actor The actor for which to re-evaluate interactions. + \return True if success @see PxSimulationFilterShader PxSimulationFilterCallback */ - virtual void resetFiltering(PxActor& actor) = 0; + virtual bool resetFiltering(PxActor& actor) = 0; /** \brief Marks the object to reset interactions and re-run collision filters for specified shapes in the next simulation step. @@ -824,6 +929,8 @@ class PxScene This is a specialization of the resetFiltering(PxActor& actor) method and allows to reset interactions for specific shapes of a PxRigidActor. + \note Do not use this method while the simulation is running. + Sleeping: Does wake up the actor. \param[in] actor The actor for which to re-evaluate interactions. @@ -832,7 +939,7 @@ class PxScene @see PxSimulationFilterShader PxSimulationFilterCallback */ - virtual void resetFiltering(PxRigidActor& actor, PxShape*const* shapes, PxU32 shapeCount) = 0; + virtual bool resetFiltering(PxRigidActor& actor, PxShape*const* shapes, PxU32 shapeCount) = 0; /** \brief Gets the pair filtering mode for kinematic-kinematic pairs. @@ -886,13 +993,13 @@ class PxScene \param[in] scratchMemBlockSize the size of the scratch memory block. Must be a multiple of 16K. \param[in] controlSimulation if true, the scene controls its PxTaskManager simulation state. Leave true unless the application is calling the PxTaskManager start/stopSimulation() methods itself. + \return True if success @see fetchResults() checkResults() */ - virtual void simulate(PxReal elapsedTime, physx::PxBaseTask* completionTask = NULL, + virtual bool simulate(PxReal elapsedTime, physx::PxBaseTask* completionTask = NULL, void* scratchMemBlock = 0, PxU32 scratchMemBlockSize = 0, bool controlSimulation = true) = 0; - /** \brief Performs dynamics phase of the simulation pipeline. @@ -901,9 +1008,9 @@ class PxScene \param[in] completionTask if non-NULL, this task will have its refcount incremented in advance(), then decremented when the scene is ready to have fetchResults called. So the task will not run until the application also calls removeReference(). - + \return True if success */ - virtual void advance(physx::PxBaseTask* completionTask = 0) = 0; + virtual bool advance(physx::PxBaseTask* completionTask = 0) = 0; /** \brief Performs collision detection for the scene over elapsedTime @@ -920,9 +1027,9 @@ class PxScene \param[in] scratchMemBlockSize the size of the scratch memory block. Must be a multiple of 16K. \param[in] controlSimulation if true, the scene controls its PxTaskManager simulation state. Leave true unless the application is calling the PxTaskManager start/stopSimulation() methods itself. - + \return True if success */ - virtual void collide(PxReal elapsedTime, physx::PxBaseTask* completionTask = 0, void* scratchMemBlock = 0, + virtual bool collide(PxReal elapsedTime, physx::PxBaseTask* completionTask = 0, void* scratchMemBlock = 0, PxU32 scratchMemBlockSize = 0, bool controlSimulation = true) = 0; /** @@ -944,7 +1051,6 @@ class PxScene \param[in] block When set to true will block until the condition is met, which is collision must finish running. */ - virtual bool fetchCollision(bool block = false) = 0; /** @@ -970,10 +1076,8 @@ class PxScene */ virtual bool fetchResults(bool block = false, PxU32* errorState = 0) = 0; - /** - This call performs the first section of fetchResults (callbacks fired before swapBuffers), and returns a pointer to a - to the contact streams output by the simulation. It can be used to process contact pairs in parallel, which is often a limiting factor + This call performs the first section of fetchResults, and returns a pointer to the contact streams output by the simulation. It can be used to process contact pairs in parallel, which is often a limiting factor for fetchResults() performance. After calling this function and processing the contact streams, call fetchResultsFinish(). Note that writes to the simulation are not @@ -988,7 +1092,6 @@ class PxScene */ virtual bool fetchResultsStart(const PxContactPairHeader*& contactPairs, PxU32& nbContactPairs, bool block = false) = 0; - /** This call processes all event callbacks in parallel. It takes a continuation task, which will be executed once all callbacks have been processed. @@ -999,9 +1102,8 @@ class PxScene */ virtual void processCallbacks(physx::PxBaseTask* continuation) = 0; - /** - This call performs the second section of fetchResults: the buffer swap and subsequent callbacks. + This call performs the second section of fetchResults. It must be called after fetchResultsStart() returns and contact reports have been processed. @@ -1013,6 +1115,10 @@ class PxScene */ virtual void fetchResultsFinish(PxU32* errorState = 0) = 0; + /** + This call performs the synchronization of particle system data copies. + */ + virtual void fetchResultsParticleSystem() = 0; /** \brief Clear internal buffers and free memory. @@ -1029,6 +1135,8 @@ class PxScene /** \brief Sets a constant gravity for the entire scene. + \note Do not use this method while the simulation is running. + Sleeping: Does NOT wake the actor up automatically. \param[in] vec A new gravity vector(e.g. PxVec3(0.0f,-9.8f,0.0f) ) Range: force vector @@ -1049,6 +1157,8 @@ class PxScene /** \brief Set the bounce threshold velocity. Collision speeds below this threshold will not cause a bounce. + \note Do not use this method while the simulation is running. + @see PxSceneDesc::bounceThresholdVelocity, getBounceThresholdVelocity */ virtual void setBounceThresholdVelocity(const PxReal t) = 0; @@ -1060,14 +1170,14 @@ class PxScene */ virtual PxReal getBounceThresholdVelocity() const = 0; - /** \brief Sets the maximum number of CCD passes + \note Do not use this method while the simulation is running. + \param[in] ccdMaxPasses Maximum number of CCD passes @see PxSceneDesc.ccdMaxPasses getCCDMaxPasses() - */ virtual void setCCDMaxPasses(PxU32 ccdMaxPasses) = 0; @@ -1077,28 +1187,106 @@ class PxScene \return The maximum number of CCD passes. @see PxSceneDesc::ccdMaxPasses setCCDMaxPasses() - */ virtual PxU32 getCCDMaxPasses() const = 0; /** - \brief Return the value of frictionOffsetThreshold that was set in PxSceneDesc when creating the scene with PxPhysics::createScene + \brief Set the maximum CCD separation. - @see PxSceneDesc::frictionOffsetThreshold, PxPhysics::createScene + \note Do not use this method while the simulation is running. + + @see PxSceneDesc::ccdMaxSeparation, getCCDMaxSeparation + */ + virtual void setCCDMaxSeparation(const PxReal t) = 0; + + /** + \brief Gets the maximum CCD separation. + + \return The maximum CCD separation. + + @see PxSceneDesc::ccdMaxSeparation setCCDMaxSeparation() + */ + virtual PxReal getCCDMaxSeparation() const = 0; + + /** + \brief Set the CCD threshold. + + \note Do not use this method while the simulation is running. + + @see PxSceneDesc::ccdThreshold, getCCDThreshold + */ + virtual void setCCDThreshold(const PxReal t) = 0; + + /** + \brief Gets the CCD threshold. + + \return The CCD threshold. + + @see PxSceneDesc::ccdThreshold setCCDThreshold() + */ + virtual PxReal getCCDThreshold() const = 0; + + /** + \brief Set the max bias coefficient. + + \note Do not use this method while the simulation is running. + + @see PxSceneDesc::maxBiasCoefficient, getMaxBiasCoefficient + */ + virtual void setMaxBiasCoefficient(const PxReal t) = 0; + + /** + \brief Gets the max bias coefficient. + + \return The max bias coefficient. + + @see PxSceneDesc::maxBiasCoefficient setMaxBiasCoefficient() + */ + virtual PxReal getMaxBiasCoefficient() const = 0; + + /** + \brief Set the friction offset threshold. + + \note Do not use this method while the simulation is running. + + @see PxSceneDesc::frictionOffsetThreshold, getFrictionOffsetThreshold + */ + virtual void setFrictionOffsetThreshold(const PxReal t) = 0; + + /** + \brief Gets the friction offset threshold. + + @see PxSceneDesc::frictionOffsetThreshold, setFrictionOffsetThreshold */ virtual PxReal getFrictionOffsetThreshold() const = 0; /** - \brief Set the friction model. - @see PxFrictionType, PxSceneDesc::frictionType + \brief Set the friction correlation distance. + + \note Do not use this method while the simulation is running. + + @see PxSceneDesc::frictionCorrelationDistance, getFrictionCorrelationDistance */ - virtual void setFrictionType(PxFrictionType::Enum frictionType) = 0; + virtual void setFrictionCorrelationDistance(const PxReal t) = 0; + + /** + \brief Gets the friction correlation distance. + + @see PxSceneDesc::frictionCorrelationDistance, setFrictionCorrelationDistance + */ + virtual PxReal getFrictionCorrelationDistance() const = 0; /** \brief Return the friction model. @see PxFrictionType, PxSceneDesc::frictionType */ - virtual PxFrictionType::Enum getFrictionType() const = 0; + virtual PxFrictionType::Enum getFrictionType() const = 0; + + /** + \brief Return the solver model. + @see PxSolverType, PxSceneDesc::solverType + */ + virtual PxSolverType::Enum getSolverType() const = 0; //@} /************************************************************************************************/ @@ -1111,6 +1299,8 @@ class PxScene Returns false if the value passed is out of range for usage specified by the enum. + \note Do not use this method while the simulation is running. + \param[in] param Parameter to set. See #PxVisualizationParameter \param[in] value The value to set, see #PxVisualizationParameter for allowable values. Setting to zero disables visualization for the specified property, setting to a positive value usually enables visualization and defines the scale factor. \return False if the parameter is out of range. @@ -1129,9 +1319,10 @@ class PxScene */ virtual PxReal getVisualizationParameter(PxVisualizationParameter::Enum paramEnum) const = 0; - /** \brief Defines a box in world space to which visualization geometry will be (conservatively) culled. Use a non-empty culling box to enable the feature, and an empty culling box to disable it. + + \note Do not use this method while the simulation is running. \param[in] box the box to which the geometry will be culled. Empty box to disable the feature. @see setVisualizationParameter getVisualizationCullingBox getRenderBuffer() @@ -1151,7 +1342,7 @@ class PxScene This will contain the results of any active visualization for this scene. - \note Do not use this method while the simulation is running. Calls to this method while result in undefined behaviour. + \note Do not use this method while the simulation is running. Calls to this method while the simulation is running will result in undefined behaviour. \return The render buffer. @@ -1170,238 +1361,6 @@ class PxScene */ virtual void getSimulationStatistics(PxSimulationStatistics& stats) const = 0; - - //@} - /************************************************************************************************/ - - /** @name Scene Query - */ - //@{ - - /** - \brief Return the value of PxSceneDesc::staticStructure that was set when creating the scene with PxPhysics::createScene - - @see PxSceneDesc::staticStructure, PxPhysics::createScene - */ - virtual PxPruningStructureType::Enum getStaticStructure() const = 0; - - /** - \brief Return the value of PxSceneDesc::dynamicStructure that was set when creating the scene with PxPhysics::createScene - - @see PxSceneDesc::dynamicStructure, PxPhysics::createScene - */ - virtual PxPruningStructureType::Enum getDynamicStructure() const = 0; - - /** - \brief Flushes any changes to the scene query representation. - - This method updates the state of the scene query representation to match changes in the scene state. - - By default, these changes are buffered until the next query is submitted. Calling this function will not change - the results from scene queries, but can be used to ensure that a query will not perform update work in the course of - its execution. - - A thread performing updates will hold a write lock on the query structure, and thus stall other querying threads. In multithread - scenarios it can be useful to explicitly schedule the period where this lock may be held for a significant period, so that - subsequent queries issued from multiple threads will not block. - - */ - virtual void flushQueryUpdates() = 0; - - /** - \brief Creates a BatchQuery object. - - Scene queries like raycasts, overlap tests and sweeps are batched in this object and are then executed at once. See #PxBatchQuery. - - \deprecated The batched query feature has been deprecated in PhysX version 3.4 - - \param[in] desc The descriptor of scene query. Scene Queries need to register a callback. See #PxBatchQueryDesc. - - @see PxBatchQuery PxBatchQueryDesc - */ - PX_DEPRECATED virtual PxBatchQuery* createBatchQuery(const PxBatchQueryDesc& desc) = 0; - - /** - \brief Sets the rebuild rate of the dynamic tree pruning structures. - - \param[in] dynamicTreeRebuildRateHint Rebuild rate of the dynamic tree pruning structures. - - @see PxSceneDesc.dynamicTreeRebuildRateHint getDynamicTreeRebuildRateHint() forceDynamicTreeRebuild() - */ - virtual void setDynamicTreeRebuildRateHint(PxU32 dynamicTreeRebuildRateHint) = 0; - - /** - \brief Retrieves the rebuild rate of the dynamic tree pruning structures. - - \return The rebuild rate of the dynamic tree pruning structures. - - @see PxSceneDesc.dynamicTreeRebuildRateHint setDynamicTreeRebuildRateHint() forceDynamicTreeRebuild() - */ - virtual PxU32 getDynamicTreeRebuildRateHint() const = 0; - - /** - \brief Forces dynamic trees to be immediately rebuilt. - - \param[in] rebuildStaticStructure True to rebuild the dynamic tree containing static objects - \param[in] rebuildDynamicStructure True to rebuild the dynamic tree containing dynamic objects - - @see PxSceneDesc.dynamicTreeRebuildRateHint setDynamicTreeRebuildRateHint() getDynamicTreeRebuildRateHint() - */ - virtual void forceDynamicTreeRebuild(bool rebuildStaticStructure, bool rebuildDynamicStructure) = 0; - - /** - \brief Sets scene query update mode - - \param[in] updateMode Scene query update mode. - - @see PxSceneQueryUpdateMode::Enum - */ - virtual void setSceneQueryUpdateMode(PxSceneQueryUpdateMode::Enum updateMode) = 0; - - /** - \brief Gets scene query update mode - - \return Current scene query update mode. - - @see PxSceneQueryUpdateMode::Enum - */ - virtual PxSceneQueryUpdateMode::Enum getSceneQueryUpdateMode() const = 0; - - /** - \brief Executes scene queries update tasks. - This function will refit dirty shapes within the pruner and will execute a task to build a new AABB tree, which is - build on a different thread. The new AABB tree is built based on the dynamic tree rebuild hint rate. Once - the new tree is ready it will be commited in next fetchQueries call, which must be called after. - - \note If PxSceneQueryUpdateMode::eBUILD_DISABLED_COMMIT_DISABLED is used, it is required to update the scene queries - using this function. - - \param[in] completionTask if non-NULL, this task will have its refcount incremented in sceneQueryUpdate(), then - decremented when the scene is ready to have fetchQueries called. So the task will not run until the - application also calls removeReference(). - \param[in] controlSimulation if true, the scene controls its PxTaskManager simulation state. Leave - true unless the application is calling the PxTaskManager start/stopSimulation() methods itself. - - @see PxSceneQueryUpdateMode::eBUILD_DISABLED_COMMIT_DISABLED - */ - virtual void sceneQueriesUpdate(physx::PxBaseTask* completionTask = NULL, bool controlSimulation = true) = 0; - - /** - \brief This checks to see if the scene queries update has completed. - - This does not cause the data available for reading to be updated with the results of the scene queries update, it is simply a status check. - The bool will allow it to either return immediately or block waiting for the condition to be met so that it can return true - - \param[in] block When set to true will block until the condition is met. - \return True if the results are available. - - @see sceneQueriesUpdate() fetchResults() - */ - virtual bool checkQueries(bool block = false) = 0; - - /** - This method must be called after sceneQueriesUpdate. It will wait for the scene queries update to finish. If the user makes an illegal scene queries update call, - the SDK will issue an error message. - - If a new AABB tree build finished, then during fetchQueries the current tree within the pruning structure is swapped with the new tree. - - \param[in] block When set to true will block until the condition is met, which is tree built task must finish running. - */ - - virtual bool fetchQueries(bool block = false) = 0; - - /** - \brief Performs a raycast against objects in the scene, returns results in a PxRaycastBuffer object - or via a custom user callback implementation inheriting from PxRaycastCallback. - - \note Touching hits are not ordered. - \note Shooting a ray from within an object leads to different results depending on the shape type. Please check the details in user guide article SceneQuery. User can ignore such objects by employing one of the provided filter mechanisms. - - \param[in] origin Origin of the ray. - \param[in] unitDir Normalized direction of the ray. - \param[in] distance Length of the ray. Has to be in the [0, inf) range. - \param[out] hitCall Raycast hit buffer or callback object used to report raycast hits. - \param[in] hitFlags Specifies which properties per hit should be computed and returned via the hit callback. - \param[in] filterData Filtering data passed to the filter shader. See #PxQueryFilterData #PxBatchQueryPreFilterShader, #PxBatchQueryPostFilterShader - \param[in] filterCall Custom filtering logic (optional). Only used if the corresponding #PxQueryFlag flags are set. If NULL, all hits are assumed to be blocking. - \param[in] cache Cached hit shape (optional). Ray is tested against cached shape first. If no hit is found the ray gets queried against the scene. - Note: Filtering is not executed for a cached shape if supplied; instead, if a hit is found, it is assumed to be a blocking hit. - Note: Using past touching hits as cache will produce incorrect behavior since the cached hit will always be treated as blocking. - - \return True if any touching or blocking hits were found or any hit was found in case PxQueryFlag::eANY_HIT was specified. - - @see PxRaycastCallback PxRaycastBuffer PxQueryFilterData PxQueryFilterCallback PxQueryCache PxRaycastHit PxQueryFlag PxQueryFlag::eANY_HIT - */ - virtual bool raycast( - const PxVec3& origin, const PxVec3& unitDir, const PxReal distance, - PxRaycastCallback& hitCall, PxHitFlags hitFlags = PxHitFlags(PxHitFlag::eDEFAULT), - const PxQueryFilterData& filterData = PxQueryFilterData(), PxQueryFilterCallback* filterCall = NULL, - const PxQueryCache* cache = NULL) const = 0; - - /** - \brief Performs a sweep test against objects in the scene, returns results in a PxSweepBuffer object - or via a custom user callback implementation inheriting from PxSweepCallback. - - \note Touching hits are not ordered. - \note If a shape from the scene is already overlapping with the query shape in its starting position, - the hit is returned unless eASSUME_NO_INITIAL_OVERLAP was specified. - - \param[in] geometry Geometry of object to sweep (supported types are: box, sphere, capsule, convex). - \param[in] pose Pose of the sweep object. - \param[in] unitDir Normalized direction of the sweep. - \param[in] distance Sweep distance. Needs to be in [0, inf) range and >0 if eASSUME_NO_INITIAL_OVERLAP was specified. Will be clamped to PX_MAX_SWEEP_DISTANCE. - \param[out] hitCall Sweep hit buffer or callback object used to report sweep hits. - \param[in] hitFlags Specifies which properties per hit should be computed and returned via the hit callback. - \param[in] filterData Filtering data and simple logic. - \param[in] filterCall Custom filtering logic (optional). Only used if the corresponding #PxQueryFlag flags are set. If NULL, all hits are assumed to be blocking. - \param[in] cache Cached hit shape (optional). Sweep is performed against cached shape first. If no hit is found the sweep gets queried against the scene. - Note: Filtering is not executed for a cached shape if supplied; instead, if a hit is found, it is assumed to be a blocking hit. - Note: Using past touching hits as cache will produce incorrect behavior since the cached hit will always be treated as blocking. - \param[in] inflation This parameter creates a skin around the swept geometry which increases its extents for sweeping. The sweep will register a hit as soon as the skin touches a shape, and will return the corresponding distance and normal. - Note: ePRECISE_SWEEP doesn't support inflation. Therefore the sweep will be performed with zero inflation. - - \return True if any touching or blocking hits were found or any hit was found in case PxQueryFlag::eANY_HIT was specified. - - - @see PxSweepCallback PxSweepBuffer PxQueryFilterData PxQueryFilterCallback PxSweepHit PxQueryCache - */ - virtual bool sweep(const PxGeometry& geometry, const PxTransform& pose, const PxVec3& unitDir, const PxReal distance, - PxSweepCallback& hitCall, PxHitFlags hitFlags = PxHitFlags(PxHitFlag::eDEFAULT), - const PxQueryFilterData& filterData = PxQueryFilterData(), PxQueryFilterCallback* filterCall = NULL, - const PxQueryCache* cache = NULL, const PxReal inflation = 0.f) const = 0; - - - /** - \brief Performs an overlap test of a given geometry against objects in the scene, returns results in a PxOverlapBuffer object - or via a custom user callback implementation inheriting from PxOverlapCallback. - - \note Filtering: returning eBLOCK from user filter for overlap queries will cause a warning (see #PxQueryHitType). - - \param[in] geometry Geometry of object to check for overlap (supported types are: box, sphere, capsule, convex). - \param[in] pose Pose of the object. - \param[out] hitCall Overlap hit buffer or callback object used to report overlap hits. - \param[in] filterData Filtering data and simple logic. See #PxQueryFilterData #PxQueryFilterCallback - \param[in] filterCall Custom filtering logic (optional). Only used if the corresponding #PxQueryFlag flags are set. If NULL, all hits are assumed to overlap. - - \return True if any touching or blocking hits were found or any hit was found in case PxQueryFlag::eANY_HIT was specified. - - \note eBLOCK should not be returned from user filters for overlap(). Doing so will result in undefined behavior, and a warning will be issued. - \note If the PxQueryFlag::eNO_BLOCK flag is set, the eBLOCK will instead be automatically converted to an eTOUCH and the warning suppressed. - - @see PxOverlapCallback PxOverlapBuffer PxHitFlags PxQueryFilterData PxQueryFilterCallback - */ - virtual bool overlap(const PxGeometry& geometry, const PxTransform& pose, PxOverlapCallback& hitCall, - const PxQueryFilterData& filterData = PxQueryFilterData(), PxQueryFilterCallback* filterCall = NULL - ) const = 0; - - - /** - \brief Retrieves the scene's internal scene query timestamp, increased each time a change to the - static scene query structure is performed. - - \return scene query static timestamp - */ - virtual PxU32 getSceneQueryStaticTimestamp() const = 0; //@} /************************************************************************************************/ @@ -1444,6 +1403,8 @@ class PxScene /** \brief Adds a new broad-phase region. + The bounds for the new region must be non-empty, otherwise an error occurs and the call is ignored. + Note that by default, objects already existing in the SDK that might touch this region will not be automatically added to the region. In other words the newly created region will be empty, and will only be populated with new objects when they are added to the simulation, or with already existing objects when they are updated. @@ -1453,9 +1414,20 @@ class PxScene when the game can not guarantee that all objects within the new region will be added to the simulation after the region itself. + Objects automatically move from one region to another during their lifetime. The system keeps tracks of what + regions a given object is in. It is legal for an object to be in an arbitrary number of regions. However if an + object leaves all regions, or is created outside of all regions, several things happen: + - collisions get disabled for this object + - if a PxBroadPhaseCallback object is provided, an "out-of-bounds" event is generated via that callback + - if a PxBroadPhaseCallback object is not provided, a warning/error message is sent to the error stream + + If an object goes out-of-bounds and user deletes it during the same frame, neither the out-of-bounds event nor the + error message is generated. + \param[in] region User-provided region data \param[in] populateRegion Automatically populate new region with already existing objects overlapping it \return Handle for newly created region, or 0xffffffff in case of failure. + \see PxBroadPhaseRegion PxBroadPhaseCallback */ virtual PxU32 addBroadPhaseRegion(const PxBroadPhaseRegion& region, bool populateRegion=false) = 0; @@ -1489,7 +1461,6 @@ class PxScene */ virtual PxTaskManager* getTaskManager() const = 0; - /** \brief Lock the scene for reading from the calling thread. @@ -1551,7 +1522,6 @@ class PxScene */ virtual void unlockWrite() = 0; - /** \brief set the cache blocks that can be used during simulate(). @@ -1561,12 +1531,13 @@ class PxScene This call will force allocation of cache blocks if the numBlocks parameter is greater than the currently allocated number of blocks, and less than the max16KContactDataBlocks parameter specified at scene creation time. + \note Do not use this method while the simulation is running. + \param[in] numBlocks The number of blocks to allocate. @see PxSceneDesc.nbContactDataBlocks PxSceneDesc.maxNbContactDataBlocks flushSimulation() getNbContactDataBlocksUsed getMaxNbContactDataBlocksUsed */ virtual void setNbContactDataBlocks(PxU32 numBlocks) = 0; - /** \brief get the number of cache blocks currently used by the scene @@ -1590,18 +1561,18 @@ class PxScene */ virtual PxU32 getMaxNbContactDataBlocksUsed() const = 0; - /** \brief Return the value of PxSceneDesc::contactReportStreamBufferSize that was set when creating the scene with PxPhysics::createScene @see PxSceneDesc::contactReportStreamBufferSize, PxPhysics::createScene */ - virtual PxU32 getContactReportStreamBufferSize() const = 0; + virtual PxU32 getContactReportStreamBufferSize() const = 0; - /** \brief Sets the number of actors required to spawn a separate rigid body solver thread. + \note Do not use this method while the simulation is running. + \param[in] solverBatchSize Number of actors required to spawn a separate rigid body solver thread. @see PxSceneDesc.solverBatchSize getSolverBatchSize() @@ -1620,6 +1591,8 @@ class PxScene /** \brief Sets the number of articulations required to spawn a separate rigid body solver thread. + \note Do not use this method while the simulation is running. + \param[in] solverBatchSize Number of articulations required to spawn a separate rigid body solver thread. @see PxSceneDesc.solverBatchSize getSolverArticulationBatchSize() @@ -1635,7 +1608,6 @@ class PxScene */ virtual PxU32 getSolverArticulationBatchSize() const = 0; - //@} /** @@ -1671,6 +1643,168 @@ class PxScene */ virtual PxPvdSceneClient* getScenePvdClient() = 0; + /** + \brief Copy GPU articulation data from the internal GPU buffer to a user-provided device buffer. + \param[in] data User-provided gpu data buffer which should be sized appropriately for the particular data that is requested. Further details provided in the user guide. + \param[in] index User-provided gpu index buffer. This buffer stores the articulation indices which the user wants to copy. + \param[in] dataType Enum specifying the type of data the user wants to read back from the articulations. + \param[in] nbCopyArticulations Number of articulations that data should be copied from. + \param[in] copyEvent User-provided event for the articulation stream to signal when the data copy to the user buffer has completed. + */ + virtual void copyArticulationData(void* data, void* index, PxArticulationGpuDataType::Enum dataType, const PxU32 nbCopyArticulations, void* copyEvent = NULL) = 0; + + /** + \brief Apply GPU articulation data from a user-provided device buffer to the internal GPU buffer. + \param[in] data User-provided gpu data buffer which should be sized appropriately for the particular data that is requested. Further details provided in the user guide. + \param[in] index User-provided gpu index buffer. This buffer stores the articulation indices which the user wants to write to. + \param[in] dataType Enum specifying the type of data the user wants to write to the articulations. + \param[in] nbUpdatedArticulations Number of articulations that data should be written to. + \param[in] waitEvent User-provided event for the articulation stream to wait for data. + \param[in] signalEvent User-provided event for the articulation stream to signal when the data read from the user buffer has completed. + */ + virtual void applyArticulationData(void* data, void* index, PxArticulationGpuDataType::Enum dataType, const PxU32 nbUpdatedArticulations, void* waitEvent = NULL, void* signalEvent = NULL) = 0; + + /** + \brief Copy GPU softbody data from the internal GPU buffer to a user-provided device buffer. + \param[in] data User-provided gpu buffer containing a pointer to another gpu buffer for every softbody to process + \param[in] dataSizes The size of every buffer in bytes + \param[in] softBodyIndices User provided gpu index buffer. This buffer stores the softbody index which the user want to copy. + \param[in] maxSize The largest size stored in dataSizes. Used internally to decide how many threads to launch for the copy process. + \param[in] flag Flag defining which data the user wants to read back from the softbody system + \param[in] nbCopySoftBodies The number of softbodies to be copied. + \param[in] copyEvent User-provided event for the user to sync data + */ + virtual void copySoftBodyData(void** data, void* dataSizes, void* softBodyIndices, PxSoftBodyDataFlag::Enum flag, const PxU32 nbCopySoftBodies, const PxU32 maxSize, void* copyEvent = NULL) = 0; + + + /** + \brief Apply user-provided data to the internal softbody system. + \param[in] data User-provided gpu buffer containing a pointer to another gpu buffer for every softbody to process + \param[in] dataSizes The size of every buffer in bytes + \param[in] softBodyIndices User provided gpu index buffer. This buffer stores the updated softbody index. + \param[in] flag Flag defining which data the user wants to write to the softbody system + \param[in] maxSize The largest size stored in dataSizes. Used internally to decide how many threads to launch for the copy process. + \param[in] nbUpdatedSoftBodies The number of updated softbodies + \param[in] applyEvent User-provided event for the softbody stream to wait for data + */ + virtual void applySoftBodyData(void** data, void* dataSizes, void* softBodyIndices, PxSoftBodyDataFlag::Enum flag, const PxU32 nbUpdatedSoftBodies, const PxU32 maxSize, void* applyEvent = NULL) = 0; + + /** + \brief Copy contact data from the internal GPU buffer to a user-provided device buffer. + + \note The contact data contains pointers to internal state and is only valid until the next call to simulate(). + + \param[in] data User-provided gpu data buffer, which should be the size of PxGpuContactPair * numContactPairs + \param[in] maxContactPairs The maximum number of pairs that the buffer can contain + \param[in] numContactPairs The actual number of contact pairs that were written + \param[in] copyEvent User-provided event for the user to sync data + */ + virtual void copyContactData(void* data, const PxU32 maxContactPairs, void* numContactPairs, void* copyEvent = NULL) = 0; + + /** + \brief Copy GPU rigid body data from the internal GPU buffer to a user-provided device buffer. + \param[in] data User-provided gpu data buffer which should nbCopyActors * sizeof(PxGpuBodyData). The only data it can copy is PxGpuBodyData. + \param[in] index User provided node PxGpuActorPair buffer. This buffer stores pairs of indices: the PxNodeIndex corresponding to the rigid body and an index corresponding to the location in the user buffer that this value should be placed. + \param[in] nbCopyActors The number of rigid body to be copied. + \param[in] copyEvent User-provided event for the user to sync data. + */ + virtual void copyBodyData(PxGpuBodyData* data, PxGpuActorPair* index, const PxU32 nbCopyActors, void* copyEvent = NULL) = 0; + + /** + \brief Apply user-provided data to rigid body. + \param[in] data User-provided gpu data buffer which should be sized appropriately for the particular data that is requested. Further details provided in the user guide. + \param[in] index User provided PxGpuActorPair buffer. This buffer stores pairs of indices: the PxNodeIndex corresponding to the rigid body and an index corresponding to the location in the user buffer that this value should be placed. + \param[in] flag Flag defining which data the user wants to write to the rigid body + \param[in] nbUpdatedActors The number of updated rigid body + \param[in] waitEvent User-provided event for the rigid body stream to wait for data + \param[in] signalEvent User-provided event for the rigid body stream to signal when the read from the user buffer has completed + */ + virtual void applyActorData(void* data, PxGpuActorPair* index, PxActorCacheFlag::Enum flag, const PxU32 nbUpdatedActors, void* waitEvent = NULL, void* signalEvent = NULL) = 0; + + /** + \brief Compute dense Jacobian matrices for specified articulations on the GPU. + + The size of Jacobians can vary by articulation, since it depends on the number of links, degrees-of-freedom, and whether the base is fixed. + + The size is determined using these formulas: + nCols = (fixedBase ? 0 : 6) + dofCount + nRows = (fixedBase ? 0 : 6) + (linkCount - 1) * 6; + + The user must ensure that adequate space is provided for each Jacobian matrix. + + \param[in] indices User-provided gpu buffer of (index, data) pairs. The entries map a GPU articulation index to a GPU block of memory where the returned Jacobian will be stored. + \param[in] nbIndices The number of (index, data) pairs provided. + \param[in] computeEvent User-provided event for the user to sync data. + */ + virtual void computeDenseJacobians(const PxIndexDataPair* indices, PxU32 nbIndices, void* computeEvent) = 0; + + /** + \brief Compute the joint-space inertia matrices that maps joint accelerations to joint forces: forces = M * accelerations on the GPU. + + The size of matrices can vary by articulation, since it depends on the number of links and degrees-of-freedom. + + The size is determined using this formula: + sizeof(float) * dofCount * dofCount + + The user must ensure that adequate space is provided for each mass matrix. + + \param[in] indices User-provided gpu buffer of (index, data) pairs. The entries map a GPU articulation index to a GPU block of memory where the returned matrix will be stored. + \param[in] nbIndices The number of (index, data) pairs provided. + \param[in] computeEvent User-provided event for the user to sync data. + */ + virtual void computeGeneralizedMassMatrices(const PxIndexDataPair* indices, PxU32 nbIndices, void* computeEvent) = 0; + + /** + \brief Computes the joint DOF forces required to counteract gravitational forces for the given articulation pose. + + The size of the result can vary by articulation, since it depends on the number of links and degrees-of-freedom. + + The size is determined using this formula: + sizeof(float) * dofCount + + The user must ensure that adequate space is provided for each articulation. + + \param[in] indices User-provided gpu buffer of (index, data) pairs. The entries map a GPU articulation index to a GPU block of memory where the returned matrix will be stored. + \param[in] nbIndices The number of (index, data) pairs provided. + \param[in] computeEvent User-provided event for the user to sync data. + */ + virtual void computeGeneralizedGravityForces(const PxIndexDataPair* indices, PxU32 nbIndices, void* computeEvent) = 0; + + /** + \brief Computes the joint DOF forces required to counteract coriolis and centrifugal forces for the given articulation pose. + + The size of the result can vary by articulation, since it depends on the number of links and degrees-of-freedom. + + The size is determined using this formula: + sizeof(float) * dofCount + + The user must ensure that adequate space is provided for each articulation. + + \param[in] indices User-provided gpu buffer of (index, data) pairs. The entries map a GPU articulation index to a GPU block of memory where the returned matrix will be stored. + \param[in] nbIndices The number of (index, data) pairs provided. + \param[in] computeEvent User-provided event for the user to sync data. + */ + virtual void computeCoriolisAndCentrifugalForces(const PxIndexDataPair* indices, PxU32 nbIndices, void* computeEvent) = 0; + + virtual PxgDynamicsMemoryConfig getGpuDynamicsConfig() const = 0; + + /** + \brief Apply user-provided data to particle buffers. + + This function should be used if the particle buffer flags are already on the device. Otherwise, use PxParticleBuffer::raiseFlags() + from the CPU. + + This assumes the data has been changed directly in the PxParticleBuffer. + + \param[in] indices User-provided index buffer that indexes into the BufferIndexPair and flags list. + \param[in] bufferIndexPair User-provided index pair buffer specifying the unique id and GPU particle system for each PxParticleBuffer. See PxGpuParticleBufferIndexPair. + \param[in] flags Flags to mark what data needs to be updated. See PxParticleBufferFlags. + \param[in] nbUpdatedBuffers The number of particle buffers to update. + \param[in] waitEvent User-provided event for the particle stream to wait for data. + \param[in] signalEvent User-provided event for the particle stream to signal when the data read from the user buffer has completed. + */ + virtual void applyParticleBufferData(const PxU32* indices, const PxGpuParticleBufferIndexPair* bufferIndexPair, const PxParticleBufferFlags* flags, PxU32 nbUpdatedBuffers, void* waitEvent = NULL, void* signalEvent = NULL) = 0; + void* userData; //!< user can assign this to whatever, usually to create a 1:1 relationship with a user object. }; diff --git a/Source/ThirdParty/PhysX/PxSceneDesc.h b/Source/ThirdParty/PhysX/PxSceneDesc.h index f4dc1ed48..de8303c85 100644 --- a/Source/ThirdParty/PhysX/PxSceneDesc.h +++ b/Source/ThirdParty/PhysX/PxSceneDesc.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,20 +22,21 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_NX_SCENEDESC -#define PX_PHYSICS_NX_SCENEDESC +#ifndef PX_SCENE_DESC_H +#define PX_SCENE_DESC_H /** \addtogroup physics @{ */ +#include "PxSceneQueryDesc.h" #include "PxPhysXConfig.h" #include "foundation/PxFlags.h" #include "foundation/PxBounds3.h" +#include "foundation/PxBitUtils.h" #include "PxFiltering.h" #include "PxBroadPhase.h" #include "common/PxTolerancesScale.h" @@ -47,68 +47,9 @@ namespace physx { #endif + class PxBroadPhaseCallback; class PxCudaContextManager; -/** -\brief Pruning structure used to accelerate scene queries. - -eNONE uses a simple data structure that consumes less memory than the alternatives, -but generally has slower query performance. - -eDYNAMIC_AABB_TREE usually provides the fastest queries. However there is a -constant per-frame management cost associated with this structure. How much work should -be done per frame can be tuned via the #PxSceneDesc::dynamicTreeRebuildRateHint -parameter. - -eSTATIC_AABB_TREE is typically used for static objects. It is the same as the -dynamic AABB tree, without the per-frame overhead. This can be a good choice for static -objects, if no static objects are added, moved or removed after the scene has been -created. If there is no such guarantee (e.g. when streaming parts of the world in and out), -then the dynamic version is a better choice even for static objects. - -*/ -struct PxPruningStructureType -{ - enum Enum - { - eNONE, //!< Using a simple data structure - eDYNAMIC_AABB_TREE, //!< Using a dynamic AABB tree - eSTATIC_AABB_TREE, //!< Using a static AABB tree - - eLAST - }; -}; - -/** -\brief Scene query update mode - -When PxScene::fetchResults is called it does scene query related work, with this enum it is possible to -set what work is done during the fetchResults. - -FetchResults will sync changed bounds during simulation and update the scene query bounds in pruners, this work is mandatory. - -eCOMMIT_ENABLED_BUILD_ENABLED does allow to execute the new AABB tree build step during fetchResults, additionally the pruner commit is -called where any changes are applied. During commit PhysX refits the dynamic scene query tree and if a new tree was built and -the build finished the tree is swapped with current AABB tree. - -eCOMMIT_DISABLED_BUILD_ENABLED does allow to execute the new AABB tree build step during fetchResults. Pruner commit is not called, -this means that refit will then occur during the first scene query following fetchResults, or may be forced by the method PxScene::flushSceneQueryUpdates(). - -eCOMMIT_DISABLED_BUILD_DISABLED no further scene query work is executed. The scene queries update needs to be called manually, see PxScene::sceneQueriesUpdate. -It is recommended to call PxScene::sceneQueriesUpdate right after fetchResults as the pruning structures are not updated. - -*/ -struct PxSceneQueryUpdateMode -{ - enum Enum - { - eBUILD_ENABLED_COMMIT_ENABLED, //!< Both scene query build and commit are executed. - eBUILD_ENABLED_COMMIT_DISABLED, //!< Scene query build only is executed. - eBUILD_DISABLED_COMMIT_DISABLED //!< No work is done, no update of scene queries - }; -}; - - /** \brief Enum for selecting the friction algorithm used for simulation. @@ -135,11 +76,10 @@ struct PxFrictionType }; }; - /** \brief Enum for selecting the type of solver used for the simulation. -#PxSolverType::ePGS selects the default iterative sequential impulse solver. This is the same kind of solver used in PhysX 3.4 and earlier releases. +#PxSolverType::ePGS selects the iterative sequential impulse solver. This is the same kind of solver used in PhysX 3.4 and earlier releases. #PxSolverType::eTGS selects a non linear iterative solver. This kind of solver can lead to improved convergence and handle large mass ratios, long chains and jointed systems better. It is slightly more expensive than the default solver and can introduce more energy to correct joint and contact errors. */ @@ -147,18 +87,16 @@ struct PxSolverType { enum Enum { - ePGS, //!< Default Projected Gauss-Seidel iterative solver - eTGS //!< Temporal Gauss-Seidel solver + ePGS, //!< Projected Gauss-Seidel iterative solver + eTGS //!< Default Temporal Gauss-Seidel solver }; }; - /** \brief flags for configuring properties of the scene @see PxScene */ - struct PxSceneFlag { enum Enum @@ -212,15 +150,6 @@ struct PxSceneFlag */ eDISABLE_CCD_RESWEEP = (1<<2), - /** - \brief Enable adaptive forces to accelerate convergence of the solver. - - \note This flag is not mutable, and must be set in PxSceneDesc at scene creation. - - Default: false - */ - eADAPTIVE_FORCE = (1<<3), - /** \brief Enable GJK-based distance collision detection system. @@ -349,11 +278,21 @@ struct PxSceneFlag */ eENABLE_FRICTION_EVERY_ITERATION = (1 << 15), - eMUTABLE_FLAGS = eENABLE_ACTIVE_ACTORS|eEXCLUDE_KINEMATICS_FROM_ACTIVE_ACTORS + /* + \brief Disables GPU readback of articulation data when running on GPU. + Useful if your application only needs to communicate to the GPU via GPU buffers. Can be significantly faster + */ + eSUPPRESS_READBACK = (1<<16), + + /* + \brief Forces GPU readback of articulation data when user raise eSUPPRESS_READBACK. + */ + eFORCE_READBACK = (1 << 17), + + eMUTABLE_FLAGS = eENABLE_ACTIVE_ACTORS|eEXCLUDE_KINEMATICS_FROM_ACTIVE_ACTORS|eSUPPRESS_READBACK }; }; - /** \brief collection of set bits defined in PxSceneFlag. @@ -362,7 +301,6 @@ struct PxSceneFlag typedef PxFlags PxSceneFlags; PX_FLAGS_OPERATORS(PxSceneFlag::Enum,PxU32) - class PxSimulationEventCallback; class PxContactModifyCallback; class PxCCDContactModifyCallback; @@ -437,28 +375,44 @@ PX_INLINE bool PxSceneLimits::isValid() const struct PxgDynamicsMemoryConfig { - PxU32 constraintBufferCapacity; //!< Capacity of constraint buffer allocated in GPU global memory - PxU32 contactBufferCapacity; //!< Capacity of contact buffer allocated in GPU global memory - PxU32 tempBufferCapacity; //!< Capacity of temp buffer allocated in pinned host memory. - PxU32 contactStreamSize; //!< Size of contact stream buffer allocated in pinned host memory. This is double-buffered so total allocation size = 2* contactStreamCapacity * sizeof(PxContact). - PxU32 patchStreamSize; //!< Size of the contact patch stream buffer allocated in pinned host memory. This is double-buffered so total allocation size = 2 * patchStreamCapacity * sizeof(PxContactPatch). - PxU32 forceStreamCapacity; //!< Capacity of force buffer allocated in pinned host memory. - PxU32 heapCapacity; //!< Initial capacity of the GPU and pinned host memory heaps. Additional memory will be allocated if more memory is required. - PxU32 foundLostPairsCapacity; //!< Capacity of found and lost buffers allocated in GPU global memory. This is used for the found/lost pair reports in the BP. + PxU32 tempBufferCapacity; //!< Capacity of temp buffer allocated in pinned host memory. + PxU32 maxRigidContactCount; //!< Size of contact stream buffer allocated in pinned host memory. This is double-buffered so total allocation size = 2* contactStreamCapacity * sizeof(PxContact). + PxU32 maxRigidPatchCount; //!< Size of the contact patch stream buffer allocated in pinned host memory. This is double-buffered so total allocation size = 2 * patchStreamCapacity * sizeof(PxContactPatch). + PxU32 heapCapacity; //!< Initial capacity of the GPU and pinned host memory heaps. Additional memory will be allocated if more memory is required. + PxU32 foundLostPairsCapacity; //!< Capacity of found and lost buffers allocated in GPU global memory. This is used for the found/lost pair reports in the BP. + PxU32 foundLostAggregatePairsCapacity; //!Range: force vector
Default: Zero - @see PxScene.setGravity() + @see PxScene.setGravity() PxScene.getGravity() When setting gravity, you should probably also set bounce threshold. */ - PxVec3 gravity; + PxVec3 gravity; /** \brief Possible notification callback. @@ -518,18 +472,18 @@ public: Default: NULL - @see PxSimulationFilterShader PxScene::setFilterShaderData() + @see PxSimulationFilterShader PxScene.setFilterShaderData() PxScene.getFilterShaderData() */ - const void* filterShaderData; + const void* filterShaderData; /** \brief Size (in bytes) of the shared global filter data #filterShaderData. Default: 0 - @see PxSimulationFilterShader filterShaderData + @see PxSimulationFilterShader filterShaderData PxScene.getFilterShaderDataSize() */ - PxU32 filterShaderDataSize; + PxU32 filterShaderDataSize; /** \brief The custom filter shader to use for collision filtering. @@ -538,7 +492,7 @@ public: use the default shader #PxDefaultSimulationFilterShader which can be found in the PhysX extensions library. - @see PxSimulationFilterShader + @see PxSimulationFilterShader PxScene.getFilterShader() */ PxSimulationFilterShader filterShader; @@ -548,7 +502,7 @@ public: Default: NULL - @see PxSimulationFilterCallback + @see PxSimulationFilterCallback PxScene.getFilterCallback() */ PxSimulationFilterCallback* filterCallback; @@ -557,53 +511,52 @@ public: Default: PxPairFilteringMode::eDEFAULT - @see PxPairFilteringMode + @see PxPairFilteringMode PxScene.getKinematicKinematicFilteringMode() */ - PxPairFilteringMode::Enum kineKineFilteringMode; + PxPairFilteringMode::Enum kineKineFilteringMode; /** \brief Filtering mode for static-kinematic pairs in the broadphase. Default: PxPairFilteringMode::eDEFAULT - @see PxPairFilteringMode + @see PxPairFilteringMode PxScene.getStaticKinematicFilteringMode() */ - PxPairFilteringMode::Enum staticKineFilteringMode; + PxPairFilteringMode::Enum staticKineFilteringMode; /** \brief Selects the broad-phase algorithm to use. - Default: PxBroadPhaseType::eABP + Default: PxBroadPhaseType::ePABP - @see PxBroadPhaseType + @see PxBroadPhaseType PxScene.getBroadPhaseType() */ - PxBroadPhaseType::Enum broadPhaseType; + PxBroadPhaseType::Enum broadPhaseType; /** \brief Broad-phase callback Default: NULL - @see PxBroadPhaseCallback + @see PxBroadPhaseCallback PxScene.getBroadPhaseCallback() PxScene.setBroadPhaseCallback() */ - PxBroadPhaseCallback* broadPhaseCallback; + PxBroadPhaseCallback* broadPhaseCallback; /** \brief Expected scene limits. - @see PxSceneLimits + @see PxSceneLimits PxScene.getLimits() */ - PxSceneLimits limits; + PxSceneLimits limits; /** \brief Selects the friction algorithm to use for simulation. \note frictionType cannot be modified after the first call to any of PxScene::simulate, PxScene::solve and PxScene::collide - @see PxFrictionType Default: PxFrictionType::ePATCH - @see PxScene::setFrictionType, PxScene::getFrictionType + @see PxFrictionType PxScene.setFrictionType(), PxScene.getFrictionType() */ PxFrictionType::Enum frictionType; @@ -612,18 +565,18 @@ public: Default: PxSolverType::ePGS - @see PxSolverType + @see PxSolverType PxScene.getSolverType() */ - PxSolverType::Enum solverType; + PxSolverType::Enum solverType; /** \brief A contact with a relative velocity below this will not bounce. A typical value for simulation. stability is about 0.2 * gravity. - Range: [0, PX_MAX_F32)
+ Range: (0, PX_MAX_F32)
Default: 0.2 * PxTolerancesScale::speed - @see PxMaterial + @see PxMaterial PxScene.setBounceThresholdVelocity() PxScene.getBounceThresholdVelocity() */ PxReal bounceThresholdVelocity; @@ -639,96 +592,56 @@ public: Range: [0, PX_MAX_F32)
Default: 0.04 * PxTolerancesScale::length + + @see PxScene.setFrictionOffsetThreshold() PxScene.getFrictionOffsetThreshold() */ PxReal frictionOffsetThreshold; /** - \brief A threshold for speculative CCD. Used to control whether bias, restitution or a combination of the two are used to resolve the contacts. + \brief Friction correlation distance used to decide whether contacts are close enough to be merged into a single friction anchor point or not. - \note This only has any effect on contacting pairs where one of the bodies has PxRigidBodyFlag::eENABLE_SPECULATIVE_CCD raised. + \note If the correlation distance is larger than the distance between contact points generated between a pair of shapes, some of the contacts may not experience frictional forces. + + \note This parameter can be used to tune the correlation distance used in the solver. Contact points can be merged into a single friction anchor if the distance between the contacts is smaller than correlation distance. Range: [0, PX_MAX_F32)
- Default: 0.04 * PxTolerancesScale::length + Default: 0.025f * PxTolerancesScale::length + + @see PxScene.setFrictionCorrelationDistance() PxScene.getFrictionCorrelationDistance() */ - - PxReal ccdMaxSeparation; - - /** - \brief A slop value used to zero contact offsets from the body's COM on an axis if the offset along that axis is smaller than this threshold. Can be used to compensate - for small numerical errors in contact generation. - - Range: [0, PX_MAX_F32)
- Default: 0.0 - */ - - PxReal solverOffsetSlop; + PxReal frictionCorrelationDistance; /** \brief Flags used to select scene options. - @see PxSceneFlag PxSceneFlags + Default: PxSceneFlag::eENABLE_PCM + + @see PxSceneFlag PxSceneFlags PxScene.getFlags() PxScene.setFlag() */ - PxSceneFlags flags; + PxSceneFlags flags; /** \brief The CPU task dispatcher for the scene. - See PxCpuDispatcher, PxScene::getCpuDispatcher + @see PxCpuDispatcher, PxScene::getCpuDispatcher */ - PxCpuDispatcher* cpuDispatcher; + PxCpuDispatcher* cpuDispatcher; /** \brief The CUDA context manager for the scene. Platform specific: Applies to PC GPU only. - See PxCudaContextManager, PxScene::getCudaContextManager + @see PxCudaContextManager, PxScene::getCudaContextManager */ PxCudaContextManager* cudaContextManager; - /** - \brief Defines the structure used to store static objects. - - \note Only PxPruningStructureType::eSTATIC_AABB_TREE and PxPruningStructureType::eDYNAMIC_AABB_TREE are allowed here. - */ - PxPruningStructureType::Enum staticStructure; - - /** - \brief Defines the structure used to store dynamic objects. - */ - PxPruningStructureType::Enum dynamicStructure; - - /** - \brief Hint for how much work should be done per simulation frame to rebuild the pruning structure. - - This parameter gives a hint on the distribution of the workload for rebuilding the dynamic AABB tree - pruning structure #PxPruningStructureType::eDYNAMIC_AABB_TREE. It specifies the desired number of simulation frames - the rebuild process should take. Higher values will decrease the workload per frame but the pruning - structure will get more and more outdated the longer the rebuild takes (which can make - scene queries less efficient). - - \note Only used for #PxPruningStructureType::eDYNAMIC_AABB_TREE pruning structure. - - \note This parameter gives only a hint. The rebuild process might still take more or less time depending on the - number of objects involved. - - Range: [4, PX_MAX_U32)
- Default: 100 - */ - PxU32 dynamicTreeRebuildRateHint; - - /** - \brief Defines the scene query update mode. - Default: PxSceneQueryUpdateMode::eBUILD_ENABLED_COMMIT_ENABLED - */ - PxSceneQueryUpdateMode::Enum sceneQueryUpdateMode; - /** \brief Will be copied to PxScene::userData. Default: NULL */ - void* userData; + void* userData; /** \brief Defines the number of actors required to spawn a separate rigid body solver island task chain. @@ -745,7 +658,7 @@ public: @see PxScene.setSolverBatchSize() PxScene.getSolverBatchSize() */ - PxU32 solverBatchSize; + PxU32 solverBatchSize; /** \brief Defines the number of articulations required to spawn a separate rigid body solver island task chain. @@ -758,11 +671,11 @@ public: Note that a rigid body solver task chain is spawned as soon as either a sufficient number of rigid bodies or articulations are batched together. - Default: 128 + Default: 16 @see PxScene.setSolverArticulationBatchSize() PxScene.getSolverArticulationBatchSize() */ - PxU32 solverArticulationBatchSize; + PxU32 solverArticulationBatchSize; /** \brief Setting to define the number of 16K blocks that will be initially reserved to store contact, friction, and contact cache data. @@ -777,7 +690,7 @@ public: @see PxPhysics::createScene PxScene::setNbContactDataBlocks */ - PxU32 nbContactDataBlocks; + PxU32 nbContactDataBlocks; /** \brief Setting to define the maximum number of 16K blocks that can be allocated to store contact, friction, and contact cache data. @@ -795,9 +708,9 @@ public: Range: [0, PX_MAX_U32]
- @see nbContactDataBlocks PxScene::setNbContactDataBlocks + @see nbContactDataBlocks PxScene.setNbContactDataBlocks() */ - PxU32 maxNbContactDataBlocks; + PxU32 maxNbContactDataBlocks; /** \brief The maximum bias coefficient used in the constraint solver @@ -814,8 +727,9 @@ public: Range [0, PX_MAX_F32]
+ @see PxScene.setMaxBiasCoefficient() PxScene.getMaxBiasCoefficient() */ - PxReal maxBiasCoefficient; + PxReal maxBiasCoefficient; /** \brief Size of the contact report stream (in bytes). @@ -829,8 +743,9 @@ public: Range: (0, PX_MAX_U32]
+ @see PxScene.getContactReportStreamBufferSize() */ - PxU32 contactReportStreamBufferSize; + PxU32 contactReportStreamBufferSize; /** \brief Maximum number of CCD passes @@ -842,8 +757,10 @@ public: Default: 1 Range: [1, PX_MAX_U32]
+ + @see PxScene.setCCDMaxPasses() PxScene.getCCDMaxPasses() */ - PxU32 ccdMaxPasses; + PxU32 ccdMaxPasses; /** \brief CCD threshold @@ -857,9 +774,22 @@ public: Default: PX_MAX_F32 Range: [Eps, PX_MAX_F32]
- */ - PxReal ccdThreshold; + @see PxScene.setCCDThreshold() PxScene.getCCDThreshold() + */ + PxReal ccdThreshold; + + /** + \brief A threshold for speculative CCD. Used to control whether bias, restitution or a combination of the two are used to resolve the contacts. + + \note This only has any effect on contacting pairs where one of the bodies has PxRigidBodyFlag::eENABLE_SPECULATIVE_CCD raised. + + Range: [0, PX_MAX_F32)
+ Default: 0.04 * PxTolerancesScale::length + + @see PxScene.setCCDMaxSeparation() PxScene.getCCDMaxSeparation() + */ + PxReal ccdMaxSeparation; /** \brief The wake counter reset value @@ -869,9 +799,9 @@ public: Range: (0, PX_MAX_F32)
Default: 0.4 (which corresponds to 20 frames for a time step of 0.02) - @see PxRigidDynamic::wakeUp() PxArticulationBase::wakeUp() + @see PxRigidDynamic::wakeUp() PxArticulationReducedCoordinate::wakeUp() PxScene.getWakeCounterResetValue() */ - PxReal wakeCounterResetValue; + PxReal wakeCounterResetValue; /** \brief The bounds used to sanity check user-set positions of actors and articulation links @@ -882,7 +812,7 @@ public: Range: any valid PxBounds3
Default: (-PX_MAX_BOUNDS_EXTENTS, PX_MAX_BOUNDS_EXTENTS) on each axis */ - PxBounds3 sanityBounds; + PxBounds3 sanityBounds; /** \brief The pre-allocations performed in the GPU dynamics pipeline. @@ -895,24 +825,52 @@ public: A value greater than 32 is currently not supported. Range: (1, 32)
*/ - PxU32 gpuMaxNumPartitions; + PxU32 gpuMaxNumPartitions; + + /** + \brief Limitation for the number of static rigid body partitions in the GPU dynamics pipeline. + Range: (1, 255)
+ Default: 16 + */ + PxU32 gpuMaxNumStaticPartitions; /** \brief Defines which compute version the GPU dynamics should target. DO NOT MODIFY */ - PxU32 gpuComputeVersion; + PxU32 gpuComputeVersion; + + /** + \brief Defines the size of a contact pool slab. + Contact pairs and associated data are allocated using a pool allocator. Increasing the slab size can trade + off some performance spikes when a large number of new contacts are found for an increase in overall memory + usage. + + Range:(1, PX_MAX_U32)
+ Default: 256 + */ + PxU32 contactPairSlabSize; + + /** + \brief The scene query sub-system for the scene. + + If left to NULL, PxScene will use its usual internal sub-system. If non-NULL, all SQ-related calls + will be re-routed to the user-provided implementation. An external SQ implementation is available + in the Extensions library (see PxCreateExternalSceneQuerySystem). This can also be fully re-implemented by users if needed. + + @see PxSceneQuerySystem + */ + PxSceneQuerySystem* sceneQuerySystem; private: /** \cond */ // For internal use only - PxTolerancesScale tolerancesScale; + PxTolerancesScale tolerancesScale; /** \endcond */ - public: /** \brief constructor sets to default. @@ -951,55 +909,53 @@ public: }; PX_INLINE PxSceneDesc::PxSceneDesc(const PxTolerancesScale& scale): - gravity (PxVec3(0.0f)), - simulationEventCallback (NULL), - contactModifyCallback (NULL), - ccdContactModifyCallback (NULL), + gravity (PxVec3(0.0f)), + simulationEventCallback (NULL), + contactModifyCallback (NULL), + ccdContactModifyCallback (NULL), - filterShaderData (NULL), - filterShaderDataSize (0), - filterShader (NULL), - filterCallback (NULL), + filterShaderData (NULL), + filterShaderDataSize (0), + filterShader (NULL), + filterCallback (NULL), - kineKineFilteringMode (PxPairFilteringMode::eDEFAULT), - staticKineFilteringMode (PxPairFilteringMode::eDEFAULT), + kineKineFilteringMode (PxPairFilteringMode::eDEFAULT), + staticKineFilteringMode (PxPairFilteringMode::eDEFAULT), - broadPhaseType (PxBroadPhaseType::eABP), - broadPhaseCallback (NULL), + broadPhaseType (PxBroadPhaseType::ePABP), + broadPhaseCallback (NULL), - frictionType (PxFrictionType::ePATCH), - solverType (PxSolverType::ePGS), - bounceThresholdVelocity (0.2f * scale.speed), - frictionOffsetThreshold (0.04f * scale.length), - ccdMaxSeparation (0.04f * scale.length), - solverOffsetSlop (0.0f), + frictionType (PxFrictionType::ePATCH), + solverType (PxSolverType::ePGS), + bounceThresholdVelocity (0.2f * scale.speed), + frictionOffsetThreshold (0.04f * scale.length), + frictionCorrelationDistance (0.025f * scale.length), - flags (PxSceneFlag::eENABLE_PCM), + flags (PxSceneFlag::eENABLE_PCM), - cpuDispatcher (NULL), - cudaContextManager (NULL), + cpuDispatcher (NULL), + cudaContextManager (NULL), - staticStructure (PxPruningStructureType::eDYNAMIC_AABB_TREE), - dynamicStructure (PxPruningStructureType::eDYNAMIC_AABB_TREE), - dynamicTreeRebuildRateHint (100), - sceneQueryUpdateMode (PxSceneQueryUpdateMode::eBUILD_ENABLED_COMMIT_ENABLED), + userData (NULL), - userData (NULL), + solverBatchSize (128), + solverArticulationBatchSize (16), - solverBatchSize (128), - solverArticulationBatchSize (16), - - nbContactDataBlocks (0), - maxNbContactDataBlocks (1<<16), - maxBiasCoefficient (PX_MAX_F32), - contactReportStreamBufferSize (8192), - ccdMaxPasses (1), - ccdThreshold (PX_MAX_F32), - wakeCounterResetValue (20.0f*0.02f), - sanityBounds (PxBounds3(PxVec3(-PX_MAX_BOUNDS_EXTENTS), PxVec3(PX_MAX_BOUNDS_EXTENTS))), - gpuMaxNumPartitions (8), - gpuComputeVersion (0), - tolerancesScale (scale) + nbContactDataBlocks (0), + maxNbContactDataBlocks (1<<16), + maxBiasCoefficient (PX_MAX_F32), + contactReportStreamBufferSize (8192), + ccdMaxPasses (1), + ccdThreshold (PX_MAX_F32), + ccdMaxSeparation (0.04f * scale.length), + wakeCounterResetValue (20.0f*0.02f), + sanityBounds (PxBounds3(PxVec3(-PX_MAX_BOUNDS_EXTENTS), PxVec3(PX_MAX_BOUNDS_EXTENTS))), + gpuMaxNumPartitions (8), + gpuMaxNumStaticPartitions (16), + gpuComputeVersion (0), + contactPairSlabSize (256), + sceneQuerySystem (NULL), + tolerancesScale (scale) { } @@ -1010,6 +966,9 @@ PX_INLINE void PxSceneDesc::setToDefault(const PxTolerancesScale& scale) PX_INLINE bool PxSceneDesc::isValid() const { + if(!PxSceneQueryDesc::isValid()) + return false; + if(!filterShader) return false; @@ -1020,22 +979,21 @@ PX_INLINE bool PxSceneDesc::isValid() const if(!limits.isValid()) return false; - if(staticStructure!=PxPruningStructureType::eSTATIC_AABB_TREE && staticStructure!=PxPruningStructureType::eDYNAMIC_AABB_TREE) - return false; - - if(dynamicTreeRebuildRateHint < 4) - return false; - - if(bounceThresholdVelocity < 0.0f) + if(bounceThresholdVelocity <= 0.0f) return false; if(frictionOffsetThreshold < 0.0f) return false; - if(ccdMaxSeparation < 0.0f) - return false; - if (solverOffsetSlop < 0.f) + if(frictionCorrelationDistance <= 0) return false; - if(ccdThreshold <= 0.f) + if(maxBiasCoefficient < 0.0f) + return false; + + if(!ccdMaxPasses) + return false; + if(ccdThreshold <= 0.0f) + return false; + if(ccdMaxSeparation < 0.0f) return false; if(!cpuDispatcher) @@ -1050,25 +1008,32 @@ PX_INLINE bool PxSceneDesc::isValid() const if(wakeCounterResetValue <= 0.0f) return false; - //Adaptive force and stabilization are incompatible. You can only have one or the other - if((flags & (PxSceneFlag::eADAPTIVE_FORCE | PxSceneFlag::eENABLE_STABILIZATION)) == (PxSceneFlag::eADAPTIVE_FORCE | PxSceneFlag::eENABLE_STABILIZATION)) - return false; - if(!sanityBounds.isValid()) return false; #if PX_SUPPORT_GPU_PHYSX - //gpuMaxNumPartitions must be power of 2 - if((gpuMaxNumPartitions&(gpuMaxNumPartitions - 1)) != 0) + if(!PxIsPowerOfTwo(gpuMaxNumPartitions)) return false; - if (gpuMaxNumPartitions > 32) + if(gpuMaxNumPartitions > 32) return false; + if (gpuMaxNumPartitions == 0) + return false; + if(!gpuDynamicsConfig.isValid()) + return false; + + if (flags & PxSceneFlag::eSUPPRESS_READBACK) + { + if(!(flags & PxSceneFlag::eENABLE_GPU_DYNAMICS && broadPhaseType == PxBroadPhaseType::eGPU)) + return false; + } #endif + if(contactPairSlabSize == 0) + return false; + return true; } - #if !PX_DOXYGEN } // namespace physx #endif diff --git a/Source/ThirdParty/PhysX/PxSceneLock.h b/Source/ThirdParty/PhysX/PxSceneLock.h index fcd8236e0..903841c0d 100644 --- a/Source/ThirdParty/PhysX/PxSceneLock.h +++ b/Source/ThirdParty/PhysX/PxSceneLock.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_NX_SCENELOCK -#define PX_PHYSICS_NX_SCENELOCK +#ifndef PX_SCENE_LOCK_H +#define PX_SCENE_LOCK_H /** \addtogroup physics @{ */ @@ -50,7 +48,7 @@ for the duration of the enclosing scope: PxSceneReadLock lock(sceneRef); -\see PxScene::lockRead(), PxScene::unlockRead(), PxSceneFlag::eREQUIRE_RW_LOCK +@see PxScene::lockRead(), PxScene::unlockRead(), PxSceneFlag::eREQUIRE_RW_LOCK */ class PxSceneReadLock { @@ -89,7 +87,7 @@ for the duration of the enclosing scope: PxSceneWriteLock lock(sceneRef); -\see PxScene::lockWrite(), PxScene::unlockWrite(), PxSceneFlag::eREQUIRE_RW_LOCK +@see PxScene::lockWrite(), PxScene::unlockWrite(), PxSceneFlag::eREQUIRE_RW_LOCK */ class PxSceneWriteLock { diff --git a/Source/ThirdParty/PhysX/PxSceneQueryDesc.h b/Source/ThirdParty/PhysX/PxSceneQueryDesc.h new file mode 100644 index 000000000..50eae851b --- /dev/null +++ b/Source/ThirdParty/PhysX/PxSceneQueryDesc.h @@ -0,0 +1,328 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_SCENE_QUERY_DESC_H +#define PX_SCENE_QUERY_DESC_H +/** \addtogroup physics +@{ +*/ + +#include "PxPhysXConfig.h" +#include "geometry/PxBVHBuildStrategy.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + class PxSceneQuerySystem; + +/** +\brief Pruning structure used to accelerate scene queries. + +eNONE uses a simple data structure that consumes less memory than the alternatives, +but generally has slower query performance. + +eDYNAMIC_AABB_TREE usually provides the fastest queries. However there is a +constant per-frame management cost associated with this structure. How much work should +be done per frame can be tuned via the #PxSceneQueryDesc::dynamicTreeRebuildRateHint +parameter. + +eSTATIC_AABB_TREE is typically used for static objects. It is the same as the +dynamic AABB tree, without the per-frame overhead. This can be a good choice for static +objects, if no static objects are added, moved or removed after the scene has been +created. If there is no such guarantee (e.g. when streaming parts of the world in and out), +then the dynamic version is a better choice even for static objects. +*/ +struct PxPruningStructureType +{ + enum Enum + { + eNONE, //!< Using a simple data structure + eDYNAMIC_AABB_TREE, //!< Using a dynamic AABB tree + eSTATIC_AABB_TREE, //!< Using a static AABB tree + + eLAST + }; +}; + +/** +\brief Secondary pruning structure used for newly added objects in dynamic trees. + +Dynamic trees (PxPruningStructureType::eDYNAMIC_AABB_TREE) are slowly rebuilt +over several frames. A secondary pruning structure holds and manages objects +added to the scene while this rebuild is in progress. + +eNONE ignores newly added objects. This means that for a number of frames (roughly +defined by PxSceneQueryDesc::dynamicTreeRebuildRateHint) newly added objects will +be ignored by scene queries. This can be acceptable when streaming large worlds, e.g. +when the objects added at the boundaries of the game world don't immediately need to be +visible from scene queries (it would be equivalent to streaming that data in a few frames +later). The advantage of this approach is that there is no CPU cost associated with +inserting the new objects in the scene query data structures, and no extra runtime cost +when performing queries. + +eBUCKET uses a structure similar to PxPruningStructureType::eNONE. Insertion is fast but +query cost can be high. + +eINCREMENTAL uses an incremental AABB-tree, with no direct PxPruningStructureType equivalent. +Query time is fast but insertion cost can be high. + +eBVH uses a PxBVH structure. This usually offers the best overall performance. +*/ +struct PxDynamicTreeSecondaryPruner +{ + enum Enum + { + eNONE, //!< no secondary pruner, new objects aren't visible to SQ for a few frames + eBUCKET , //!< bucket-based secondary pruner, faster updates, slower query time + eINCREMENTAL, //!< incremental-BVH secondary pruner, faster query time, slower updates + eBVH, //!< PxBVH-based secondary pruner, good overall performance + + eLAST + }; +}; + +/** +\brief Scene query update mode + +This enum controls what work is done when the scene query system is updated. The updates traditionally happen when PxScene::fetchResults +is called. This function then calls PxSceneQuerySystem::finalizeUpdates, where the update mode is used. + +fetchResults/finalizeUpdates will sync changed bounds during simulation and update the scene query bounds in pruners, this work is mandatory. + +eBUILD_ENABLED_COMMIT_ENABLED does allow to execute the new AABB tree build step during fetchResults/finalizeUpdates, additionally +the pruner commit is called where any changes are applied. During commit PhysX refits the dynamic scene query tree and if a new tree +was built and the build finished the tree is swapped with current AABB tree. + +eBUILD_ENABLED_COMMIT_DISABLED does allow to execute the new AABB tree build step during fetchResults/finalizeUpdates. Pruner commit +is not called, this means that refit will then occur during the first scene query following fetchResults/finalizeUpdates, or may be forced +by the method PxScene::flushQueryUpdates() / PxSceneQuerySystemBase::flushUpdates(). + +eBUILD_DISABLED_COMMIT_DISABLED no further scene query work is executed. The scene queries update needs to be called manually, see +PxScene::sceneQueriesUpdate (see that function's doc for the equivalent PxSceneQuerySystem sequence). It is recommended to call +PxScene::sceneQueriesUpdate right after fetchResults/finalizeUpdates as the pruning structures are not updated. +*/ +struct PxSceneQueryUpdateMode +{ + enum Enum + { + eBUILD_ENABLED_COMMIT_ENABLED, //!< Both scene query build and commit are executed. + eBUILD_ENABLED_COMMIT_DISABLED, //!< Scene query build only is executed. + eBUILD_DISABLED_COMMIT_DISABLED //!< No work is done, no update of scene queries + }; +}; + +/** +\brief Descriptor class for scene query system. See #PxSceneQuerySystem. +*/ +class PxSceneQueryDesc +{ +public: + + /** + \brief Defines the structure used to store static objects (PxRigidStatic actors). + + There are usually a lot more static actors than dynamic actors in a scene, so they are stored + in a separate structure. The idea is that when dynamic actors move each frame, the static structure + remains untouched and does not need updating. + + Default: PxPruningStructureType::eDYNAMIC_AABB_TREE + + \note Only PxPruningStructureType::eSTATIC_AABB_TREE and PxPruningStructureType::eDYNAMIC_AABB_TREE are allowed here. + + @see PxPruningStructureType PxSceneSQSystem.getStaticStructure() + */ + PxPruningStructureType::Enum staticStructure; + + /** + \brief Defines the structure used to store dynamic objects (non-PxRigidStatic actors). + + Default: PxPruningStructureType::eDYNAMIC_AABB_TREE + + @see PxPruningStructureType PxSceneSQSystem.getDynamicStructure() + */ + PxPruningStructureType::Enum dynamicStructure; + + /** + \brief Hint for how much work should be done per simulation frame to rebuild the pruning structures. + + This parameter gives a hint on the distribution of the workload for rebuilding the dynamic AABB tree + pruning structure #PxPruningStructureType::eDYNAMIC_AABB_TREE. It specifies the desired number of simulation frames + the rebuild process should take. Higher values will decrease the workload per frame but the pruning + structure will get more and more outdated the longer the rebuild takes (which can make + scene queries less efficient). + + \note Only used for #PxPruningStructureType::eDYNAMIC_AABB_TREE pruning structures. + + \note Both staticStructure & dynamicStructure can use a PxPruningStructureType::eDYNAMIC_AABB_TREE, in which case + this parameter is used for both. + + \note This parameter gives only a hint. The rebuild process might still take more or less time depending on the + number of objects involved. + + Range: [4, PX_MAX_U32)
+ Default: 100 + + @see PxSceneQuerySystemBase.setDynamicTreeRebuildRateHint() PxSceneQuerySystemBase.getDynamicTreeRebuildRateHint() + */ + PxU32 dynamicTreeRebuildRateHint; + + /** + \brief Secondary pruner for dynamic tree. + + This is used for PxPruningStructureType::eDYNAMIC_AABB_TREE structures, to control how objects added to the system + at runtime are managed. + + \note Both staticStructure & dynamicStructure can use a PxPruningStructureType::eDYNAMIC_AABB_TREE, in which case + this parameter is used for both. + + Default: PxDynamicTreeSecondaryPruner::eINCREMENTAL + + @see PxDynamicTreeSecondaryPruner + */ + PxDynamicTreeSecondaryPruner::Enum dynamicTreeSecondaryPruner; + + /** + \brief Build strategy for PxSceneQueryDesc::staticStructure. + + This parameter is used to refine / control the build strategy of PxSceneQueryDesc::staticStructure. This is only + used with PxPruningStructureType::eDYNAMIC_AABB_TREE and PxPruningStructureType::eSTATIC_AABB_TREE. + + Default: PxBVHBuildStrategy::eFAST + + @see PxBVHBuildStrategy PxSceneQueryDesc::staticStructure + */ + PxBVHBuildStrategy::Enum staticBVHBuildStrategy; + + /** + \brief Build strategy for PxSceneQueryDesc::dynamicStructure. + + This parameter is used to refine / control the build strategy of PxSceneQueryDesc::dynamicStructure. This is only + used with PxPruningStructureType::eDYNAMIC_AABB_TREE and PxPruningStructureType::eSTATIC_AABB_TREE. + + Default: PxBVHBuildStrategy::eFAST + + @see PxBVHBuildStrategy PxSceneQueryDesc::dynamicStructure + */ + PxBVHBuildStrategy::Enum dynamicBVHBuildStrategy; + + /** + \brief Number of objects per node for PxSceneQueryDesc::staticStructure. + + This parameter is used to refine / control the number of objects per node for PxSceneQueryDesc::staticStructure. + This is only used with PxPruningStructureType::eDYNAMIC_AABB_TREE and PxPruningStructureType::eSTATIC_AABB_TREE. + + This parameter has an impact on how quickly the structure gets built, and on the per-frame cost of maintaining + the structure. Increasing this value gives smaller AABB-trees that use less memory, are faster to build and + update, but it can lead to slower queries. + + Default: 4 + + @see PxSceneQueryDesc::staticStructure + */ + PxU32 staticNbObjectsPerNode; + + /** + \brief Number of objects per node for PxSceneQueryDesc::dynamicStructure. + + This parameter is used to refine / control the number of objects per node for PxSceneQueryDesc::dynamicStructure. + This is only used with PxPruningStructureType::eDYNAMIC_AABB_TREE and PxPruningStructureType::eSTATIC_AABB_TREE. + + This parameter has an impact on how quickly the structure gets built, and on the per-frame cost of maintaining + the structure. Increasing this value gives smaller AABB-trees that use less memory, are faster to build and + update, but it can lead to slower queries. + + Default: 4 + + @see PxSceneQueryDesc::dynamicStructure + */ + PxU32 dynamicNbObjectsPerNode; + + /** + \brief Defines the scene query update mode. + + Default: PxSceneQueryUpdateMode::eBUILD_ENABLED_COMMIT_ENABLED + + @see PxSceneQuerySystemBase.setUpdateMode() PxSceneQuerySystemBase.getUpdateMode() + */ + PxSceneQueryUpdateMode::Enum sceneQueryUpdateMode; + +public: + /** + \brief constructor sets to default. + */ + PX_INLINE PxSceneQueryDesc(); + + /** + \brief (re)sets the structure to the default. + */ + PX_INLINE void setToDefault(); + + /** + \brief Returns true if the descriptor is valid. + \return true if the current settings are valid. + */ + PX_INLINE bool isValid() const; +}; + +PX_INLINE PxSceneQueryDesc::PxSceneQueryDesc(): + staticStructure (PxPruningStructureType::eDYNAMIC_AABB_TREE), + dynamicStructure (PxPruningStructureType::eDYNAMIC_AABB_TREE), + dynamicTreeRebuildRateHint (100), + dynamicTreeSecondaryPruner (PxDynamicTreeSecondaryPruner::eINCREMENTAL), + staticBVHBuildStrategy (PxBVHBuildStrategy::eFAST), + dynamicBVHBuildStrategy (PxBVHBuildStrategy::eFAST), + staticNbObjectsPerNode (4), + dynamicNbObjectsPerNode (4), + sceneQueryUpdateMode (PxSceneQueryUpdateMode::eBUILD_ENABLED_COMMIT_ENABLED) +{ +} + +PX_INLINE void PxSceneQueryDesc::setToDefault() +{ + *this = PxSceneQueryDesc(); +} + +PX_INLINE bool PxSceneQueryDesc::isValid() const +{ + if(staticStructure!=PxPruningStructureType::eSTATIC_AABB_TREE && staticStructure!=PxPruningStructureType::eDYNAMIC_AABB_TREE) + return false; + + if(dynamicTreeRebuildRateHint < 4) + return false; + + return true; +} + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/PxSceneQuerySystem.h b/Source/ThirdParty/PhysX/PxSceneQuerySystem.h new file mode 100644 index 000000000..759e6d894 --- /dev/null +++ b/Source/ThirdParty/PhysX/PxSceneQuerySystem.h @@ -0,0 +1,656 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_SCENE_QUERY_SYSTEM_H +#define PX_SCENE_QUERY_SYSTEM_H +/** \addtogroup physics +@{ */ + +#include "foundation/PxSimpleTypes.h" +#include "foundation/PxBitMap.h" +#include "foundation/PxTransform.h" +#include "PxSceneQueryDesc.h" +#include "PxQueryReport.h" +#include "PxQueryFiltering.h" +#include "geometry/PxGeometryQueryFlags.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + class PxBaseTask; + class PxRenderOutput; + class PxGeometry; + class PxRigidActor; + class PxShape; + class PxBVH; + class PxPruningStructure; + + /** + \brief Built-in enum for default PxScene pruners + + This is passed as a pruner index to various functions in the following APIs. + + @see PxSceneQuerySystemBase::forceRebuildDynamicTree PxSceneQuerySystem::preallocate + @see PxSceneQuerySystem::visualize PxSceneQuerySystem::sync PxSceneQuerySystem::prepareSceneQueryBuildStep + */ + enum PxScenePrunerIndex + { + PX_SCENE_PRUNER_STATIC = 0, + PX_SCENE_PRUNER_DYNAMIC = 1, + PX_SCENE_COMPOUND_PRUNER = 0xffffffff + }; + + /** + \brief Base class for the scene-query system. + + Methods defined here are common to both the traditional PxScene API and the PxSceneQuerySystem API. + + @see PxScene PxSceneQuerySystem + */ + class PxSceneQuerySystemBase + { + protected: + PxSceneQuerySystemBase() {} + virtual ~PxSceneQuerySystemBase() {} + + public: + + /** @name Scene Query + */ + //@{ + + /** + \brief Sets the rebuild rate of the dynamic tree pruning structures. + + \param[in] dynamicTreeRebuildRateHint Rebuild rate of the dynamic tree pruning structures. + + @see PxSceneQueryDesc.dynamicTreeRebuildRateHint getDynamicTreeRebuildRateHint() forceRebuildDynamicTree() + */ + virtual void setDynamicTreeRebuildRateHint(PxU32 dynamicTreeRebuildRateHint) = 0; + + /** + \brief Retrieves the rebuild rate of the dynamic tree pruning structures. + + \return The rebuild rate of the dynamic tree pruning structures. + + @see PxSceneQueryDesc.dynamicTreeRebuildRateHint setDynamicTreeRebuildRateHint() forceRebuildDynamicTree() + */ + virtual PxU32 getDynamicTreeRebuildRateHint() const = 0; + + /** + \brief Forces dynamic trees to be immediately rebuilt. + + \param[in] prunerIndex Index of pruner containing the dynamic tree to rebuild + + \note PxScene will call this function with the PX_SCENE_PRUNER_STATIC or PX_SCENE_PRUNER_DYNAMIC value. + + @see PxSceneQueryDesc.dynamicTreeRebuildRateHint setDynamicTreeRebuildRateHint() getDynamicTreeRebuildRateHint() + */ + virtual void forceRebuildDynamicTree(PxU32 prunerIndex) = 0; + + /** + \brief Sets scene query update mode + + \param[in] updateMode Scene query update mode. + + @see PxSceneQueryUpdateMode::Enum + */ + virtual void setUpdateMode(PxSceneQueryUpdateMode::Enum updateMode) = 0; + + /** + \brief Gets scene query update mode + + \return Current scene query update mode. + + @see PxSceneQueryUpdateMode::Enum + */ + virtual PxSceneQueryUpdateMode::Enum getUpdateMode() const = 0; + + /** + \brief Retrieves the system's internal scene query timestamp, increased each time a change to the + static scene query structure is performed. + + \return scene query static timestamp + */ + virtual PxU32 getStaticTimestamp() const = 0; + + /** + \brief Flushes any changes to the scene query representation. + + This method updates the state of the scene query representation to match changes in the scene state. + + By default, these changes are buffered until the next query is submitted. Calling this function will not change + the results from scene queries, but can be used to ensure that a query will not perform update work in the course of + its execution. + + A thread performing updates will hold a write lock on the query structure, and thus stall other querying threads. In multithread + scenarios it can be useful to explicitly schedule the period where this lock may be held for a significant period, so that + subsequent queries issued from multiple threads will not block. + */ + virtual void flushUpdates() = 0; + + /** + \brief Performs a raycast against objects in the scene, returns results in a PxRaycastBuffer object + or via a custom user callback implementation inheriting from PxRaycastCallback. + + \note Touching hits are not ordered. + \note Shooting a ray from within an object leads to different results depending on the shape type. Please check the details in user guide article SceneQuery. User can ignore such objects by employing one of the provided filter mechanisms. + + \param[in] origin Origin of the ray. + \param[in] unitDir Normalized direction of the ray. + \param[in] distance Length of the ray. Has to be in the [0, inf) range. + \param[out] hitCall Raycast hit buffer or callback object used to report raycast hits. + \param[in] hitFlags Specifies which properties per hit should be computed and returned via the hit callback. + \param[in] filterData Filtering data passed to the filter shader. + \param[in] filterCall Custom filtering logic (optional). Only used if the corresponding #PxQueryFlag flags are set. If NULL, all hits are assumed to be blocking. + \param[in] cache Cached hit shape (optional). Ray is tested against cached shape first. If no hit is found the ray gets queried against the scene. + Note: Filtering is not executed for a cached shape if supplied; instead, if a hit is found, it is assumed to be a blocking hit. + Note: Using past touching hits as cache will produce incorrect behavior since the cached hit will always be treated as blocking. + \param[in] queryFlags Optional flags controlling the query. + + \return True if any touching or blocking hits were found or any hit was found in case PxQueryFlag::eANY_HIT was specified. + + @see PxRaycastCallback PxRaycastBuffer PxQueryFilterData PxQueryFilterCallback PxQueryCache PxRaycastHit PxQueryFlag PxQueryFlag::eANY_HIT PxGeometryQueryFlag + */ + virtual bool raycast(const PxVec3& origin, const PxVec3& unitDir, const PxReal distance, + PxRaycastCallback& hitCall, PxHitFlags hitFlags = PxHitFlag::eDEFAULT, + const PxQueryFilterData& filterData = PxQueryFilterData(), PxQueryFilterCallback* filterCall = NULL, + const PxQueryCache* cache = NULL, PxGeometryQueryFlags queryFlags = PxGeometryQueryFlag::eDEFAULT) const = 0; + + /** + \brief Performs a sweep test against objects in the scene, returns results in a PxSweepBuffer object + or via a custom user callback implementation inheriting from PxSweepCallback. + + \note Touching hits are not ordered. + \note If a shape from the scene is already overlapping with the query shape in its starting position, + the hit is returned unless eASSUME_NO_INITIAL_OVERLAP was specified. + + \param[in] geometry Geometry of object to sweep (supported types are: box, sphere, capsule, convex). + \param[in] pose Pose of the sweep object. + \param[in] unitDir Normalized direction of the sweep. + \param[in] distance Sweep distance. Needs to be in [0, inf) range and >0 if eASSUME_NO_INITIAL_OVERLAP was specified. Will be clamped to PX_MAX_SWEEP_DISTANCE. + \param[out] hitCall Sweep hit buffer or callback object used to report sweep hits. + \param[in] hitFlags Specifies which properties per hit should be computed and returned via the hit callback. + \param[in] filterData Filtering data and simple logic. + \param[in] filterCall Custom filtering logic (optional). Only used if the corresponding #PxQueryFlag flags are set. If NULL, all hits are assumed to be blocking. + \param[in] cache Cached hit shape (optional). Sweep is performed against cached shape first. If no hit is found the sweep gets queried against the scene. + Note: Filtering is not executed for a cached shape if supplied; instead, if a hit is found, it is assumed to be a blocking hit. + Note: Using past touching hits as cache will produce incorrect behavior since the cached hit will always be treated as blocking. + \param[in] inflation This parameter creates a skin around the swept geometry which increases its extents for sweeping. The sweep will register a hit as soon as the skin touches a shape, and will return the corresponding distance and normal. + Note: ePRECISE_SWEEP doesn't support inflation. Therefore the sweep will be performed with zero inflation. + \param[in] queryFlags Optional flags controlling the query. + + \return True if any touching or blocking hits were found or any hit was found in case PxQueryFlag::eANY_HIT was specified. + + @see PxSweepCallback PxSweepBuffer PxQueryFilterData PxQueryFilterCallback PxSweepHit PxQueryCache PxGeometryQueryFlag + */ + virtual bool sweep( const PxGeometry& geometry, const PxTransform& pose, const PxVec3& unitDir, const PxReal distance, + PxSweepCallback& hitCall, PxHitFlags hitFlags = PxHitFlag::eDEFAULT, + const PxQueryFilterData& filterData = PxQueryFilterData(), PxQueryFilterCallback* filterCall = NULL, + const PxQueryCache* cache = NULL, const PxReal inflation = 0.0f, PxGeometryQueryFlags queryFlags = PxGeometryQueryFlag::eDEFAULT) const = 0; + + /** + \brief Performs an overlap test of a given geometry against objects in the scene, returns results in a PxOverlapBuffer object + or via a custom user callback implementation inheriting from PxOverlapCallback. + + \note Filtering: returning eBLOCK from user filter for overlap queries will cause a warning (see #PxQueryHitType). + + \param[in] geometry Geometry of object to check for overlap (supported types are: box, sphere, capsule, convex). + \param[in] pose Pose of the object. + \param[out] hitCall Overlap hit buffer or callback object used to report overlap hits. + \param[in] filterData Filtering data and simple logic. See #PxQueryFilterData #PxQueryFilterCallback + \param[in] filterCall Custom filtering logic (optional). Only used if the corresponding #PxQueryFlag flags are set. If NULL, all hits are assumed to overlap. + \param[in] cache Cached hit shape (optional). Overlap is performed against cached shape first. If no hit is found the overlap gets queried against the scene. + \param[in] queryFlags Optional flags controlling the query. + Note: Filtering is not executed for a cached shape if supplied; instead, if a hit is found, it is assumed to be a blocking hit. + Note: Using past touching hits as cache will produce incorrect behavior since the cached hit will always be treated as blocking. + + \return True if any touching or blocking hits were found or any hit was found in case PxQueryFlag::eANY_HIT was specified. + + \note eBLOCK should not be returned from user filters for overlap(). Doing so will result in undefined behavior, and a warning will be issued. + \note If the PxQueryFlag::eNO_BLOCK flag is set, the eBLOCK will instead be automatically converted to an eTOUCH and the warning suppressed. + + @see PxOverlapCallback PxOverlapBuffer PxHitFlags PxQueryFilterData PxQueryFilterCallback PxGeometryQueryFlag + */ + virtual bool overlap(const PxGeometry& geometry, const PxTransform& pose, PxOverlapCallback& hitCall, + const PxQueryFilterData& filterData = PxQueryFilterData(), PxQueryFilterCallback* filterCall = NULL, + const PxQueryCache* cache = NULL, PxGeometryQueryFlags queryFlags = PxGeometryQueryFlag::eDEFAULT) const = 0; + //@} + }; + + /** + \brief Traditional SQ system for PxScene. + + Methods defined here are only available through the traditional PxScene API. + Thus PxSceneSQSystem effectively captures the scene-query related part of the PxScene API. + + @see PxScene PxSceneQuerySystemBase + */ + class PxSceneSQSystem : public PxSceneQuerySystemBase + { + protected: + PxSceneSQSystem() {} + virtual ~PxSceneSQSystem() {} + + public: + + /** @name Scene Query + */ + //@{ + + /** + \brief Sets scene query update mode + + \param[in] updateMode Scene query update mode. + + @see PxSceneQueryUpdateMode::Enum + */ + PX_FORCE_INLINE void setSceneQueryUpdateMode(PxSceneQueryUpdateMode::Enum updateMode) { setUpdateMode(updateMode); } + + /** + \brief Gets scene query update mode + + \return Current scene query update mode. + + @see PxSceneQueryUpdateMode::Enum + */ + PX_FORCE_INLINE PxSceneQueryUpdateMode::Enum getSceneQueryUpdateMode() const { return getUpdateMode(); } + + /** + \brief Retrieves the scene's internal scene query timestamp, increased each time a change to the + static scene query structure is performed. + + \return scene query static timestamp + */ + PX_FORCE_INLINE PxU32 getSceneQueryStaticTimestamp() const { return getStaticTimestamp(); } + + /** + \brief Flushes any changes to the scene query representation. + + @see flushUpdates + */ + PX_FORCE_INLINE void flushQueryUpdates() { flushUpdates(); } + + /** + \brief Forces dynamic trees to be immediately rebuilt. + + \param[in] rebuildStaticStructure True to rebuild the dynamic tree containing static objects + \param[in] rebuildDynamicStructure True to rebuild the dynamic tree containing dynamic objects + + @see PxSceneQueryDesc.dynamicTreeRebuildRateHint setDynamicTreeRebuildRateHint() getDynamicTreeRebuildRateHint() + */ + PX_FORCE_INLINE void forceDynamicTreeRebuild(bool rebuildStaticStructure, bool rebuildDynamicStructure) + { + if(rebuildStaticStructure) + forceRebuildDynamicTree(PX_SCENE_PRUNER_STATIC); + if(rebuildDynamicStructure) + forceRebuildDynamicTree(PX_SCENE_PRUNER_DYNAMIC); + } + + /** + \brief Return the value of PxSceneQueryDesc::staticStructure that was set when creating the scene with PxPhysics::createScene + + @see PxSceneQueryDesc::staticStructure, PxPhysics::createScene + */ + virtual PxPruningStructureType::Enum getStaticStructure() const = 0; + + /** + \brief Return the value of PxSceneQueryDesc::dynamicStructure that was set when creating the scene with PxPhysics::createScene + + @see PxSceneQueryDesc::dynamicStructure, PxPhysics::createScene + */ + virtual PxPruningStructureType::Enum getDynamicStructure() const = 0; + + /** + \brief Executes scene queries update tasks. + + This function will refit dirty shapes within the pruner and will execute a task to build a new AABB tree, which is + build on a different thread. The new AABB tree is built based on the dynamic tree rebuild hint rate. Once + the new tree is ready it will be commited in next fetchQueries call, which must be called after. + + This function is equivalent to the following PxSceneQuerySystem calls: + Synchronous calls: + - PxSceneQuerySystemBase::flushUpdates() + - handle0 = PxSceneQuerySystem::prepareSceneQueryBuildStep(PX_SCENE_PRUNER_STATIC) + - handle1 = PxSceneQuerySystem::prepareSceneQueryBuildStep(PX_SCENE_PRUNER_DYNAMIC) + Asynchronous calls: + - PxSceneQuerySystem::sceneQueryBuildStep(handle0); + - PxSceneQuerySystem::sceneQueryBuildStep(handle1); + + This function is part of the PxSceneSQSystem interface because it uses the PxScene task system under the hood. But + it calls PxSceneQuerySystem functions, which are independent from this system and could be called in a similar + fashion by a separate, possibly user-defined task manager. + + \note If PxSceneQueryUpdateMode::eBUILD_DISABLED_COMMIT_DISABLED is used, it is required to update the scene queries + using this function. + + \param[in] completionTask if non-NULL, this task will have its refcount incremented in sceneQueryUpdate(), then + decremented when the scene is ready to have fetchQueries called. So the task will not run until the + application also calls removeReference(). + \param[in] controlSimulation if true, the scene controls its PxTaskManager simulation state. Leave + true unless the application is calling the PxTaskManager start/stopSimulation() methods itself. + + @see PxSceneQueryUpdateMode::eBUILD_DISABLED_COMMIT_DISABLED + */ + virtual void sceneQueriesUpdate(PxBaseTask* completionTask = NULL, bool controlSimulation = true) = 0; + + /** + \brief This checks to see if the scene queries update has completed. + + This does not cause the data available for reading to be updated with the results of the scene queries update, it is simply a status check. + The bool will allow it to either return immediately or block waiting for the condition to be met so that it can return true + + \param[in] block When set to true will block until the condition is met. + \return True if the results are available. + + @see sceneQueriesUpdate() fetchResults() + */ + virtual bool checkQueries(bool block = false) = 0; + + /** + This method must be called after sceneQueriesUpdate. It will wait for the scene queries update to finish. If the user makes an illegal scene queries update call, + the SDK will issue an error message. + + If a new AABB tree build finished, then during fetchQueries the current tree within the pruning structure is swapped with the new tree. + + \param[in] block When set to true will block until the condition is met, which is tree built task must finish running. + */ + virtual bool fetchQueries(bool block = false) = 0; + //@} + }; + + typedef PxU32 PxSQCompoundHandle; + typedef PxU32 PxSQPrunerHandle; + typedef void* PxSQBuildStepHandle; + + /** + \brief Scene-queries external sub-system for PxScene-based objects. + + The default PxScene has hardcoded support for 2 regular pruners + 1 compound pruner, but these interfaces + should work with multiple pruners. + + Regular shapes are traditional PhysX shapes that belong to an actor. That actor can be a compound, i.e. it has + more than one shape. *All of these go to the regular pruners*. This is important because it might be misleading: + by default all shapes go to one of the two regular pruners, even shapes that belong to compound actors. + + For compound actors, adding all the actor's shapes individually to the SQ system can be costly, since all the + corresponding bounds will always move together and remain close together - that can put a lot of stress on the + code that updates the SQ spatial structures. In these cases it can be more efficient to add the compound's bounds + (i.e. the actor's bounds) to the system, as the first level of a bounds hierarchy. The scene queries would then + be performed against the actor's bounds first, and only visit the shapes' bounds second. This is only useful + for actors that have more than one shape, i.e. compound actors. Such actors added to the SQ system are thus + called "SQ compounds". These objects are managed by the "compound pruner", which is only used when an explicit + SQ compound is added to the SQ system via the addSQCompound call. So in the end one has to distinguish between: + + - a "compound shape", which is added to regular pruners as its own individual entity. + - an "SQ compound shape", which is added to the compound pruner as a subpart of an SQ compound actor. + + A compound shape has an invalid compound ID, since it does not belong to an SQ compound. + An SQ compound shape has a valid compound ID, that identifies its SQ compound owner. + + @see PxScene PxSceneQuerySystemBase + */ + class PxSceneQuerySystem : public PxSceneQuerySystemBase + { + protected: + PxSceneQuerySystem() {} + virtual ~PxSceneQuerySystem() {} + public: + + /** + \brief Decrements the reference count of the object and releases it if the new reference count is zero. + */ + virtual void release() = 0; + + /** + \brief Acquires a counted reference to this object. + + This method increases the reference count of the object by 1. Decrement the reference count by calling release() + */ + virtual void acquireReference() = 0; + + /** + \brief Preallocates internal arrays to minimize the amount of reallocations. + + The system does not prevent more allocations than given numbers. It is legal to not call this function at all, + or to add more shapes to the system than the preallocated amounts. + + \param[in] prunerIndex Index of pruner to preallocate (PX_SCENE_PRUNER_STATIC, PX_SCENE_PRUNER_DYNAMIC or PX_SCENE_COMPOUND_PRUNER when called from PxScene). + \param[in] nbShapes Expected number of (regular) shapes + */ + virtual void preallocate(PxU32 prunerIndex, PxU32 nbShapes) = 0; + + /** + \brief Frees internal memory that may not be in-use anymore. + + This is an entry point for reclaiming transient memory allocated at some point by the SQ system, + but which wasn't been immediately freed for performance reason. Calling this function might free + some memory, but it might also produce a new set of allocations in the next frame. + */ + virtual void flushMemory() = 0; + + /** + \brief Adds a shape to the SQ system. + + The same function is used to add either a regular shape, or a SQ compound shape. + + \param[in] actor The shape's actor owner + \param[in] shape The shape itself + \param[in] bounds Shape bounds, in world-space for regular shapes, in local-space for SQ compound shapes. + \param[in] transform Shape transform, in world-space for regular shapes, in local-space for SQ compound shapes. + \param[in] compoundHandle Handle of SQ compound owner, or NULL for regular shapes. + \param[in] hasPruningStructure True if the shape is part of a pruning structure. The structure will be merged later, adding the objects will not invalidate the pruner. + + @see merge() PxPruningStructure + */ + virtual void addSQShape( const PxRigidActor& actor, const PxShape& shape, const PxBounds3& bounds, + const PxTransform& transform, const PxSQCompoundHandle* compoundHandle=NULL, bool hasPruningStructure=false) = 0; + + /** + \brief Removes a shape from the SQ system. + + The same function is used to remove either a regular shape, or a SQ compound shape. + + \param[in] actor The shape's actor owner + \param[in] shape The shape itself + */ + virtual void removeSQShape(const PxRigidActor& actor, const PxShape& shape) = 0; + + /** + \brief Updates a shape in the SQ system. + + The same function is used to update either a regular shape, or a SQ compound shape. + + The transforms are eager-evaluated, but the bounds are lazy-evaluated. This means that + the updated transform has to be passed to the update function, while the bounds are automatically + recomputed by the system whenever needed. + + \param[in] actor The shape's actor owner + \param[in] shape The shape itself + \param[in] transform New shape transform, in world-space for regular shapes, in local-space for SQ compound shapes. + */ + virtual void updateSQShape(const PxRigidActor& actor, const PxShape& shape, const PxTransform& transform) = 0; + + /** + \brief Adds a compound to the SQ system. + + \param[in] actor The compound actor + \param[in] shapes The compound actor's shapes + \param[in] bvh BVH structure containing the compound's shapes in local space + \param[in] transforms Shape transforms, in local-space + + \return SQ compound handle + + @see PxBVH PxCooking::createBVH + */ + virtual PxSQCompoundHandle addSQCompound(const PxRigidActor& actor, const PxShape** shapes, const PxBVH& bvh, const PxTransform* transforms) = 0; + + /** + \brief Removes a compound from the SQ system. + + \param[in] compoundHandle SQ compound handle (returned by addSQCompound) + */ + virtual void removeSQCompound(PxSQCompoundHandle compoundHandle) = 0; + + /** + \brief Updates a compound in the SQ system. + + The compound structures are immediately updated when the call occurs. + + \param[in] compoundHandle SQ compound handle (returned by addSQCompound) + \param[in] compoundTransform New actor/compound transform, in world-space + */ + virtual void updateSQCompound(PxSQCompoundHandle compoundHandle, const PxTransform& compoundTransform) = 0; + + /** + \brief Shift the data structures' origin by the specified vector. + + Please refer to the notes of the similar function in PxScene. + + \param[in] shift Translation vector to shift the origin by. + */ + virtual void shiftOrigin(const PxVec3& shift) = 0; + + /** + \brief Visualizes the system's internal data-structures, for debugging purposes. + + \param[in] prunerIndex Index of pruner to visualize (PX_SCENE_PRUNER_STATIC, PX_SCENE_PRUNER_DYNAMIC or PX_SCENE_COMPOUND_PRUNER when called from PxScene). + + \param[out] out Filled with render output data + + @see PxRenderOutput + */ + virtual void visualize(PxU32 prunerIndex, PxRenderOutput& out) const = 0; + + /** + \brief Merges a pruning structure with the SQ system's internal pruners. + + \param[in] pruningStructure The pruning structure to merge + + @see PxPruningStructure + */ + virtual void merge(const PxPruningStructure& pruningStructure) = 0; + + /** + \brief Shape to SQ-pruner-handle mapping function. + + This function finds and returns the SQ pruner handle associated with a given (actor/shape) couple + that was previously added to the system. This is needed for the sync function. + + \param[in] actor The shape's actor owner + \param[in] shape The shape itself + \param[out] prunerIndex Index of pruner the shape belongs to + + \return Associated SQ pruner handle. + */ + virtual PxSQPrunerHandle getHandle(const PxRigidActor& actor, const PxShape& shape, PxU32& prunerIndex) const = 0; + + /** + \brief Synchronizes the scene-query system with another system that references the same objects. + + This function is used when the scene-query objects also exist in another system that can also update them. For example the scene-query objects + (used for raycast, overlap or sweep queries) might be driven by equivalent objects in an external rigid-body simulation engine. In this case + the rigid-body simulation engine computes the new poses and transforms, and passes them to the scene-query system using this function. It is + more efficient than calling updateSQShape on each object individually, since updateSQShape would end up recomputing the bounds already available + in the rigid-body engine. + + \param[in] prunerIndex Index of pruner being synched (PX_SCENE_PRUNER_DYNAMIC for regular PhysX usage) + \param[in] handles Handles of updated objects + \param[in] indices Bounds & transforms indices of updated objects, i.e. object handles[i] has bounds[indices[i]] and transforms[indices[i]] + \param[in] bounds Array of bounds for all objects (not only updated bounds) + \param[in] transforms Array of transforms for all objects (not only updated transforms) + \param[in] count Number of updated objects + \param[in] ignoredIndices Optional bitmap of ignored indices, i.e. update is skipped if ignoredIndices[indices[i]] is set. + + @see PxBounds3 PxTransform32 PxBitMap + */ + virtual void sync(PxU32 prunerIndex, const PxSQPrunerHandle* handles, const PxU32* indices, const PxBounds3* bounds, const PxTransform32* transforms, PxU32 count, const PxBitMap& ignoredIndices) = 0; + + /** + \brief Finalizes updates made to the SQ system. + + This function should be called after updates have been made to the SQ system, to fully reflect the changes + inside the internal pruners. In particular it should be called: + - after calls to updateSQShape + - after calls to sync + + This function: + - recomputes bounds of manually updated shapes (i.e. either regular or SQ compound shapes modified by updateSQShape) + - updates dynamic pruners (refit operations) + - incrementally rebuilds AABB-trees + + The amount of work performed in this function depends on PxSceneQueryUpdateMode. + + @see PxSceneQueryUpdateMode updateSQShape() sync() + */ + virtual void finalizeUpdates() = 0; + + /** + \brief Prepares asynchronous build step. + + This is directly called (synchronously) by PxSceneSQSystem::sceneQueriesUpdate(). See the comments there. + + This function is called to let the system execute any necessary synchronous operation before the + asynchronous sceneQueryBuildStep() function is called. + + If there is any work to do for the specific pruner, the function returns a pruner-specific handle that + will be passed to the corresponding, asynchronous sceneQueryBuildStep function. + + \return A pruner-specific handle that will be sent to sceneQueryBuildStep if there is any work to do, i.e. to execute the corresponding sceneQueryBuildStep() call. + + \param[in] prunerIndex Index of pruner being built. (PX_SCENE_PRUNER_STATIC or PX_SCENE_PRUNER_DYNAMIC when called by PxScene). + + \return Null if there is no work to do, otherwise a pruner-specific handle. + + @see PxSceneSQSystem::sceneQueriesUpdate sceneQueryBuildStep + */ + virtual PxSQBuildStepHandle prepareSceneQueryBuildStep(PxU32 prunerIndex) = 0; + + /** + \brief Executes asynchronous build step. + + This is directly called (asynchronously) by PxSceneSQSystem::sceneQueriesUpdate(). See the comments there. + + This function incrementally builds the internal trees/pruners. It is called asynchronously, i.e. this can be + called from different threads for building multiple trees at the same time. + + \param[in] handle Pruner-specific handle previously returned by the prepareSceneQueryBuildStep function. + + @see PxSceneSQSystem::sceneQueriesUpdate prepareSceneQueryBuildStep + */ + virtual void sceneQueryBuildStep(PxSQBuildStepHandle handle) = 0; + }; + +#if !PX_DOXYGEN +} // namespace physx +#endif + + /** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/PxShape.h b/Source/ThirdParty/PhysX/PxShape.h index 812f603c1..48ecf297e 100644 --- a/Source/ThirdParty/PhysX/PxShape.h +++ b/Source/ThirdParty/PhysX/PxShape.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PX_PHYSICS_NX_SHAPE -#define PX_PHYSICS_NX_SHAPE +#ifndef PX_SHAPE_H +#define PX_SHAPE_H /** \addtogroup physics @{ */ @@ -49,11 +48,16 @@ class PxCapsuleGeometry; class PxPlaneGeometry; class PxConvexMeshGeometry; class PxTriangleMeshGeometry; +class PxTetrahedronMeshGeometry; class PxHeightFieldGeometry; +class PxParticleSystemGeometry; +class PxHairSystemGeometry; class PxRigidActor; struct PxFilterData; -struct PxRaycastHit; -struct PxSweepHit; +class PxBaseMaterial; +class PxMaterial; +class PxFEMSoftBodyMaterial; +class PxFEMClothMaterial; /** \brief Flags which affect the behavior of PxShapes. @@ -122,7 +126,6 @@ struct PxShapeFlag typedef PxFlags PxShapeFlags; PX_FLAGS_OPERATORS(PxShapeFlag::Enum,PxU8) - /** \brief Abstract class for collision shapes. @@ -139,10 +142,9 @@ the createShape() method of the PxPhysics class. @see PxPhysics.createShape() PxRigidActor.createShape() PxBoxGeometry PxSphereGeometry PxCapsuleGeometry PxPlaneGeometry PxConvexMeshGeometry PxTriangleMeshGeometry PxHeightFieldGeometry */ -class PxShape : public PxBase +class PxShape : public PxRefCounted { public: - /** \brief Decrements the reference count of a shape and releases it if the new reference count is zero. @@ -153,33 +155,7 @@ public: @see PxRigidActor::createShape() PxPhysics::createShape() PxRigidActor::attachShape() PxRigidActor::detachShape() */ - virtual void release() = 0; - - /** - \brief Returns the reference count of the shape. - - At creation, the reference count of the shape is 1. Every actor referencing this shape increments the - count by 1. When the reference count reaches 0, and only then, the shape gets destroyed automatically. - - \return the current reference count. - */ - virtual PxU32 getReferenceCount() const = 0; - - /** - \brief Acquires a counted reference to a shape. - - This method increases the reference count of the shape by 1. Decrement the reference count by calling release() - */ - virtual void acquireReference() = 0; - - /** - \brief Get the geometry type of the shape. - - \return Type of shape geometry. - - @see PxGeometryType - */ - virtual PxGeometryType::Enum getGeometryType() const = 0; + virtual void release() = 0; /** \brief Adjust the geometry of the shape. @@ -192,19 +168,31 @@ public: @see PxGeometry PxGeometryType getGeometryType() */ - virtual void setGeometry(const PxGeometry& geometry) = 0; - + virtual void setGeometry(const PxGeometry& geometry) = 0; /** - \brief Retrieve the geometry from the shape in a PxGeometryHolder wrapper class. + \brief Retrieve a reference to the shape's geometry. + + \warning The returned reference has the same lifetime as the PxShape it comes from. + + \return Reference to internal PxGeometry object. - \return a PxGeometryHolder object containing the geometry; - @see PxGeometry PxGeometryType getGeometryType() setGeometry() */ + virtual const PxGeometry& getGeometry() const = 0; - virtual PxGeometryHolder getGeometry() const = 0; + /** + \brief Get the geometry type of the shape. + \return Type of shape geometry. + + @see PxGeometryType + @deprecated + */ + PX_DEPRECATED PX_FORCE_INLINE PxGeometryType::Enum getGeometryType() const + { + return getGeometry().getType(); + } /** \brief Fetch the geometry of the shape. @@ -216,8 +204,12 @@ public: \return True on success else false @see PxGeometry PxGeometryType getGeometryType() + @deprecated */ - virtual bool getBoxGeometry(PxBoxGeometry& geometry) const = 0; + PX_DEPRECATED PX_FORCE_INLINE bool getBoxGeometry(PxBoxGeometry& geometry) const + { + return getGeometryT(PxGeometryType::eBOX, geometry); + } /** \brief Fetch the geometry of the shape. @@ -229,8 +221,12 @@ public: \return True on success else false @see PxGeometry PxGeometryType getGeometryType() + @deprecated */ - virtual bool getSphereGeometry(PxSphereGeometry& geometry) const = 0; + PX_DEPRECATED PX_FORCE_INLINE bool getSphereGeometry(PxSphereGeometry& geometry) const + { + return getGeometryT(PxGeometryType::eSPHERE, geometry); + } /** \brief Fetch the geometry of the shape. @@ -242,8 +238,12 @@ public: \return True on success else false @see PxGeometry PxGeometryType getGeometryType() + @deprecated */ - virtual bool getCapsuleGeometry(PxCapsuleGeometry& geometry) const = 0; + PX_DEPRECATED PX_FORCE_INLINE bool getCapsuleGeometry(PxCapsuleGeometry& geometry) const + { + return getGeometryT(PxGeometryType::eCAPSULE, geometry); + } /** \brief Fetch the geometry of the shape. @@ -255,8 +255,12 @@ public: \return True on success else false @see PxGeometry PxGeometryType getGeometryType() + @deprecated */ - virtual bool getPlaneGeometry(PxPlaneGeometry& geometry) const = 0; + PX_DEPRECATED PX_FORCE_INLINE bool getPlaneGeometry(PxPlaneGeometry& geometry) const + { + return getGeometryT(PxGeometryType::ePLANE, geometry); + } /** \brief Fetch the geometry of the shape. @@ -268,8 +272,12 @@ public: \return True on success else false @see PxGeometry PxGeometryType getGeometryType() + @deprecated */ - virtual bool getConvexMeshGeometry(PxConvexMeshGeometry& geometry) const = 0; + PX_DEPRECATED PX_FORCE_INLINE bool getConvexMeshGeometry(PxConvexMeshGeometry& geometry) const + { + return getGeometryT(PxGeometryType::eCONVEXMESH, geometry); + } /** \brief Fetch the geometry of the shape. @@ -281,9 +289,12 @@ public: \return True on success else false @see PxGeometry PxGeometryType getGeometryType() + @deprecated */ - virtual bool getTriangleMeshGeometry(PxTriangleMeshGeometry& geometry) const = 0; - + PX_DEPRECATED PX_FORCE_INLINE bool getTriangleMeshGeometry(PxTriangleMeshGeometry& geometry) const + { + return getGeometryT(PxGeometryType::eTRIANGLEMESH, geometry); + } /** \brief Fetch the geometry of the shape. @@ -295,8 +306,63 @@ public: \return True on success else false @see PxGeometry PxGeometryType getGeometryType() + @deprecated */ - virtual bool getHeightFieldGeometry(PxHeightFieldGeometry& geometry) const = 0; + PX_DEPRECATED PX_FORCE_INLINE bool getTetrahedronMeshGeometry(PxTetrahedronMeshGeometry& geometry) const + { + return getGeometryT(PxGeometryType::eTETRAHEDRONMESH, geometry); + } + + /** + \brief Fetch the geometry of the shape. + + \note If the type of geometry to extract does not match the geometry type of the shape + then the method will return false and the passed in geometry descriptor is not modified. + + \param[in] geometry The descriptor to save the shape's geometry data to. + \return True on success else false + + @see PxGeometry PxGeometryType getGeometryType() + @deprecated + */ + PX_DEPRECATED PX_FORCE_INLINE bool getParticleSystemGeometry(PxParticleSystemGeometry& geometry) const + { + return getGeometryT(PxGeometryType::ePARTICLESYSTEM, geometry); + } + + /** + \brief Fetch the geometry of the shape. + + \note If the type of geometry to extract does not match the geometry type of the shape + then the method will return false and the passed in geometry descriptor is not modified. + + \param[in] geometry The descriptor to save the shape's geometry data to. + \return True on success else false + + @see PxGeometry PxGeometryType getGeometryType() + @deprecated + */ + PX_DEPRECATED PX_FORCE_INLINE bool getHeightFieldGeometry(PxHeightFieldGeometry& geometry) const + { + return getGeometryT(PxGeometryType::eHEIGHTFIELD, geometry); + } + + /** + \brief Fetch the geometry of the shape. + + \note If the type of geometry to extract does not match the geometry type of the shape + then the method will return false and the passed in geometry descriptor is not modified. + + \param[in] geometry The descriptor to save the shape's geometry data to. + \return True on success else false + + @see PxGeometry PxGeometryType getGeometryType() + @deprecated + */ + PX_DEPRECATED PX_FORCE_INLINE bool getCustomGeometry(PxCustomGeometry& geometry) const + { + return getGeometryT(PxGeometryType::eCUSTOM, geometry); + } /** \brief Retrieves the actor which this shape is associated with. @@ -305,8 +371,7 @@ public: @see PxRigidStatic, PxRigidDynamic, PxArticulationLink */ - virtual PxRigidActor* getActor() const = 0; - + virtual PxRigidActor* getActor() const = 0; /************************************************************************************************/ @@ -332,7 +397,7 @@ public: @see getLocalPose() */ - virtual void setLocalPose(const PxTransform& pose) = 0; + virtual void setLocalPose(const PxTransform& pose) = 0; /** \brief Retrieves the pose of the shape in actor space, i.e. relative to the actor they are owned by. @@ -343,7 +408,7 @@ public: @see setLocalPose() */ - virtual PxTransform getLocalPose() const = 0; + virtual PxTransform getLocalPose() const = 0; //@} /************************************************************************************************/ @@ -362,14 +427,14 @@ public: @see getSimulationFilterData() */ - virtual void setSimulationFilterData(const PxFilterData& data) = 0; + virtual void setSimulationFilterData(const PxFilterData& data) = 0; /** \brief Retrieves the shape's collision filter data. @see setSimulationFilterData() */ - virtual PxFilterData getSimulationFilterData() const = 0; + virtual PxFilterData getSimulationFilterData() const = 0; /** \brief Sets the user definable query filter data. @@ -378,20 +443,20 @@ public: @see getQueryFilterData() */ - virtual void setQueryFilterData(const PxFilterData& data) = 0; + virtual void setQueryFilterData(const PxFilterData& data) = 0; /** \brief Retrieves the shape's Query filter data. @see setQueryFilterData() */ - virtual PxFilterData getQueryFilterData() const = 0; + virtual PxFilterData getQueryFilterData() const = 0; //@} /************************************************************************************************/ /** - \brief Assigns material(s) to the shape. + \brief Assigns material(s) to the shape. Will remove existing materials from the shape. Sleeping: Does NOT wake the associated actor up automatically. @@ -400,7 +465,32 @@ public: @see PxPhysics.createMaterial() getMaterials() */ - virtual void setMaterials(PxMaterial*const* materials, PxU16 materialCount) = 0; + virtual void setMaterials(PxMaterial*const* materials, PxU16 materialCount) = 0; + + /** + \brief Assigns FEM soft body material(s) to the shape. Will remove existing materials from the shape. + + Sleeping: Does NOT wake the associated actor up automatically. + + \param[in] materials List of material pointers to assign to the shape. See #PxFEMSoftBodyMaterial + \param[in] materialCount The number of materials provided. + + @see PxPhysics.createFEMSoftBodyMaterial() getSoftBodyMaterials() + */ + virtual void setSoftBodyMaterials(PxFEMSoftBodyMaterial*const* materials, PxU16 materialCount) = 0; + + /** + \brief Assigns FEM cloth material(s) to the shape. Will remove existing materials from the shape. + \warning Feature under development, only for internal usage. + + Sleeping: Does NOT wake the associated actor up automatically. + + \param[in] materials List of material pointers to assign to the shape. See #PxFEMClothMaterial + \param[in] materialCount The number of materials provided. + + @see PxPhysics.createFEMClothMaterial() getClothMaterials() + */ + virtual void setClothMaterials(PxFEMClothMaterial*const* materials, PxU16 materialCount) = 0; /** \brief Returns the number of materials assigned to the shape. @@ -411,14 +501,14 @@ public: @see PxMaterial getMaterials() */ - virtual PxU16 getNbMaterials() const = 0; + virtual PxU16 getNbMaterials() const = 0; /** \brief Retrieve all the material pointers associated with the shape. You can retrieve the number of material pointers by calling #getNbMaterials() - Note: Removing materials with #PxMaterial::release() will invalidate the pointer of the released material. + Note: The returned data may contain invalid pointers if you release materials using #PxMaterial::release(). \param[out] userBuffer The buffer to store the material pointers. \param[in] bufferSize Size of provided user buffer. @@ -427,8 +517,41 @@ public: @see PxMaterial getNbMaterials() PxMaterial::release() */ - virtual PxU32 getMaterials(PxMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex=0) const = 0; - + virtual PxU32 getMaterials(PxMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex=0) const = 0; + + /** + \brief Retrieve all the FEM soft body material pointers associated with the shape. + + You can retrieve the number of material pointers by calling #getNbMaterials() + + Note: The returned data may contain invalid pointers if you release materials using #PxMaterial::release(). + + \param[out] userBuffer The buffer to store the material pointers. + \param[in] bufferSize Size of provided user buffer. + \param[in] startIndex Index of first material pointer to be retrieved + \return Number of material pointers written to the buffer. + + @see PxFEMSoftBodyMaterial getNbMaterials() PxMaterial::release() + */ + virtual PxU32 getSoftBodyMaterials(PxFEMSoftBodyMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0; + + /** + \brief Retrieve all the FEM cloth material pointers associated with the shape. + \warning Feature under development, only for internal usage. + + You can retrieve the number of material pointers by calling #getNbMaterials() + + Note: The returned data may contain invalid pointers if you release materials using #PxMaterial::release(). + + \param[out] userBuffer The buffer to store the material pointers. + \param[in] bufferSize Size of provided user buffer. + \param[in] startIndex Index of first material pointer to be retrieved + \return Number of material pointers written to the buffer. + + @see PxFEMClothMaterial getNbMaterials() PxMaterial::release() + */ + virtual PxU32 getClothMaterials(PxFEMClothMaterial** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const = 0; + /** \brief Retrieve material from given triangle index. @@ -436,8 +559,8 @@ public: returned to users by various SDK functions such as raycasts. This function is only useful for triangle meshes or heightfields, which have per-triangle - materials. For other shapes the function returns the single material associated with the - shape, regardless of the index. + materials. For other shapes or SDF triangle meshes, the function returns the single material + associated with the shape, regardless of the index. \param[in] faceIndex The internal triangle index whose material you want to retrieve. \return Material from input triangle @@ -447,7 +570,7 @@ public: @see PxMaterial getNbMaterials() PxMaterial::release() */ - virtual PxMaterial* getMaterialFromInternalFaceIndex(PxU32 faceIndex) const = 0; + virtual PxBaseMaterial* getMaterialFromInternalFaceIndex(PxU32 faceIndex) const = 0; /** \brief Sets the contact offset. @@ -465,7 +588,7 @@ public: @see getContactOffset PxTolerancesScale setRestOffset */ - virtual void setContactOffset(PxReal contactOffset) = 0; + virtual void setContactOffset(PxReal contactOffset) = 0; /** \brief Retrieves the contact offset. @@ -474,7 +597,7 @@ public: @see setContactOffset() */ - virtual PxReal getContactOffset() const = 0; + virtual PxReal getContactOffset() const = 0; /** \brief Sets the rest offset. @@ -491,7 +614,7 @@ public: @see getRestOffset setContactOffset */ - virtual void setRestOffset(PxReal restOffset) = 0; + virtual void setRestOffset(PxReal restOffset) = 0; /** \brief Retrieves the rest offset. @@ -500,8 +623,31 @@ public: @see setRestOffset() */ - virtual PxReal getRestOffset() const = 0; + virtual PxReal getRestOffset() const = 0; + /** + \brief Sets the density used to interact with fluids. + + To be physically accurate, the density of a rigid body should be computed as its mass divided by its volume. To + simplify tuning the interaction of fluid and rigid bodies, the density for fluid can differ from the real density. This + allows to create floating bodies, even if they are supposed to sink with their mass and volume. + + Default: 800.0f + + \param[in] densityForFluid Range: (0, PX_MAX_F32) + + @see getDensityForFluid + */ + virtual void setDensityForFluid(PxReal densityForFluid) = 0; + + /** + \brief Retrieves the density used to interact with fluids. + + \return The density of the body when interacting with fluid. + + @see setDensityForFluid() + */ + virtual PxReal getDensityForFluid() const = 0; /** \brief Sets torsional patch radius. @@ -511,10 +657,11 @@ public: so, if the shapes are separated or penetration is zero, no torsional friction will be applied. It is used to approximate rotational friction introduced by the compression of contacting surfaces. - \param[in] radius Range: (0, PX_MAX_F32) + Default: 0.0 + \param[in] radius Range: (0, PX_MAX_F32) */ - virtual void setTorsionalPatchRadius(PxReal radius) = 0; + virtual void setTorsionalPatchRadius(PxReal radius) = 0; /** \brief Gets torsional patch radius. @@ -526,7 +673,7 @@ public: \return The torsional patch radius of the shape. */ - virtual PxReal getTorsionalPatchRadius() const = 0; + virtual PxReal getTorsionalPatchRadius() const = 0; /** \brief Sets minimum torsional patch radius. @@ -536,10 +683,11 @@ public: If the radius is > 0, some torsional friction will be applied regardless of the value of torsionalPatchRadius or the amount of penetration. - \param[in] radius Range: (0, PX_MAX_F32) + Default: 0.0 + \param[in] radius Range: (0, PX_MAX_F32) */ - virtual void setMinTorsionalPatchRadius(PxReal radius) = 0; + virtual void setMinTorsionalPatchRadius(PxReal radius) = 0; /** \brief Gets minimum torsional patch radius. @@ -551,8 +699,7 @@ public: \return The minimum torsional patch radius of the shape. */ - virtual PxReal getMinTorsionalPatchRadius() const = 0; - + virtual PxReal getMinTorsionalPatchRadius() const = 0; /************************************************************************************************/ @@ -568,14 +715,14 @@ public: @see PxShapeFlag getFlags() */ - virtual void setFlag(PxShapeFlag::Enum flag, bool value) = 0; + virtual void setFlag(PxShapeFlag::Enum flag, bool value) = 0; /** \brief Sets shape flags @see PxShapeFlag getFlags() */ - virtual void setFlags(PxShapeFlags inFlags) = 0; + virtual void setFlags(PxShapeFlags inFlags) = 0; /** \brief Retrieves shape flags. @@ -584,14 +731,14 @@ public: @see PxShapeFlag setFlag() */ - virtual PxShapeFlags getFlags() const = 0; + virtual PxShapeFlags getFlags() const = 0; /** \brief Returns true if the shape is exclusive to an actor. @see PxPhysics::createShape() */ - virtual bool isExclusive() const = 0; + virtual bool isExclusive() const = 0; /** \brief Sets a name string for the object that can be retrieved with #getName(). @@ -605,8 +752,7 @@ public: @see getName() */ - virtual void setName(const char* name) = 0; - + virtual void setName(const char* name) = 0; /** \brief retrieves the name string set with setName(). @@ -614,21 +760,30 @@ public: @see setName() */ - virtual const char* getName() const = 0; + virtual const char* getName() const = 0; - virtual const char* getConcreteTypeName() const { return "PxShape"; } + virtual const char* getConcreteTypeName() const { return "PxShape"; } /************************************************************************************************/ - void* userData; //!< user can assign this to whatever, usually to create a 1:1 relationship with a user object. + void* userData; //!< user can assign this to whatever, usually to create a 1:1 relationship with a user object. protected: - PX_INLINE PxShape(PxBaseFlags baseFlags) : PxBase(baseFlags) {} - PX_INLINE PxShape(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags), userData(NULL) {} - virtual ~PxShape() {} - virtual bool isKindOf(const char* name) const { return !::strcmp("PxShape", name) || PxBase::isKindOf(name); } + PX_INLINE PxShape(PxBaseFlags baseFlags) : PxRefCounted(baseFlags) {} + PX_INLINE PxShape(PxType concreteType, PxBaseFlags baseFlags) : PxRefCounted(concreteType, baseFlags), userData(NULL) {} + virtual ~PxShape() {} + virtual bool isKindOf(const char* name) const { return !::strcmp("PxShape", name) || PxRefCounted::isKindOf(name); } + template + PX_FORCE_INLINE bool getGeometryT(PxGeometryType::Enum type, T& geom) const + { + if(getGeometryType() != type) + return false; + + geom = static_cast(getGeometry()); + return true; + } }; #if !PX_DOXYGEN diff --git a/Source/ThirdParty/PhysX/PxSimulationEventCallback.h b/Source/ThirdParty/PhysX/PxSimulationEventCallback.h index e242d45b1..5c4cb1813 100644 --- a/Source/ThirdParty/PhysX/PxSimulationEventCallback.h +++ b/Source/ThirdParty/PhysX/PxSimulationEventCallback.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_SIMULATION_EVENT_CALLBACK -#define PX_SIMULATION_EVENT_CALLBACK +#ifndef PX_SIMULATION_EVENT_CALLBACK_H +#define PX_SIMULATION_EVENT_CALLBACK_H /** \addtogroup physics @{ */ @@ -137,7 +135,7 @@ public: If CCD with multiple passes is enabled, then a fast moving object might bounce on and off the same object multiple times. Also, different shapes of the same actor might gain and lose contact with an other -object over multiple passes. This marker allows to seperate the extra data items for each collision case, as well as +object over multiple passes. This marker allows to separate the extra data items for each collision case, as well as distinguish the shape pair reports of different CCD passes. Example: @@ -360,7 +358,7 @@ struct PxContactPairHeader @see PxActor */ - PxRigidActor* actors[2]; + PxActor* actors[2]; /** \brief Stream containing extra data as requested in the PxPairFlag flags of the simulation filter. @@ -748,9 +746,9 @@ struct PxTriggerPair PX_INLINE PxTriggerPair() {} PxShape* triggerShape; //!< The shape that has been marked as a trigger. - PxRigidActor* triggerActor; //!< The actor to which triggerShape is attached + PxActor* triggerActor; //!< The actor to which triggerShape is attached PxShape* otherShape; //!< The shape causing the trigger event. \deprecated (see #PxSimulationEventCallback::onTrigger()) If collision between trigger shapes is enabled, then this member might point to a trigger shape as well. - PxRigidActor* otherActor; //!< The actor to which otherShape is attached + PxActor* otherActor; //!< The actor to which otherShape is attached PxPairFlag::Enum status; //!< Type of trigger event (eNOTIFY_TOUCH_FOUND or eNOTIFY_TOUCH_LOST). eNOTIFY_TOUCH_PERSISTS events are not supported. PxTriggerPairFlags flags; //!< Additional information on the pair (see #PxTriggerPairFlag) }; @@ -779,7 +777,7 @@ struct PxConstraintInfo With the exception of onAdvance(), the events get sent during the call to either #PxScene::fetchResults() or #PxScene::flushSimulation() with sendPendingReports=true. onAdvance() gets called while the simulation -is running (that is between PxScene::simulate(), onAdvance() and PxScene::fetchResults()). +is running (that is between PxScene::simulate() or PxScene::advance() and PxScene::fetchResults()). \note SDK state should not be modified from within the callbacks. In particular objects should not be created or destroyed. If state modification is needed then the changes should be stored to a buffer @@ -885,10 +883,6 @@ class PxSimulationEventCallback \note The provided buffers are valid and can be read until the next call to #PxScene::simulate() or #PxScene::collide(). - \note Buffered user changes to the rigid body pose will not yet be reflected in the provided data. More important, - the provided data might contain bodies that have been deleted while the simulation was running. It is the user's - responsibility to detect and avoid dereferencing such bodies. - \note This callback gets triggered while the simulation is running. If the provided rigid body references are used to read properties of the object, then the callback has to guarantee no other thread is writing to the same body at the same time. diff --git a/Source/ThirdParty/PhysX/PxSimulationStatistics.h b/Source/ThirdParty/PhysX/PxSimulationStatistics.h index 57635e3de..2102ecd90 100644 --- a/Source/ThirdParty/PhysX/PxSimulationStatistics.h +++ b/Source/ThirdParty/PhysX/PxSimulationStatistics.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_SIMULATION_STATISTICS -#define PX_SIMULATION_STATISTICS +#ifndef PX_SIMULATION_STATISTICS_H +#define PX_SIMULATION_STATISTICS_H /** \addtogroup physics @{ */ @@ -274,6 +272,106 @@ public: */ PxU32 nbPartitions; + /** + \brief GPU device memory in bytes allocated for particle state accessible through API + */ + PxU64 gpuMemParticles; + + /** + \brief GPU device memory in bytes allocated for FEM-based soft body state accessible through API + */ + PxU64 gpuMemSoftBodies; + + /** + \brief GPU device memory in bytes allocated for FEM-based cloth state accessible through API + */ + PxU64 gpuMemFEMCloths; + + /** + \brief GPU device memory in bytes allocated for hairsystem state accessible through API + */ + PxU64 gpuMemHairSystems; + + /** + \brief GPU device memory in bytes allocated for internal heap allocation + */ + PxU64 gpuMemHeap; + + /** + \brief GPU device heap memory used for broad phase in bytes + */ + PxU64 gpuMemHeapBroadPhase; + + /** + \brief GPU device heap memory used for narrow phase in bytes + */ + PxU64 gpuMemHeapNarrowPhase; + + /** + \brief GPU device heap memory used for solver in bytes + */ + PxU64 gpuMemHeapSolver; + + /** + \brief GPU device heap memory used for articulations in bytes + */ + PxU64 gpuMemHeapArticulation; + + /** + \brief GPU device heap memory used for simulation pipeline in bytes + */ + PxU64 gpuMemHeapSimulation; + + /** + \brief GPU device heap memory used for articulations in the simulation pipeline in bytes + */ + PxU64 gpuMemHeapSimulationArticulation; + + /** + \brief GPU device heap memory used for particles in the simulation pipeline in bytes + */ + PxU64 gpuMemHeapSimulationParticles; + + /** + \brief GPU device heap memory used for soft bodies in the simulation pipeline in bytes + */ + PxU64 gpuMemHeapSimulationSoftBody; + + /** + \brief GPU device heap memory used for FEM-cloth in the simulation pipeline in bytes + */ + PxU64 gpuMemHeapSimulationFEMCloth; + + /** + \brief GPU device heap memory used for hairsystem in the simulation pipeline in bytes + */ + PxU64 gpuMemHeapSimulationHairSystem; + + /** + \brief GPU device heap memory used for shared buffers in the particles pipeline in bytes + */ + PxU64 gpuMemHeapParticles; + + /** + \brief GPU device heap memory used for shared buffers in the FEM-based soft body pipeline in bytes + */ + PxU64 gpuMemHeapSoftBodies; + + /** + \brief GPU device heap memory used for shared buffers in the FEM-based cloth pipeline in bytes + */ + PxU64 gpuMemHeapFEMCloths; + + /** + \brief GPU device heap memory used for shared buffers in the hairsystem pipeline in bytes + */ + PxU64 gpuMemHeapHairSystems; + + /** + \brief GPU device heap memory not covered by other stats in bytes + */ + PxU64 gpuMemHeapOther; + PxSimulationStatistics() : nbActiveConstraints (0), nbActiveDynamicBodies (0), @@ -294,7 +392,27 @@ public: nbLostPairs (0), nbNewTouches (0), nbLostTouches (0), - nbPartitions (0) + nbPartitions (0), + gpuMemParticles (0), + gpuMemSoftBodies (0), + gpuMemFEMCloths (0), + gpuMemHairSystems (0), + gpuMemHeap (0), + gpuMemHeapBroadPhase (0), + gpuMemHeapNarrowPhase (0), + gpuMemHeapSolver (0), + gpuMemHeapArticulation (0), + gpuMemHeapSimulation (0), + gpuMemHeapSimulationArticulation (0), + gpuMemHeapSimulationParticles (0), + gpuMemHeapSimulationSoftBody (0), + gpuMemHeapSimulationFEMCloth (0), + gpuMemHeapSimulationHairSystem (0), + gpuMemHeapParticles (0), + gpuMemHeapSoftBodies (0), + gpuMemHeapFEMCloths (0), + gpuMemHeapHairSystems (0), + gpuMemHeapOther (0) { nbBroadPhaseAdds = 0; nbBroadPhaseRemoves = 0; diff --git a/Source/ThirdParty/PhysX/PxSoftBody.h b/Source/ThirdParty/PhysX/PxSoftBody.h new file mode 100644 index 000000000..c69ffd119 --- /dev/null +++ b/Source/ThirdParty/PhysX/PxSoftBody.h @@ -0,0 +1,742 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_SOFT_BODY_H +#define PX_SOFT_BODY_H +/** \addtogroup physics +@{ */ + +#include "PxFEMParameter.h" +#include "PxActor.h" +#include "PxConeLimitedConstraint.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +#if PX_VC +#pragma warning(push) +#pragma warning(disable : 4435) +#endif + + class PxCudaContextManager; + class PxBuffer; + class PxTetrahedronMesh; + class PxSoftBodyAuxData; + class PxFEMCloth; + class PxParticleBuffer; + + /** + \brief The maximum tetrahedron index supported in the model. + */ + #define PX_MAX_TETID 0x000fffff + + /** + \brief Identifies input and output buffers for PxSoftBody. + + @see PxSoftBodyData::readData(), PxSoftBodyData::writeData(), PxBuffer. + */ + struct PxSoftBodyData + { + enum Enum + { + eNONE = 0, + + ePOSITION_INVMASS = 1 << 0, //!< Flag to request access to the collision mesh's positions; read only @see PxSoftBody::writeData + eSIM_POSITION_INVMASS = 1 << 2, //!< Flag to request access to the simulation mesh's positions and inverse masses + eSIM_VELOCITY = 1 << 3, //!< Flag to request access to the simulation mesh's velocities and inverse masses + eSIM_KINEMATIC_TARGET = 1 << 4, //!< Flag to request access to the simulation mesh's kinematic target position + + eALL = ePOSITION_INVMASS | eSIM_POSITION_INVMASS | eSIM_VELOCITY | eSIM_KINEMATIC_TARGET + }; + }; + + typedef PxFlags PxSoftBodyDataFlags; + + /** + \brief Flags to enable or disable special modes of a SoftBody + */ + struct PxSoftBodyFlag + { + enum Enum + { + eDISABLE_SELF_COLLISION = 1 << 0, //!< Determines if self collision will be detected and resolved + eCOMPUTE_STRESS_TENSOR = 1 << 1, //!< Enables computation of a Cauchy stress tensor for every tetrahedron in the simulation mesh. The tensors can be accessed through the softbody direct API + eENABLE_CCD = 1 << 2, //!< Enables support for continuous collision detection + eDISPLAY_SIM_MESH = 1 << 3, //!< Enable debug rendering to display the simulation mesh + eKINEMATIC = 1 << 4, //!< Enables support for kinematic motion of the collision and simulation mesh. + ePARTIALLY_KINEMATIC = 1 << 5 //!< Enables partially kinematic motion of the collisios and simulation mesh. + }; + }; + + typedef PxFlags PxSoftBodyFlags; + + /** + \brief Represents a FEM softbody including everything to calculate its definition like geometry and material properties + */ + class PxSoftBody : public PxActor + { + public: + + virtual ~PxSoftBody() {} + + /** + \brief Set a single softbody flag + + \param[in] flag The flag to set or clear + \param[in] val The new state of the flag + */ + virtual void setSoftBodyFlag(PxSoftBodyFlag::Enum flag, bool val) = 0; + + /** + \brief Set the softbody flags + + \param[in] flags The new softbody flags + */ + virtual void setSoftBodyFlags(PxSoftBodyFlags flags) = 0; + + /** + \brief Get the softbody flags + + \return The softbody flags + */ + virtual PxSoftBodyFlags getSoftBodyFlag() const = 0; + + /** + \brief Set parameter for FEM internal solve + + \param[in] parameters The FEM parameters + */ + virtual void setParameter(const PxFEMParameters parameters) = 0; + + /** + \brief Get parameter for FEM internal solve + + \return The FEM parameters + */ + virtual PxFEMParameters getParameter() const = 0; + + /** + \brief Issues a read command to the PxSoftBody. + + Read operations are scheduled and then flushed in PxScene::simulate(). + Read operations are known to be finished when PxBuffer::map() returns. + + PxSoftBodyData::ePOSITION_INVMASS, PxSoftBodyData::eSIM_POSITION_INVMASS and PxSoftBodyData::eSIM_VELOCITY can be read from the PxSoftBody. + + The softbody class offers internal cpu buffers that can be used to hold the data. The cpu buffers are accessible through getPositionInvMassCPU(), + getSimPositionInvMassCPU() and getSimVelocityInvMassCPU(). + + \param[in] flags Specifies which PxSoftBody data to read from. + \param[in] buffer Specifies buffer to which data is written to. + \param[in] flush If set to true the command gets executed immediately, otherwise it will get executed the next time copy commands are flushed. + + @see writeData(), PxBuffer, PxSoftBodyData + */ + virtual void readData(PxSoftBodyData::Enum flags, PxBuffer& buffer, bool flush = false) = 0; + + /** + \brief Issues a read command to the PxSoftBody. + + Read operations are scheduled and then flushed in PxScene::simulate(). + Read operations are known to be finished when PxBuffer::map() returns. + + PxSoftBodyData::ePOSITION_INVMASS, PxSoftBodyData::eSIM_POSITION_INVMASS and PxSoftBodyData::eSIM_VELOCITY can be read from the PxSoftBody. + + The data to read from the GPU is written to the corresponding cpu buffer that a softbody provides. Those cpu buffers are accessible through + getPositionInvMassCPU(), getSimPositionInvMassCPU() or getSimVelocityInvMassCPU(). + + \param[in] flags Specifies which PxSoftBody data to read from. + \param[in] flush If set to true the command gets executed immediately, otherwise it will get executed the next time copy commands are flushed. + + @see writeData(), PxSoftBodyData + */ + virtual void readData(PxSoftBodyData::Enum flags, bool flush = false) = 0; + + /** + \brief Issues a write command to the PxSoftBody. + + Write operations are scheduled and then flushed in PxScene::simulate(). + Write operations are known to be finished when PxScene::fetchResult() returns. + + PxSoftBodyData::eSIM_POSITION_INVMASS and PxSoftBodyData::eSIM_VELOCITY can be written to the PxSoftBody. PxSoftBodyData::ePOSITION_INVMASS is read only, + because the collision-mesh vertices are driven by the simulation-mesh vertices, which can be written to with PxSoftBodyData::eSIM_POSITION_INVMASS. + + The softbody class offers internal cpu buffers that can be used to hold the data. The cpu buffers are accessible through getPositionInvMassCPU(), + getSimPositionInvMassCPU() and getSimVelocityInvMassCPU(). Consider to use the PxSoftBodyExt::commit() extension method if all buffers should get written. + + \param[in] flags Specifies which PxSoftBody data to write to. + \param[in] buffer Specifies buffer from which data is read. + \param[in] flush If set to true the command gets executed immediately, otherwise it will get executed the next time copy commands are flushed. + + @see readData(), PxBuffer, PxSoftBodyData, PxSoftBodyExt::commit + */ + virtual void writeData(PxSoftBodyData::Enum flags, PxBuffer& buffer, bool flush = false) = 0; + + /** + \brief Issues a write command to the PxSoftBody. + + Write operations are scheduled and then flushed in PxScene::simulate(). + Write operations are known to be finished when PxScene::fetchResult() returns. + + PxSoftBodyData::eSIM_POSITION_INVMASS and PxSoftBodyData::eSIM_VELOCITY can be written to the PxSoftBody. PxSoftBodyData::ePOSITION_INVMASS is read only, + because the collision-mesh vertices are driven by the simulation-mesh vertices, which can be written to with PxSoftBodyData::eSIM_POSITION_INVMASS. + + The data to write to the GPU is taken from the corresponding cpu buffer that a softbody provides. Those cpu buffers are accessible through + getPositionInvMassCPU(), getSimPositionInvMassCPU() or getSimVelocityInvMassCPU(). + + \param[in] flags Specifies which PxSoftBody data to write to. + \param[in] flush If set to true the command gets executed immediately, otherwise it will get executed the next time copy commands are flushed. + + @see readData(), PxSoftBodyData + */ + virtual void writeData(PxSoftBodyData::Enum flags, bool flush = false) = 0; + + /** + \brief Return the cuda context manager + + \return The cuda context manager + */ + virtual PxCudaContextManager* getCudaContextManager() const = 0; + + /** + \brief Sets the wake counter for the soft body. + + The wake counter value determines the minimum amount of time until the soft body can be put to sleep. Please note + that a soft body will not be put to sleep if any vertex velocity is above the specified threshold + or if other awake objects are touching it. + + \note Passing in a positive value will wake the soft body up automatically. + + Default: 0.4 (which corresponds to 20 frames for a time step of 0.02) + + \param[in] wakeCounterValue Wake counter value. Range: [0, PX_MAX_F32) + + @see isSleeping() getWakeCounter() + */ + virtual void setWakeCounter(PxReal wakeCounterValue) = 0; + + /** + \brief Returns the wake counter of the soft body. + + \return The wake counter of the soft body. + + @see isSleeping() setWakeCounter() + */ + virtual PxReal getWakeCounter() const = 0; + + /** + \brief Returns true if this soft body is sleeping. + + When an actor does not move for a period of time, it is no longer simulated in order to save time. This state + is called sleeping. However, because the object automatically wakes up when it is either touched by an awake object, + or a sleep-affecting property is changed by the user, the entire sleep mechanism should be transparent to the user. + + A soft body can only go to sleep if all vertices are ready for sleeping. A soft body is guaranteed to be awake + if at least one of the following holds: + + \li The wake counter is positive (@see setWakeCounter()). + \li The velocity of any vertex is above the sleep threshold. + + If a soft body is sleeping, the following state is guaranteed: + + \li The wake counter is zero. + \li The linear velocity of all vertices is zero. + + When a soft body gets inserted into a scene, it will be considered asleep if all the points above hold, else it will + be treated as awake. + + \note It is invalid to use this method if the soft body has not been added to a scene already. + + \return True if the soft body is sleeping. + + @see isSleeping() + */ + virtual bool isSleeping() const = 0; + + /** + \brief Sets the solver iteration counts for the body. + + The solver iteration count determines how accurately deformation and contacts are resolved. + If you are having trouble with softbodies that are not as stiff as they should be, then + setting a higher position iteration count may improve the behavior. + + If intersecting bodies are being depenetrated too violently, increase the number of velocity + iterations. + + Default: 4 position iterations, 1 velocity iteration + + \param[in] minPositionIters Minimal number of position iterations the solver should perform for this body. Range: [1,255] + \param[in] minVelocityIters Minimal number of velocity iterations the solver should perform for this body. Range: [1,255] + + @see getSolverIterationCounts() + */ + virtual void setSolverIterationCounts(PxU32 minPositionIters, PxU32 minVelocityIters = 1) = 0; + + /** + \brief Retrieves the solver iteration counts. + + @see setSolverIterationCounts() + */ + virtual void getSolverIterationCounts(PxU32& minPositionIters, PxU32& minVelocityIters) const = 0; + + + /** + \brief Retrieves the shape pointer belonging to the actor. + + \return Pointer to the collision mesh's shape + @see PxShape getNbShapes() PxShape::release() + */ + virtual PxShape* getShape() = 0; + + + /** + \brief Retrieve the collision mesh pointer. + + Allows to access the geometry of the tetrahedral mesh used to perform collision detection + + \return Pointer to the collision mesh + */ + virtual PxTetrahedronMesh* getCollisionMesh() = 0; + + /** + \brief Retrieves the simulation mesh pointer. + + Allows to access the geometry of the tetrahedral mesh used to compute the object's deformation + + \return Pointer to the simulation mesh + */ + virtual PxTetrahedronMesh* getSimulationMesh() = 0; + + /** + \brief Retrieves the simulation state pointer. + + Allows to access the additional data of the simulation mesh (inverse mass, rest state etc.). + The geometry part of the data is stored in the simulation mesh. + + \return Pointer to the simulation state + */ + virtual PxSoftBodyAuxData* getSoftBodyAuxData() = 0; + + + /** + \brief Attaches a shape + + Attaches the shape to use for collision detection + + \param[in] shape The shape to use for collisions + + \return Returns true if the operation was successful + */ + virtual bool attachShape(PxShape& shape) = 0; + + /** + \brief Attaches a simulation mesh + + Attaches the simulation mesh (geometry) and a state containing inverse mass, rest pose + etc. required to compute the softbody deformation. + + \param[in] simulationMesh The tetrahedral mesh used to compute the softbody's deformation + \param[in] softBodyAuxData A state that contain a mapping from simulation to collision mesh, volume information etc. + + \return Returns true if the operation was successful + */ + virtual bool attachSimulationMesh(PxTetrahedronMesh& simulationMesh, PxSoftBodyAuxData& softBodyAuxData) = 0; + + /** + \brief Detaches the shape + + Detaches the shape used for collision detection. + + @see void detachSimulationMesh() + */ + virtual void detachShape() = 0; + + /** + \brief Detaches the simulation mesh + + Detaches the simulation mesh and simulation state used to compute the softbody deformation. + + @see void detachShape() + */ + virtual void detachSimulationMesh() = 0; + + /** + \brief Releases the softbody + + Releases the softbody and frees its resources. + */ + virtual void release() = 0; + + /** + \brief Creates a collision filter between a particle and a tetrahedron in the soft body's collision mesh. + + \param[in] particlesystem The particle system used for the collision filter + \param[in] buffer The PxParticleBuffer to which the particle belongs to. + \param[in] particleId The particle whose collisions with the tetrahedron in the soft body are filtered. + \param[in] tetId The tetradedron in the soft body that is filtered. If tetId is PX_MAX_TETID, this particle will filter against all tetrahedra in this soft body + */ + virtual void addParticleFilter(PxPBDParticleSystem* particlesystem, const PxParticleBuffer* buffer, PxU32 particleId, PxU32 tetId) = 0; + + /** + \brief Removes a collision filter between a particle and a tetrahedron in the soft body's collision mesh. + + \param[in] particlesystem The particle system used for the collision filter + \param[in] buffer The PxParticleBuffer to which the particle belongs to. + \param[in] particleId The particle whose collisions with the tetrahedron in the soft body are filtered. + \param[in] tetId The tetrahedron in the soft body is filtered. + */ + virtual void removeParticleFilter(PxPBDParticleSystem* particlesystem, const PxParticleBuffer* buffer, PxU32 particleId, PxU32 tetId) = 0; + + /** + \brief Creates an attachment between a particle and a soft body. + Be aware that destroying the particle system before destroying the attachment is illegal and may cause a crash. + The soft body keeps track of these attachments but the particle system does not. + + \param[in] particlesystem The particle system used for the attachment + \param[in] buffer The PxParticleBuffer to which the particle belongs to. + \param[in] particleId The particle that is attached to a tetrahedron in the soft body's collision mesh. + \param[in] tetId The tetrahedron in the soft body's collision mesh to attach the particle to. + \param[in] barycentric The barycentric coordinates of the particle attachment position with respect to the tetrahedron specified with tetId. + \return Returns a handle that identifies the attachment created. This handle can be used to release the attachment later + */ + virtual PxU32 addParticleAttachment(PxPBDParticleSystem* particlesystem, const PxParticleBuffer* buffer, PxU32 particleId, PxU32 tetId, const PxVec4& barycentric) = 0; + + + /** + \brief Removes an attachment between a particle and a soft body. + Be aware that destroying the particle system before destroying the attachment is illegal and may cause a crash. + The soft body keeps track of these attachments but the particle system does not. + + \param[in] particlesystem The particle system used for the attachment + \param[in] handle Index that identifies the attachment. This handle gets returned by the addParticleAttachment when the attachment is created + */ + virtual void removeParticleAttachment(PxPBDParticleSystem* particlesystem, PxU32 handle) = 0; + + /** + \brief Creates a collision filter between a vertex in a soft body and a rigid body. + + \param[in] actor The rigid body actor used for the collision filter + \param[in] vertId The index of a vertex in the softbody's collision mesh whose collisions with the rigid body are filtered. + */ + virtual void addRigidFilter(PxRigidActor* actor, PxU32 vertId) = 0; + + /** + \brief Removes a collision filter between a vertex in a soft body and a rigid body. + + \param[in] actor The rigid body actor used for the collision filter + \param[in] vertId The index of a vertex in the softbody's collision mesh whose collisions with the rigid body are filtered. + */ + virtual void removeRigidFilter(PxRigidActor* actor, PxU32 vertId) = 0; + + /** + \brief Creates a rigid attachment between a soft body and a rigid body. + Be aware that destroying the rigid body before destroying the attachment is illegal and may cause a crash. + The soft body keeps track of these attachments but the rigid body does not. + + This method attaches a vertex on the soft body collision mesh to the rigid body. + + \param[in] actor The rigid body actor used for the attachment + \param[in] vertId The index of a vertex in the softbody's collision mesh that gets attached to the rigid body. + \param[in] actorSpacePose The location of the attachment point expressed in the rigid body's coordinate system. + \param[in] constraint The user defined cone distance limit constraint to limit the movement between a vertex in the soft body and rigid body. + \return Returns a handle that identifies the attachment created. This handle can be used to relese the attachment later + */ + virtual PxU32 addRigidAttachment(PxRigidActor* actor, PxU32 vertId, const PxVec3& actorSpacePose, PxConeLimitedConstraint* constraint = NULL) = 0; + + /** + \brief Releases a rigid attachment between a soft body and a rigid body. + Be aware that destroying the rigid body before destroying the attachment is illegal and may cause a crash. + The soft body keeps track of these attachments but the rigid body does not. + + This method removes a previously-created attachment between a vertex of the soft body collision mesh and the rigid body. + + \param[in] actor The rigid body actor used for the attachment + \param[in] handle Index that identifies the attachment. This handle gets returned by the addRigidAttachment when the attachment is created + */ + virtual void removeRigidAttachment(PxRigidActor* actor, PxU32 handle) = 0; + + /** + \brief Creates collision filter between a tetrahedron in a soft body and a rigid body. + + \param[in] actor The rigid body actor used for collision filter + \param[in] tetIdx The index of a tetrahedron in the softbody's collision mesh whose collisions with the rigid body is filtered. + */ + virtual void addTetRigidFilter(PxRigidActor* actor, PxU32 tetIdx) = 0; + + /** + \brief Removes collision filter between a tetrahedron in a soft body and a rigid body. + + \param[in] actor The rigid body actor used for collision filter + \param[in] tetIdx The index of a tetrahedron in the softbody's collision mesh whose collisions with the rigid body is filtered. + */ + virtual void removeTetRigidFilter(PxRigidActor* actor, PxU32 tetIdx) = 0; + + /** + \brief Creates a rigid attachment between a soft body and a rigid body. + Be aware that destroying the rigid body before destroying the attachment is illegal and may cause a crash. + The soft body keeps track of these attachments but the rigid body does not. + + This method attaches a point inside a tetrahedron of the collision to the rigid body. + + \param[in] actor The rigid body actor used for the attachment + \param[in] tetIdx The index of a tetrahedron in the softbody's collision mesh that contains the point to be attached to the rigid body + \param[in] barycentric The barycentric coordinates of the attachment point inside the tetrahedron specified by tetIdx + \param[in] actorSpacePose The location of the attachment point expressed in the rigid body's coordinate system. + \param[in] constraint The user defined cone distance limit constraint to limit the movement between a tet and rigid body. + \return Returns a handle that identifies the attachment created. This handle can be used to release the attachment later + */ + virtual PxU32 addTetRigidAttachment(PxRigidActor* actor, PxU32 tetIdx, const PxVec4& barycentric, const PxVec3& actorSpacePose, PxConeLimitedConstraint* constraint = NULL) = 0; + + /** + \brief Creates collision filter between a tetrahedron in a soft body and a tetrahedron in another soft body. + + \param[in] otherSoftBody The other soft body actor used for collision filter + \param[in] otherTetIdx The index of the tetrahedron in the other softbody's collision mesh to be filtered. + \param[in] tetIdx1 The index of the tetrahedron in the softbody's collision mesh to be filtered. + */ + virtual void addSoftBodyFilter(PxSoftBody* otherSoftBody, PxU32 otherTetIdx, PxU32 tetIdx1) = 0; + + /** + \brief Removes collision filter between a tetrahedron in a soft body and a tetrahedron in other soft body. + + \param[in] otherSoftBody The other soft body actor used for collision filter + \param[in] otherTetIdx The index of the other tetrahedron in the other softbody's collision mesh whose collision with the tetrahedron with the soft body is filtered. + \param[in] tetIdx1 The index of the tetrahedron in the softbody's collision mesh whose collision with the other tetrahedron with the other soft body is filtered. + */ + virtual void removeSoftBodyFilter(PxSoftBody* otherSoftBody, PxU32 otherTetIdx, PxU32 tetIdx1) = 0; + + /** + \brief Creates collision filters between a tetrahedron in a soft body with another soft body. + + \param[in] otherSoftBody The other soft body actor used for collision filter + \param[in] otherTetIndices The indices of the tetrahedron in the other softbody's collision mesh to be filtered. + \param[in] tetIndices The indices of the tetrahedron of the softbody's collision mesh to be filtered. + \param[in] tetIndicesSize The size of tetIndices. + */ + virtual void addSoftBodyFilters(PxSoftBody* otherSoftBody, PxU32* otherTetIndices, PxU32* tetIndices, PxU32 tetIndicesSize) = 0; + + /** + \brief Removes collision filters between a tetrahedron in a soft body with another soft body. + + \param[in] otherSoftBody The other soft body actor used for collision filter + \param[in] otherTetIndices The indices of the tetrahedron in the other softbody's collision mesh to be filtered. + \param[in] tetIndices The indices of the tetrahedron of the softbody's collision mesh to be filtered. + \param[in] tetIndicesSize The size of tetIndices. + */ + virtual void removeSoftBodyFilters(PxSoftBody* otherSoftBody, PxU32* otherTetIndices, PxU32* tetIndices, PxU32 tetIndicesSize) = 0; + + /** + \brief Creates an attachment between two soft bodies. + + This method attaches a point inside a tetrahedron of the collision mesh to a point in another soft body's tetrahedron collision mesh. + + \param[in] softbody0 The soft body actor used for the attachment + \param[in] tetIdx0 The index of a tetrahedron in the other soft body that contains the point to be attached to the soft body + \param[in] tetBarycentric0 The barycentric coordinates of the attachment point inside the tetrahedron specified by tetIdx0 + \param[in] tetIdx1 The index of a tetrahedron in the softbody's collision mesh that contains the point to be attached to the softbody0 + \param[in] tetBarycentric1 The barycentric coordinates of the attachment point inside the tetrahedron specified by tetIdx1 + \param[in] constraint The user defined cone distance limit constraint to limit the movement between tets. + \return Returns a handle that identifies the attachment created. This handle can be used to release the attachment later + */ + virtual PxU32 addSoftBodyAttachment(PxSoftBody* softbody0, PxU32 tetIdx0, const PxVec4& tetBarycentric0, PxU32 tetIdx1, const PxVec4& tetBarycentric1, + PxConeLimitedConstraint* constraint = NULL) = 0; + + /** + \brief Releases an attachment between a soft body and the other soft body. + Be aware that destroying the soft body before destroying the attachment is illegal and may cause a crash. + + This method removes a previously-created attachment between a point inside a tetrahedron of the collision mesh to a point in another soft body's tetrahedron collision mesh. + + \param[in] softbody0 The softbody actor used for the attachment. + \param[in] handle Index that identifies the attachment. This handle gets returned by the addSoftBodyAttachment when the attachment is created. + */ + virtual void removeSoftBodyAttachment(PxSoftBody* softbody0, PxU32 handle) = 0; + + /** + \brief Creates collision filter between a tetrahedron in a soft body and a triangle in a cloth. + \warning Feature under development, only for internal usage. + + \param[in] cloth The cloth actor used for collision filter + \param[in] triIdx The index of the triangle in the cloth mesh to be filtered. + \param[in] tetIdx The index of the tetrahedron in the softbody's collision mesh to be filtered. + */ + virtual void addClothFilter(PxFEMCloth* cloth, PxU32 triIdx, PxU32 tetIdx) = 0; + + /** + \brief Removes collision filter between a tetrahedron in a soft body and a triangle in a cloth. + \warning Feature under development, only for internal usage. + + \param[in] cloth The cloth actor used for collision filter + \param[in] triIdx The index of the triangle in the cloth mesh to be filtered. + \param[in] tetIdx The index of the tetrahedron in the softbody's collision mesh to be filtered. + */ + virtual void removeClothFilter(PxFEMCloth* cloth, PxU32 triIdx, PxU32 tetIdx) = 0; + + + /** + \brief Creates an attachment between a soft body and a cloth. + Be aware that destroying the rigid body before destroying the attachment is illegal and may cause a crash. + The soft body keeps track of these attachments but the cloth does not. + + This method attaches a point inside a tetrahedron of the collision mesh to a cloth. + + \warning Feature under development, only for internal usage. + + \param[in] cloth The cloth actor used for the attachment + \param[in] triIdx The index of a triangle in the cloth mesh that contains the point to be attached to the soft body + \param[in] triBarycentric The barycentric coordinates of the attachment point inside the triangle specified by triangleIdx + \param[in] tetIdx The index of a tetrahedron in the softbody's collision mesh that contains the point to be attached to the cloth + \param[in] tetBarycentric The barycentric coordinates of the attachment point inside the tetrahedron specified by tetIdx + \param[in] constraint The user defined cone distance limit constraint to limit the movement between a triangle in the fem cloth and a tet in the soft body. + \return Returns a handle that identifies the attachment created. This handle can be used to release the attachment later + */ + virtual PxU32 addClothAttachment(PxFEMCloth* cloth, PxU32 triIdx, const PxVec4& triBarycentric, PxU32 tetIdx, const PxVec4& tetBarycentric, + PxConeLimitedConstraint* constraint = NULL) = 0; + + /** + \brief Releases an attachment between a cloth and a soft body. + Be aware that destroying the cloth before destroying the attachment is illegal and may cause a crash. + The soft body keeps track of these attachments but the cloth does not. + + This method removes a previously-created attachment between a point inside a collision mesh tetrahedron and a point inside a cloth mesh. + + \warning Feature under development, only for internal usage. + + \param[in] cloth The cloth actor used for the attachment + \param[in] handle Index that identifies the attachment. This handle gets returned by the addClothAttachment when the attachment is created + */ + virtual void removeClothAttachment(PxFEMCloth* cloth, PxU32 handle) = 0; + + /** + \brief Access to the vertices of the simulation mesh on the host + + Each element uses 4 float values containing position and inverseMass per vertex [x, y, z, inverseMass] + The inverse mass must match the inverse mass in the simVelocityCPU buffer at the same index. A copy of this value + is stored in the simVelocityCPU buffer to allow for faster access on the GPU. If the inverse masses in those two buffers + don't match, the simulation may produce wrong results + + Allows to access the CPU buffer of the simulation mesh's vertices + + \return The buffer that contains the simulation mesh's vertex positions (x, y, z) and the inverse mass as 4th component + */ + virtual PxBuffer* getSimPositionInvMassCPU() = 0; + + /** + \brief Access to the vertices of the simulation mesh on the host + + Each element uses 4 float values containing position and inverseMass per vertex [x, y, z, inverseMass] + The inverse mass must match the inverse mass in the simVelocityCPU buffer at the same index. A copy of this value + is stored in the simVelocityCPU buffer to allow for faster access on the GPU. If the inverse masses in those two buffers + don't match, the simulation may produce wrong results + + Allows to access the CPU buffer of the simulation mesh's vertices + + \return The buffer that contains the simulation mesh's vertex positions (x, y, z) and the inverse mass as 4th component + */ + virtual PxBuffer* getKinematicTargetCPU() = 0; + /** + \brief Access to the velocities of the simulation mesh on the host + + Each element uses 4 float values containing velocity and inverseMass per vertex [x, y, z, inverseMass] + The inverse mass must match the inverse mass in the simPositionInvMassCPU buffer at the same index. A copy of this value + is stored in the simPositionInvMassCPU buffer to allow for faster access on the GPU. If the inverse masses in those two buffers + don't match, the simulation may produce wrong results + + Allows to access the CPU buffer of the simulation mesh's vertices + + \return The buffer that contains the simulation mesh's velocities (x, y, z) and the inverse mass as 4th component + */ + virtual PxBuffer* getSimVelocityInvMassCPU() = 0; + + /** + \brief Access to the vertices of the collision mesh on the host + + Each element uses 4 float values containing position and inverseMass per vertex [x, y, z, inverseMass] + The inverse mass on the collision mesh has no effect, it can be set to an arbitrary value. + + Allows to access the CPU buffer of the collision mesh's vertices + + \return The buffer that contains the collision mesh's vertex positions (x, y, z) and the inverse mass as 4th component + */ + virtual PxBuffer* getPositionInvMassCPU() = 0; + + /** + \brief Access to the rest vertices of the collision mesh on the host + + Each element uses 4 float values containing position and inverseMass per vertex [x, y, z, inverseMass] + The inverse mass on the collision mesh has no effect, it can be set to an arbitrary value. + + Allows to access the CPU buffer of the collision mesh's rest vertices + + \return The buffer that contains the collision mesh's rest vertex positions (x, y, z) and the inverse mass as 4th component + */ + virtual PxBuffer* getRestPositionInvMassCPU() = 0; + + /** + \brief Retrieves the axis aligned bounding box enclosing the soft body. + + \note It is not allowed to use this method while the simulation is running (except during PxScene::collide(), + in PxContactModifyCallback or in contact report callbacks). + + \param[in] inflation Scale factor for computed world bounds. Box extents are multiplied by this value. + + \return The soft body's bounding box. + + @see PxBounds3 + */ + virtual PxBounds3 getWorldBounds(float inflation = 1.01f) const = 0; + + /** + \brief Returns the GPU soft body index. + + \return The GPU index, or 0xFFFFFFFF if the soft body is not in a scene. + */ + virtual PxU32 getGpuSoftBodyIndex() = 0; + + virtual const char* getConcreteTypeName() const PX_OVERRIDE { return "PxSoftBody"; } + + + protected: + PX_INLINE PxSoftBody(PxType concreteType, PxBaseFlags baseFlags) : PxActor(concreteType, baseFlags) {} + PX_INLINE PxSoftBody(PxBaseFlags baseFlags) : PxActor(baseFlags) {} + virtual bool isKindOf(const char* name) const PX_OVERRIDE { return !::strcmp("PxSoftBody", name) || PxActor::isKindOf(name); } + }; + +#if PX_VC +#pragma warning(pop) +#endif + + +#if !PX_DOXYGEN +} // namespace physx +#endif + + /** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/PxSoftBodyFlag.h b/Source/ThirdParty/PhysX/PxSoftBodyFlag.h new file mode 100644 index 000000000..ce19e5d67 --- /dev/null +++ b/Source/ThirdParty/PhysX/PxSoftBodyFlag.h @@ -0,0 +1,67 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_SOFT_BODY_FLAG_H +#define PX_SOFT_BODY_FLAG_H + +#include "PxPhysXConfig.h" +#include "foundation/PxFlags.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + /** + \brief These flags determine what data is read or written to the gpu softbody. + + @see PxScene::copySoftBodyData, PxScene::applySoftBodyData + */ + class PxSoftBodyDataFlag + { + public: + enum Enum + { + eTET_INDICES = 0, //!< The collision mesh tetrahedron indices (quadruples of int32) + eTET_STRESS = 1, //!< The collision mesh cauchy stress tensors (float 3x3 matrices) + eTET_STRESSCOEFF = 2, //!< The collision mesh tetrahedron von Mises stress (float scalar) + eTET_REST_POSES = 3, //!< The collision mesh tetrahedron rest poses (float 3x3 matrices) + eTET_ROTATIONS = 4, //!< The collision mesh tetrahedron orientations (quaternions, quadruples of float) + eTET_POSITION_INV_MASS = 5, //!< The collision mesh vertex positions and their inverted mass in the 4th component (quadruples of float) + eSIM_TET_INDICES = 6, //!< The simulation mesh tetrahedron indices (quadruples of int32) + eSIM_VELOCITY_INV_MASS = 7, //!< The simulation mesh vertex velocities and their inverted mass in the 4th component (quadruples of float) + eSIM_POSITION_INV_MASS = 8, //!< The simulation mesh vertex positions and their inverted mass in the 4th component (quadruples of float) + eSIM_KINEMATIC_TARGET = 9 //!< The simulation mesh kinematic target positions + }; + }; + +#if !PX_DOXYGEN +} +#endif + +#endif diff --git a/Source/ThirdParty/PhysX/PxSparseGridParams.h b/Source/ThirdParty/PhysX/PxSparseGridParams.h new file mode 100644 index 000000000..c836804ea --- /dev/null +++ b/Source/ThirdParty/PhysX/PxSparseGridParams.h @@ -0,0 +1,119 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_SPARSE_GRID_PARAMS_H +#define PX_SPARSE_GRID_PARAMS_H +/** \addtogroup physics +@{ */ + +#include "foundation/PxSimpleTypes.h" +#include "foundation/PxMath.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + /** + \brief Parameters to define the sparse grid settings like grid spacing, maximal number of subgrids etc. + */ + struct PxSparseGridParams + { + /** + \brief Default constructor. + */ + PX_INLINE PxSparseGridParams() + { + maxNumSubgrids = 512; + subgridSizeX = 32; + subgridSizeY = 32; + subgridSizeZ = 32; + gridSpacing = 0.2f; + haloSize = 1; + } + + /** + \brief Copy constructor. + */ + PX_CUDA_CALLABLE PX_INLINE PxSparseGridParams(const PxSparseGridParams& params) + { + maxNumSubgrids = params.maxNumSubgrids; + subgridSizeX = params.subgridSizeX; + subgridSizeY = params.subgridSizeY; + subgridSizeZ = params.subgridSizeZ; + gridSpacing = params.gridSpacing; + haloSize = params.haloSize; + } + + PX_CUDA_CALLABLE PX_INLINE PxU32 getNumCellsPerSubgrid() const + { + return subgridSizeX * subgridSizeY * subgridSizeZ; + } + + PX_CUDA_CALLABLE PX_INLINE PxReal getSqrt3dx() const + { + return PxSqrt(3.0f) * gridSpacing; + } + + + /** + \brief (re)sets the structure to the default. + */ + PX_INLINE void setToDefault() + { + *this = PxSparseGridParams(); + } + + /** + \brief Assignment operator + */ + PX_INLINE void operator = (const PxSparseGridParams& params) + { + maxNumSubgrids = params.maxNumSubgrids; + subgridSizeX = params.subgridSizeX; + subgridSizeY = params.subgridSizeY; + subgridSizeZ = params.subgridSizeZ; + gridSpacing = params.gridSpacing; + haloSize = params.haloSize; + } + + PxU32 maxNumSubgrids; //!< Maximum number of subgrids + PxReal gridSpacing; //!< Grid spacing for the grid + PxU16 subgridSizeX; //!< Subgrid resolution in x dimension (must be an even number) + PxU16 subgridSizeY; //!< Subgrid resolution in y dimension (must be an even number) + PxU16 subgridSizeZ; //!< Subgrid resolution in z dimension (must be an even number) + PxU16 haloSize; //!< Number of halo cell layers around every subgrid cell. Only 0 and 1 are valid values + }; + + +#if !PX_DOXYGEN +} // namespace physx +#endif + + /** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/PxVisualizationParameter.h b/Source/ThirdParty/PhysX/PxVisualizationParameter.h index c05724b27..175f3f048 100644 --- a/Source/ThirdParty/PhysX/PxVisualizationParameter.h +++ b/Source/ThirdParty/PhysX/PxVisualizationParameter.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_NX_DEBUG_VISUALIZATION_PARAMETER -#define PX_PHYSICS_NX_DEBUG_VISUALIZATION_PARAMETER +#ifndef PX_VISUALIZATION_PARAMETER_H +#define PX_VISUALIZATION_PARAMETER_H #include "foundation/PxPreprocessor.h" @@ -92,7 +90,6 @@ struct PxVisualizationParameter */ eSCALE, - /** \brief Visualize the world axes. */ @@ -132,7 +129,6 @@ struct PxVisualizationParameter */ eBODY_ANG_VELOCITY, - /* Contact visualisations */ /** @@ -155,7 +151,6 @@ struct PxVisualizationParameter */ eCONTACT_FORCE, - /** \brief Visualize actor axes. @@ -163,7 +158,6 @@ struct PxVisualizationParameter */ eACTOR_AXES, - /** \brief Visualize bounds (AABBs in world space) */ @@ -212,11 +206,6 @@ struct PxVisualizationParameter */ eCOLLISION_DYNAMIC, - /** - \brief Visualizes pairwise state. - */ - eDEPRECATED_COLLISION_PAIRS, - /** \brief Joint local axes */ @@ -237,6 +226,16 @@ struct PxVisualizationParameter */ eMBP_REGIONS, + /** + \brief Renders the simulation mesh instead of the collision mesh (only available for tetmeshes) + */ + eSIMULATION_MESH, + + /** + \brief Renders the SDF of a mesh instead of the collision mesh (only available for triangle meshes with SDFs) + */ + eSDF, + /** \brief This is not a parameter, it just records the current number of parameters (as maximum(PxVisualizationParameter)+1) for use in loops. */ diff --git a/Source/ThirdParty/PhysX/characterkinematic/PxBoxController.h b/Source/ThirdParty/PhysX/characterkinematic/PxBoxController.h index 533600b43..5ba8e54e5 100644 --- a/Source/ThirdParty/PhysX/characterkinematic/PxBoxController.h +++ b/Source/ThirdParty/PhysX/characterkinematic/PxBoxController.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_CCT_BOX_CONTROLLER -#define PX_PHYSICS_CCT_BOX_CONTROLLER +#ifndef PX_BOX_CONTROLLER_H +#define PX_BOX_CONTROLLER_H /** \addtogroup character @{ */ diff --git a/Source/ThirdParty/PhysX/characterkinematic/PxCapsuleController.h b/Source/ThirdParty/PhysX/characterkinematic/PxCapsuleController.h index cd95d7b6f..28e4e1ecc 100644 --- a/Source/ThirdParty/PhysX/characterkinematic/PxCapsuleController.h +++ b/Source/ThirdParty/PhysX/characterkinematic/PxCapsuleController.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_CCT_CAPSULE_CONTROLLER -#define PX_PHYSICS_CCT_CAPSULE_CONTROLLER +#ifndef PX_CAPSULE_CONTROLLER_H +#define PX_CAPSULE_CONTROLLER_H /** \addtogroup character @{ */ diff --git a/Source/ThirdParty/PhysX/characterkinematic/PxController.h b/Source/ThirdParty/PhysX/characterkinematic/PxController.h index 3d263bc3f..ee64b3d5a 100644 --- a/Source/ThirdParty/PhysX/characterkinematic/PxController.h +++ b/Source/ThirdParty/PhysX/characterkinematic/PxController.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PX_PHYSICS_CCT_CONTROLLER -#define PX_PHYSICS_CCT_CONTROLLER +#ifndef PX_CONTROLLER_H +#define PX_CONTROLLER_H /** \addtogroup character @{ */ @@ -119,14 +118,14 @@ PX_FLAGS_OPERATORS(PxControllerCollisionFlag::Enum, PxU8) */ struct PxControllerState { - PxVec3 deltaXP; //!< delta position vector for the object the CCT is standing/riding on. Not always match the CCT delta when variable timesteps are used. - PxShape* touchedShape; //!< Shape on which the CCT is standing - PxRigidActor* touchedActor; //!< Actor owning 'touchedShape' - ObstacleHandle touchedObstacleHandle; // Obstacle on which the CCT is standing - PxU32 collisionFlags; //!< Last known collision flags (PxControllerCollisionFlag) - bool standOnAnotherCCT; //!< Are we standing on another CCT? - bool standOnObstacle; //!< Are we standing on a user-defined obstacle? - bool isMovingUp; //!< is CCT moving up or not? (i.e. explicit jumping) + PxVec3 deltaXP; //!< delta position vector for the object the CCT is standing/riding on. Not always match the CCT delta when variable timesteps are used. + PxShape* touchedShape; //!< Shape on which the CCT is standing + PxRigidActor* touchedActor; //!< Actor owning 'touchedShape' + PxObstacleHandle touchedObstacleHandle; // Obstacle on which the CCT is standing + PxU32 collisionFlags; //!< Last known collision flags (PxControllerCollisionFlag) + bool standOnAnotherCCT; //!< Are we standing on another CCT? + bool standOnObstacle; //!< Are we standing on a user-defined obstacle? + bool isMovingUp; //!< is CCT moving up or not? (i.e. explicit jumping) }; /** @@ -506,6 +505,15 @@ public: */ bool registerDeletionListener; + /** + \brief Client ID for associated actor. + + @see PxClientID PxActor::setOwnerClient + + Default: PX_DEFAULT_CLIENT + */ + PxClientID clientID; + /** \brief User specified data associated with the controller. @@ -535,26 +543,26 @@ protected: PX_INLINE void copy(const PxControllerDesc&); }; -PX_INLINE PxControllerDesc::PxControllerDesc(PxControllerShapeType::Enum t) : mType(t) +PX_INLINE PxControllerDesc::PxControllerDesc(PxControllerShapeType::Enum t) : + position (PxExtended(0.0), PxExtended(0.0), PxExtended(0.0)), + upDirection (0.0f, 1.0f, 0.0f), + slopeLimit (0.707f), + invisibleWallHeight (0.0f), + maxJumpHeight (0.0f), + contactOffset (0.1f), + stepOffset (0.5f), + density (10.0f), + scaleCoeff (0.8f), + volumeGrowth (1.5f), + reportCallback (NULL), + behaviorCallback (NULL), + nonWalkableMode (PxControllerNonWalkableMode::ePREVENT_CLIMBING), + material (NULL), + registerDeletionListener (true), + clientID (PX_DEFAULT_CLIENT), + userData (NULL), + mType (t) { - upDirection = PxVec3(0.0f, 1.0f, 0.0f); - slopeLimit = 0.707f; - contactOffset = 0.1f; - stepOffset = 0.5f; - density = 10.0f; - scaleCoeff = 0.8f; - volumeGrowth = 1.5f; - reportCallback = NULL; - behaviorCallback = NULL; - userData = NULL; - nonWalkableMode = PxControllerNonWalkableMode::ePREVENT_CLIMBING; - position.x = PxExtended(0.0); - position.y = PxExtended(0.0); - position.z = PxExtended(0.0); - material = NULL; - invisibleWallHeight = 0.0f; - maxJumpHeight = 0.0f; - registerDeletionListener = true; } PX_INLINE PxControllerDesc::PxControllerDesc(const PxControllerDesc& other) : mType(other.mType) @@ -588,6 +596,7 @@ PX_INLINE void PxControllerDesc::copy(const PxControllerDesc& other) invisibleWallHeight = other.invisibleWallHeight; maxJumpHeight = other.maxJumpHeight; registerDeletionListener = other.registerDeletionListener; + clientID = other.clientID; } PX_INLINE PxControllerDesc::~PxControllerDesc() @@ -760,7 +769,7 @@ public: \param[in] flag The new value of the non-walkable mode. - \see PxControllerNonWalkableMode + @see PxControllerNonWalkableMode */ virtual void setNonWalkableMode(PxControllerNonWalkableMode::Enum flag) = 0; @@ -769,7 +778,7 @@ public: \return The current non-walkable mode. - \see PxControllerNonWalkableMode + @see PxControllerNonWalkableMode */ virtual PxControllerNonWalkableMode::Enum getNonWalkableMode() const = 0; diff --git a/Source/ThirdParty/PhysX/characterkinematic/PxControllerBehavior.h b/Source/ThirdParty/PhysX/characterkinematic/PxControllerBehavior.h index ea5ac3bb5..4c9aa475b 100644 --- a/Source/ThirdParty/PhysX/characterkinematic/PxControllerBehavior.h +++ b/Source/ThirdParty/PhysX/characterkinematic/PxControllerBehavior.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PX_PHYSICS_CCT_BEHAVIOR -#define PX_PHYSICS_CCT_BEHAVIOR +#ifndef PX_CONTROLLER_BEHAVIOR_H +#define PX_CONTROLLER_BEHAVIOR_H /** \addtogroup character @{ */ diff --git a/Source/ThirdParty/PhysX/characterkinematic/PxControllerManager.h b/Source/ThirdParty/PhysX/characterkinematic/PxControllerManager.h index 8accda39e..76c30e775 100644 --- a/Source/ThirdParty/PhysX/characterkinematic/PxControllerManager.h +++ b/Source/ThirdParty/PhysX/characterkinematic/PxControllerManager.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_CCT_MANAGER -#define PX_PHYSICS_CCT_MANAGER +#ifndef PX_CONTROLLER_MANAGER_H +#define PX_CONTROLLER_MANAGER_H /** \addtogroup character @{ */ @@ -296,4 +294,5 @@ protected: PX_C_EXPORT physx::PxControllerManager* PX_CALL_CONV PxCreateControllerManager(physx::PxScene& scene, bool lockingEnabled = false); /** @} */ -#endif //PX_PHYSICS_CCT_MANAGER +#endif + diff --git a/Source/ThirdParty/PhysX/characterkinematic/PxControllerObstacles.h b/Source/ThirdParty/PhysX/characterkinematic/PxControllerObstacles.h index b54a72cf0..7f438fcc3 100644 --- a/Source/ThirdParty/PhysX/characterkinematic/PxControllerObstacles.h +++ b/Source/ThirdParty/PhysX/characterkinematic/PxControllerObstacles.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PX_PHYSICS_CCT_OBSTACLES -#define PX_PHYSICS_CCT_OBSTACLES +#ifndef PX_CONTROLLER_OBSTACLES_H +#define PX_CONTROLLER_OBSTACLES_H /** \addtogroup character @{ */ @@ -43,7 +42,7 @@ namespace physx class PxControllerManager; - #define INVALID_OBSTACLE_HANDLE 0xffffffff + #define PX_INVALID_OBSTACLE_HANDLE 0xffffffff /** \brief Base class for obstacles. @@ -102,7 +101,7 @@ namespace physx PxReal mRadius; }; - typedef PxU32 ObstacleHandle; + typedef PxU32 PxObstacleHandle; /** \brief Context class for obstacles. @@ -136,7 +135,7 @@ namespace physx \return Handle for newly-added obstacle */ - virtual ObstacleHandle addObstacle(const PxObstacle& obstacle) = 0; + virtual PxObstacleHandle addObstacle(const PxObstacle& obstacle) = 0; /** \brief Removes an obstacle from the context. @@ -145,7 +144,7 @@ namespace physx \return True if success */ - virtual bool removeObstacle(ObstacleHandle handle) = 0; + virtual bool removeObstacle(PxObstacleHandle handle) = 0; /** \brief Updates data for an existing obstacle. @@ -155,7 +154,7 @@ namespace physx \return True if success */ - virtual bool updateObstacle(ObstacleHandle handle, const PxObstacle& obstacle) = 0; + virtual bool updateObstacle(PxObstacleHandle handle, const PxObstacle& obstacle) = 0; /** \brief Retrieves number of obstacles in the context. @@ -180,7 +179,7 @@ namespace physx \return Desired obstacle */ - virtual const PxObstacle* getObstacleByHandle(ObstacleHandle handle) const = 0; + virtual const PxObstacle* getObstacleByHandle(PxObstacleHandle handle) const = 0; }; #if !PX_DOXYGEN diff --git a/Source/ThirdParty/PhysX/characterkinematic/PxExtended.h b/Source/ThirdParty/PhysX/characterkinematic/PxExtended.h index 6759c296c..1bc75ebf9 100644 --- a/Source/ThirdParty/PhysX/characterkinematic/PxExtended.h +++ b/Source/ThirdParty/PhysX/characterkinematic/PxExtended.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_CCT_EXTENDED -#define PX_PHYSICS_CCT_EXTENDED +#ifndef PX_EXTENDED_H +#define PX_EXTENDED_H /** \addtogroup character @{ */ diff --git a/Source/ThirdParty/PhysX/collision/PxCollisionDefs.h b/Source/ThirdParty/PhysX/collision/PxCollisionDefs.h index 5923d0953..134c61c8d 100644 --- a/Source/ThirdParty/PhysX/collision/PxCollisionDefs.h +++ b/Source/ThirdParty/PhysX/collision/PxCollisionDefs.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,61 +22,67 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - #ifndef PX_COLLISION_DEFS_H #define PX_COLLISION_DEFS_H #include "PxPhysXConfig.h" -#include "foundation/PxVec3.h" -#include "foundation/PxMat33.h" -#include "geomutils/GuContactPoint.h" -#include "geomutils/GuContactBuffer.h" -#include "geometry/PxGeometry.h" +#include "foundation/PxSimpleTypes.h" #if !PX_DOXYGEN namespace physx { #endif +/** +\brief A callback class to allocate memory to cache information used in contact generation. +*/ +class PxCacheAllocator +{ +public: /** - \brief A structure to cache contact information produced by LL contact gen functions. + \brief Allocates cache data for contact generation. This data is stored inside PxCache objects. + The application can retain and provide this information for future contact generation passes + for a given pair to improve contact generation performance. It is the application's responsibility + to release this memory appropriately. If the memory is released, the application must ensure that + this memory is no longer referenced by any PxCache objects passed to PxGenerateContacts. + + \param byteSize [in] size of the allocation in bytes + + \return the newly-allocated memory. The returned address must be 16-byte aligned. + + @see PxCache, PxGenerateContacts */ - struct PxCache + virtual PxU8* allocateCacheData(const PxU32 byteSize) = 0; + + virtual ~PxCacheAllocator() {} +}; + +/** +\brief A structure to cache contact information produced by low-level contact generation functions. +*/ +struct PxCache +{ + PxU8* mCachedData; //!< Cached data pointer. Allocated via PxCacheAllocator + PxU16 mCachedSize; //!< The total size of the cached data + PxU8 mPairData; //!< Pair data information used and cached internally by some contact generation functions to accelerate performance. + PxU8 mManifoldFlags; //!< Manifold flags used to identify the format the cached data is stored in. @see Gu::ManifoldFlags + + PX_FORCE_INLINE PxCache() : mCachedData(NULL), mCachedSize(0), mPairData(0), mManifoldFlags(0) { - PxU8* mCachedData; //!< Cached data pointer. Allocated via PxCacheAllocator - PxU16 mCachedSize; //!< The total size of the cached data - PxU8 mPairData; //!< Pair data information used and cached internally by some contact gen functions to accelerate performance. - PxU8 mManifoldFlags; //!< Manifold flags used to identify the format the cached data is stored in. + } - PX_FORCE_INLINE PxCache() : mCachedData(NULL), mCachedSize(0), mPairData(0), mManifoldFlags(0) - { - } - - PX_FORCE_INLINE void reset() { mCachedData = NULL; mCachedSize = 0; mPairData = 0; mManifoldFlags = 0;} - }; - - - /** - A callback class to allocate memory to cache information used in contact generation. - */ - class PxCacheAllocator + PX_FORCE_INLINE void reset() { - public: - /** - \brief Allocates cache data for contact generation. This data is stored inside PxCache objects. The application can retain and provide this information for future contact generation passes - for a given pair to improve contact generation performance. It is the application's responsibility to release this memory appropriately. If the memory is released, the application must ensure that - this memory is no longer referenced by any PxCache objects passed to PxGenerateContacts. - \param byteSize The size of the allocation in bytes - \return the newly-allocated memory. The returned address must be 16-byte aligned. - */ - virtual PxU8* allocateCacheData(const PxU32 byteSize) = 0; - - virtual ~PxCacheAllocator() {} - }; + mCachedData = NULL; + mCachedSize = 0; + mPairData = 0; + mManifoldFlags = 0; + } +}; #if !PX_DOXYGEN } diff --git a/Source/ThirdParty/PhysX/common/PxBase.h b/Source/ThirdParty/PhysX/common/PxBase.h index cc4f8797f..f16cd907a 100644 --- a/Source/ThirdParty/PhysX/common/PxBase.h +++ b/Source/ThirdParty/PhysX/common/PxBase.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_PX_BASE -#define PX_PHYSICS_PX_BASE +#ifndef PX_BASE_H +#define PX_BASE_H /** \addtogroup common @{ @@ -40,6 +38,7 @@ #include "common/PxCollection.h" #include "common/PxTypeInfo.h" #include // For strcmp +#include "foundation/PxAssert.h" #if !PX_DOXYGEN namespace physx @@ -55,8 +54,8 @@ struct PxBaseFlag { enum Enum { - eOWNS_MEMORY = (1<<0), - eIS_RELEASABLE = (1<<1) + eOWNS_MEMORY = (1<<0), + eIS_RELEASABLE = (1<<1) }; }; @@ -82,13 +81,13 @@ public: /** \brief Releases the PxBase instance, please check documentation of release in derived class. */ - virtual void release() = 0; + virtual void release() = 0; /** \brief Returns string name of dynamic type. \return Class name of most derived type of this object. */ - virtual const char* getConcreteTypeName() const = 0; + virtual const char* getConcreteTypeName() const = 0; /* brief Implements dynamic cast functionality. @@ -98,7 +97,7 @@ public: \return A pointer to the specified type if object matches, otherwise NULL */ - template T* is() { return typeMatch() ? static_cast(this) : NULL; } + template T* is() { return typeMatch() ? static_cast(this) : NULL; } /* brief Implements dynamic cast functionality for const objects. @@ -108,7 +107,7 @@ public: \return A pointer to the specified type if object matches, otherwise NULL */ - template const T* is() const { return typeMatch() ? static_cast(this) : NULL; } + template const T* is() const { return typeMatch() ? static_cast(this) : NULL; } /** \brief Returns concrete type of object. @@ -116,7 +115,7 @@ public: @see PxConcreteType */ - PX_FORCE_INLINE PxType getConcreteType() const { return mConcreteType; } + PX_FORCE_INLINE PxType getConcreteType() const { return mConcreteType; } /** \brief Set PxBaseFlag @@ -124,7 +123,7 @@ public: \param[in] flag The flag to be set \param[in] value The flags new value */ - PX_FORCE_INLINE void setBaseFlag(PxBaseFlag::Enum flag, bool value) { mBaseFlags = value ? mBaseFlags|flag : mBaseFlags&~flag; } + PX_FORCE_INLINE void setBaseFlag(PxBaseFlag::Enum flag, bool value) { mBaseFlags = value ? mBaseFlags|flag : mBaseFlags&~flag; } /** \brief Set PxBaseFlags @@ -133,7 +132,7 @@ public: @see PxBaseFlags */ - PX_FORCE_INLINE void setBaseFlags(PxBaseFlags inFlags) { mBaseFlags = inFlags; } + PX_FORCE_INLINE void setBaseFlags(PxBaseFlags inFlags) { mBaseFlags = inFlags; } /** \brief Returns PxBaseFlags @@ -142,7 +141,7 @@ public: @see PxBaseFlags */ - PX_FORCE_INLINE PxBaseFlags getBaseFlags() const { return mBaseFlags; } + PX_FORCE_INLINE PxBaseFlags getBaseFlags() const { return mBaseFlags; } /** \brief Whether the object is subordinate. @@ -153,44 +152,83 @@ public: @see PxSerialization::isSerializable */ - virtual bool isReleasable() const { return mBaseFlags & PxBaseFlag::eIS_RELEASABLE; } + virtual bool isReleasable() const { return mBaseFlags & PxBaseFlag::eIS_RELEASABLE; } protected: /** \brief Constructor setting concrete type and base flags. */ - PX_INLINE PxBase(PxType concreteType, PxBaseFlags baseFlags) - : mConcreteType(concreteType), mBaseFlags(baseFlags) {} + PX_INLINE PxBase(PxType concreteType, PxBaseFlags baseFlags) + : mConcreteType(concreteType), mBaseFlags(baseFlags), mBuiltInRefCount(1) {} /** \brief Deserialization constructor setting base flags. */ - PX_INLINE PxBase(PxBaseFlags baseFlags) : mBaseFlags(baseFlags) {} - + PX_INLINE PxBase(PxBaseFlags baseFlags) : mBaseFlags(baseFlags) + { + PX_ASSERT(mBuiltInRefCount == 1); + } /** \brief Destructor. */ - virtual ~PxBase() {} + virtual ~PxBase() {} /** \brief Returns whether a given type name matches with the type of this instance */ - virtual bool isKindOf(const char* superClass) const { return !::strcmp(superClass, "PxBase"); } - - template bool typeMatch() const - { - return PxU32(PxTypeInfo::eFastTypeId)!=PxU32(PxConcreteType::eUNDEFINED) ? - PxU32(getConcreteType()) == PxU32(PxTypeInfo::eFastTypeId) : isKindOf(PxTypeInfo::name()); - } + virtual bool isKindOf(const char* superClass) const { return !::strcmp(superClass, "PxBase"); } + template bool typeMatch() const + { + return PxU32(PxTypeInfo::eFastTypeId)!=PxU32(PxConcreteType::eUNDEFINED) ? + PxU32(getConcreteType()) == PxU32(PxTypeInfo::eFastTypeId) : isKindOf(PxTypeInfo::name()); + } private: - friend void getBinaryMetaData_PxBase(PxOutputStream& stream); + friend void getBinaryMetaData_PxBase(PxOutputStream& stream); protected: - PxType mConcreteType; // concrete type identifier - see PxConcreteType. - PxBaseFlags mBaseFlags; // internal flags + PxType mConcreteType; // concrete type identifier - see PxConcreteType. + PxBaseFlags mBaseFlags; // internal flags + PxU32 mBuiltInRefCount; +}; +/** +\brief Base class for ref-counted objects. +*/ +class PxRefCounted : public PxBase +{ +public: + + /** + \brief Decrements the reference count of the object and releases it if the new reference count is zero. + */ + virtual void release() = 0; + + /** + \brief Returns the reference count of the object. + + At creation, the reference count of the object is 1. Every other object referencing this object increments the + count by 1. When the reference count reaches 0, and only then, the object gets destroyed automatically. + + \return the current reference count. + */ + virtual PxU32 getReferenceCount() const = 0; + + /** + \brief Acquires a counted reference to this object. + + This method increases the reference count of the object by 1. Decrement the reference count by calling release() + */ + virtual void acquireReference() = 0; + +protected: + virtual void onRefCountZero() { delete this; } + + PX_INLINE PxRefCounted(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags) {} + PX_INLINE PxRefCounted(PxBaseFlags baseFlags) : PxBase(baseFlags) {} + virtual ~PxRefCounted() {} + virtual bool isKindOf(const char* name) const { return !::strcmp("PxRefCounted", name) || PxBase::isKindOf(name); } }; #if !PX_DOXYGEN diff --git a/Source/ThirdParty/PhysX/common/PxCollection.h b/Source/ThirdParty/PhysX/common/PxCollection.h index d9ec5cfc4..84d67e5ab 100644 --- a/Source/ThirdParty/PhysX/common/PxCollection.h +++ b/Source/ThirdParty/PhysX/common/PxCollection.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_PX_COLLECTION -#define PX_PHYSICS_PX_COLLECTION +#ifndef PX_COLLECTION_H +#define PX_COLLECTION_H #include "common/PxSerialFramework.h" @@ -272,7 +270,7 @@ For deserialization, the system gives back a collection of deserialized objects @see PxCollection, PxCollection::release() */ -PX_PHYSX_COMMON_API physx::PxCollection* PX_CALL_CONV PxCreateCollection(); +PX_C_EXPORT PX_PHYSX_COMMON_API physx::PxCollection* PX_CALL_CONV PxCreateCollection(); /** @} */ diff --git a/Source/ThirdParty/PhysX/common/PxCoreUtilityTypes.h b/Source/ThirdParty/PhysX/common/PxCoreUtilityTypes.h index 0c4d4809d..bc1ab8089 100644 --- a/Source/ThirdParty/PhysX/common/PxCoreUtilityTypes.h +++ b/Source/ThirdParty/PhysX/common/PxCoreUtilityTypes.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_CORE_UTILTY_TYPES_H -#define PX_CORE_UTILTY_TYPES_H +#ifndef PX_CORE_UTILITY_TYPES_H +#define PX_CORE_UTILITY_TYPES_H /** \addtogroup common @{ */ @@ -78,6 +76,20 @@ struct PxTypedStridedData { } + PxTypedStridedData(const TDataType* data_, PxU32 stride_ = 0) + : stride(stride_) + , data(data_) + { + } + + PX_INLINE const TDataType& at(PxU32 idx) const + { + PxU32 theStride(stride); + if (theStride == 0) + theStride = sizeof(TDataType); + PxU32 offset(theStride * idx); + return *(reinterpret_cast(reinterpret_cast(data) + offset)); + } }; struct PxBoundedData : public PxStridedData @@ -183,7 +195,7 @@ public: void clear() { - memset(mDataPairs, 0, NB_ELEMENTS*2*sizeof(PxReal)); + PxMemSet(mDataPairs, 0, NB_ELEMENTS*2*sizeof(PxReal)); mNbDataPairs = 0; } diff --git a/Source/ThirdParty/PhysX/common/PxPhysicsInsertionCallback.h b/Source/ThirdParty/PhysX/common/PxInsertionCallback.h similarity index 73% rename from Source/ThirdParty/PhysX/common/PxPhysicsInsertionCallback.h rename to Source/ThirdParty/PhysX/common/PxInsertionCallback.h index 6b29f776f..e9f373884 100644 --- a/Source/ThirdParty/PhysX/common/PxPhysicsInsertionCallback.h +++ b/Source/ThirdParty/PhysX/common/PxInsertionCallback.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_PX_PHYSICS_INSERTION_CALLBACK -#define PX_PHYSICS_PX_PHYSICS_INSERTION_CALLBACK +#ifndef PX_INSERTION_CALLBACK_H +#define PX_INSERTION_CALLBACK_H #include "common/PxBase.h" @@ -43,27 +41,25 @@ namespace physx #endif /** - - \brief Callback interface that permits PxCooking to insert a - TriangleMesh, HeightfieldMesh or ConvexMesh directly into PxPhysics without the need to store - the cooking results into a stream. - + \brief Callback interface that permits TriangleMesh, Heightfield, ConvexMesh or BVH to be used + directly without the need to store the cooking results into a stream. Using this is advised only if real-time cooking is required; using "offline" cooking and streams is otherwise preferred. - The default PxPhysicsInsertionCallback implementation must be used. The PxPhysics + The default PxInsertionCallback implementations must be used. The PxPhysics default callback can be obtained using the PxPhysics::getPhysicsInsertionCallback(). + The PxCooking default callback can be obtained using the PxCooking::getStandaloneInsertionCallback(). @see PxCooking PxPhysics */ - class PxPhysicsInsertionCallback + class PxInsertionCallback { public: - PxPhysicsInsertionCallback() {} + PxInsertionCallback() {} /** - \brief Builds object (TriangleMesh, HeightfieldMesh or ConvexMesh) from given data in PxPhysics. + \brief Builds object (TriangleMesh, Heightfield, ConvexMesh or BVH) from given data in PxPhysics. \param type Object type to build. \param data Object data @@ -72,9 +68,10 @@ namespace physx virtual PxBase* buildObjectFromData(PxConcreteType::Enum type, void* data) = 0; protected: - virtual ~PxPhysicsInsertionCallback() {} + virtual ~PxInsertionCallback() {} }; + typedef PxInsertionCallback PxPhysicsInsertionCallback; #if !PX_DOXYGEN } // namespace physx diff --git a/Source/ThirdParty/PhysX/common/PxMetaData.h b/Source/ThirdParty/PhysX/common/PxMetaData.h index 27c06d4b6..4b2e26a67 100644 --- a/Source/ThirdParty/PhysX/common/PxMetaData.h +++ b/Source/ThirdParty/PhysX/common/PxMetaData.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_METADATA_H -#define PX_PHYSICS_METADATA_H +#ifndef PX_METADATA_H +#define PX_METADATA_H /** \addtogroup physics @{ */ diff --git a/Source/ThirdParty/PhysX/common/PxMetaDataFlags.h b/Source/ThirdParty/PhysX/common/PxMetaDataFlags.h index c8718e745..f7bdebeb2 100644 --- a/Source/ThirdParty/PhysX/common/PxMetaDataFlags.h +++ b/Source/ThirdParty/PhysX/common/PxMetaDataFlags.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_METADATA_FLAGS -#define PX_PHYSICS_METADATA_FLAGS +#ifndef PX_METADATA_FLAGS_H +#define PX_METADATA_FLAGS_H #include "foundation/Px.h" diff --git a/Source/ThirdParty/PhysX/common/PxPhysXCommonConfig.h b/Source/ThirdParty/PhysX/common/PxPhysXCommonConfig.h index d2f83a0d7..2e809674a 100644 --- a/Source/ThirdParty/PhysX/common/PxPhysXCommonConfig.h +++ b/Source/ThirdParty/PhysX/common/PxPhysXCommonConfig.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_COMMON_NX -#define PX_PHYSICS_COMMON_NX +#ifndef PX_PHYSX_COMMON_CONFIG_H +#define PX_PHYSX_COMMON_CONFIG_H /** \addtogroup common @{ */ @@ -47,7 +45,7 @@ https://developercommunity.visualstudio.com/content/problem/66047/possible-compi #if defined PX_PHYSX_STATIC_LIB #define PX_PHYSX_CORE_API #else - #if (PX_WINDOWS_FAMILY || PX_XBOXONE || PX_PS4) + #if (PX_WINDOWS_FAMILY || PX_PS4 || PX_PS5) #if defined PX_PHYSX_CORE_EXPORTS #define PX_PHYSX_CORE_API __declspec(dllexport) #else @@ -85,7 +83,7 @@ https://developercommunity.visualstudio.com/content/problem/66047/possible-compi #if defined PX_PHYSX_STATIC_LIB #define PX_PHYSX_COMMON_API #else - #if (PX_WINDOWS_FAMILY || PX_XBOXONE || PX_PS4) && !defined(__CUDACC__) + #if (PX_WINDOWS_FAMILY || PX_PS4 || PX_PS5) && !defined(__CUDACC__) #if defined PX_PHYSX_COMMON_EXPORTS #define PX_PHYSX_COMMON_API __declspec(dllexport) #else @@ -98,23 +96,27 @@ https://developercommunity.visualstudio.com/content/problem/66047/possible-compi #endif #endif +// PT: typical "invalid" value in various CD algorithms +#define PX_INVALID_U32 0xffffffff +#define PX_INVALID_U16 0xffff + // Changing these parameters requires recompilation of the SDK +// Enable debug visualization +#define PX_ENABLE_DEBUG_VISUALIZATION 1 +#define PX_CATCH_UNDEFINED_ENABLE_DEBUG_VISUALIZATION + +// Enable simulation statistics generation +#define PX_ENABLE_SIM_STATS 1 +#define PX_CATCH_UNDEFINED_ENABLE_SIM_STATS + #if !PX_DOXYGEN namespace physx { #endif - class PxCollection; - class PxBase; - - class PxHeightField; - class PxHeightFieldDesc; - - class PxTriangleMesh; - class PxConvexMesh; - typedef PxU32 PxTriangleID; typedef PxU16 PxMaterialTableIndex; + typedef PxU16 PxFEMMaterialTableIndex; #if !PX_DOXYGEN } // namespace physx diff --git a/Source/ThirdParty/PhysX/common/PxProfileZone.h b/Source/ThirdParty/PhysX/common/PxProfileZone.h index 17f042940..a562940de 100644 --- a/Source/ThirdParty/PhysX/common/PxProfileZone.h +++ b/Source/ThirdParty/PhysX/common/PxProfileZone.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,13 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. -#ifndef PXFOUNDATION_PXPROFILEZONE_H -#define PXFOUNDATION_PXPROFILEZONE_H +#ifndef PX_PROFILE_ZONE_H +#define PX_PROFILE_ZONE_H #include "foundation/PxProfiler.h" -#include "PxFoundation.h" +#include "foundation/PxFoundation.h" #if PX_DEBUG || PX_CHECKED || PX_PROFILE #define PX_PROFILE_ZONE(x, y) \ @@ -48,4 +47,4 @@ #define PX_PROFILE_POINTER_TO_U64(pointer) static_cast(reinterpret_cast(pointer)) -#endif // PXFOUNDATION_PXPROFILEZONE_H +#endif diff --git a/Source/ThirdParty/PhysX/common/PxRenderBuffer.h b/Source/ThirdParty/PhysX/common/PxRenderBuffer.h index 12fb6cf35..23baf4a88 100644 --- a/Source/ThirdParty/PhysX/common/PxRenderBuffer.h +++ b/Source/ThirdParty/PhysX/common/PxRenderBuffer.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_FOUNDATION_PXRENDERBUFFER_H -#define PX_FOUNDATION_PXRENDERBUFFER_H +#ifndef PX_RENDER_BUFFER_H +#define PX_RENDER_BUFFER_H /** \addtogroup common @{ @@ -61,12 +59,13 @@ struct PxDebugColor eARGB_CYAN = 0xff00ffff, eARGB_WHITE = 0xffffffff, eARGB_GREY = 0xff808080, - eARGB_DARKRED = 0x88880000, - eARGB_DARKGREEN = 0x88008800, - eARGB_DARKBLUE = 0x88000088 + eARGB_DARKRED = 0xff880000, + eARGB_DARKGREEN = 0xff008800, + eARGB_DARKBLUE = 0xff000088 }; }; + /** \brief Used to store a single point and colour for debug rendering. */ @@ -114,17 +113,22 @@ struct PxDebugTriangle */ struct PxDebugText { - PxDebugText() : string(0) {} + PxDebugText() : string(0) + { + } - PxDebugText(const PxVec3& p, const PxReal& s, const PxU32& c, const char* str) - : position(p), size(s), color(c), string(str) {} + PxDebugText(const PxVec3& pos, const PxReal& sz, const PxU32& clr, const char* str) + : position(pos), size(sz), color(clr), string(str) + { + } - PxVec3 position; - PxReal size; - PxU32 color; - const char* string; + PxVec3 position; + PxReal size; + PxU32 color; + const char* string; }; + /** \brief Interface for points, lines, triangles, and text buffer. */ @@ -135,18 +139,24 @@ public: virtual PxU32 getNbPoints() const = 0; virtual const PxDebugPoint* getPoints() const = 0; + virtual void addPoint(const PxDebugPoint& point) = 0; virtual PxU32 getNbLines() const = 0; virtual const PxDebugLine* getLines() const = 0; + virtual void addLine(const PxDebugLine& line) = 0; + virtual PxDebugLine* reserveLines(const PxU32 nbLines) = 0; + virtual PxDebugPoint* reservePoints(const PxU32 nbLines) = 0; virtual PxU32 getNbTriangles() const = 0; virtual const PxDebugTriangle* getTriangles() const = 0; - - virtual PxU32 getNbTexts() const = 0; - virtual const PxDebugText* getTexts() const = 0; + virtual void addTriangle(const PxDebugTriangle& triangle) = 0; virtual void append(const PxRenderBuffer& other) = 0; virtual void clear() = 0; + + virtual void shift(const PxVec3& delta) = 0; + + virtual bool empty() const = 0; }; #if !PX_DOXYGEN diff --git a/Source/ThirdParty/PhysX/common/PxRenderOutput.h b/Source/ThirdParty/PhysX/common/PxRenderOutput.h new file mode 100644 index 000000000..2bc16f8c0 --- /dev/null +++ b/Source/ThirdParty/PhysX/common/PxRenderOutput.h @@ -0,0 +1,404 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_RENDER_OUTPUT_H +#define PX_RENDER_OUTPUT_H + +#include "foundation/PxMat44.h" +#include "foundation/PxBasicTemplates.h" +#include "PxRenderBuffer.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +#if PX_VC +#pragma warning(push) +#pragma warning( disable : 4251 ) // class needs to have dll-interface to be used by clients of class +#endif + + /** + Output stream to fill RenderBuffer + */ + class PX_PHYSX_COMMON_API PxRenderOutput + { + public: + + enum Primitive + { + POINTS, + LINES, + LINESTRIP, + TRIANGLES, + TRIANGLESTRIP + }; + + PxRenderOutput(PxRenderBuffer& buffer) + : mPrim(POINTS), + mColor(0), + mVertex0(0.0f), + mVertex1(0.0f), + mVertexCount(0), + mTransform(PxIdentity), + mBuffer(buffer) + { + } + + PX_INLINE PxRenderOutput& operator<<(Primitive prim); + + PX_INLINE PxRenderOutput& operator<<(PxU32 color) ; + + PX_INLINE PxRenderOutput& operator<<(const PxMat44& transform); + + PX_INLINE PxRenderOutput& operator<<(const PxTransform& t); + + PX_INLINE PxRenderOutput& operator<<(const PxVec3& vertex); //AM: Don't use this! Slow! Deprecated! + + PX_INLINE PxDebugLine* reserveSegments(PxU32 nbSegments); + + PX_INLINE PxDebugPoint* reservePoints(PxU32 nbSegments); + + PX_INLINE void outputSegment(const PxVec3& v0, const PxVec3& v1); + + PX_INLINE PxRenderOutput& outputCapsule(PxF32 radius, PxF32 halfHeight, const PxMat44& absPose); + + private: + + PxRenderOutput& operator=(const PxRenderOutput&); + + Primitive mPrim; + PxU32 mColor; + PxVec3 mVertex0, mVertex1; + PxU32 mVertexCount; + PxMat44 mTransform; + PxRenderBuffer& mBuffer; + }; + + struct PxDebugBox + { + explicit PxDebugBox(const PxVec3& extents, bool wireframe_ = true) + : minimum(-extents), maximum(extents), wireframe(wireframe_) {} + + explicit PxDebugBox(const PxVec3& pos, const PxVec3& extents, bool wireframe_ = true) + : minimum(pos - extents), maximum(pos + extents), wireframe(wireframe_) {} + + explicit PxDebugBox(const PxBounds3& bounds, bool wireframe_ = true) + : minimum(bounds.minimum), maximum(bounds.maximum), wireframe(wireframe_) {} + + PxVec3 minimum, maximum; + bool wireframe; + }; + PX_FORCE_INLINE PxRenderOutput& operator<<(PxRenderOutput& out, const PxDebugBox& box) + { + if (box.wireframe) + { + out << PxRenderOutput::LINESTRIP; + out << PxVec3(box.minimum.x, box.minimum.y, box.minimum.z); + out << PxVec3(box.maximum.x, box.minimum.y, box.minimum.z); + out << PxVec3(box.maximum.x, box.maximum.y, box.minimum.z); + out << PxVec3(box.minimum.x, box.maximum.y, box.minimum.z); + out << PxVec3(box.minimum.x, box.minimum.y, box.minimum.z); + out << PxVec3(box.minimum.x, box.minimum.y, box.maximum.z); + out << PxVec3(box.maximum.x, box.minimum.y, box.maximum.z); + out << PxVec3(box.maximum.x, box.maximum.y, box.maximum.z); + out << PxVec3(box.minimum.x, box.maximum.y, box.maximum.z); + out << PxVec3(box.minimum.x, box.minimum.y, box.maximum.z); + out << PxRenderOutput::LINES; + out << PxVec3(box.maximum.x, box.minimum.y, box.minimum.z); + out << PxVec3(box.maximum.x, box.minimum.y, box.maximum.z); + out << PxVec3(box.maximum.x, box.maximum.y, box.minimum.z); + out << PxVec3(box.maximum.x, box.maximum.y, box.maximum.z); + out << PxVec3(box.minimum.x, box.maximum.y, box.minimum.z); + out << PxVec3(box.minimum.x, box.maximum.y, box.maximum.z); + } + else + { + out << PxRenderOutput::TRIANGLESTRIP; + out << PxVec3(box.minimum.x, box.minimum.y, box.minimum.z); // 0 + out << PxVec3(box.minimum.x, box.maximum.y, box.minimum.z); // 2 + out << PxVec3(box.maximum.x, box.minimum.y, box.minimum.z); // 1 + out << PxVec3(box.maximum.x, box.maximum.y, box.minimum.z); // 3 + out << PxVec3(box.maximum.x, box.maximum.y, box.maximum.z); // 7 + out << PxVec3(box.minimum.x, box.maximum.y, box.minimum.z); // 2 + out << PxVec3(box.minimum.x, box.maximum.y, box.maximum.z); // 6 + out << PxVec3(box.minimum.x, box.minimum.y, box.minimum.z); // 0 + out << PxVec3(box.minimum.x, box.minimum.y, box.maximum.z); // 4 + out << PxVec3(box.maximum.x, box.minimum.y, box.minimum.z); // 1 + out << PxVec3(box.maximum.x, box.minimum.y, box.maximum.z); // 5 + out << PxVec3(box.maximum.x, box.maximum.y, box.maximum.z); // 7 + out << PxVec3(box.minimum.x, box.minimum.y, box.maximum.z); // 4 + out << PxVec3(box.minimum.x, box.maximum.y, box.maximum.z); // 6 + } + return out; + } + + struct PxDebugArrow + { + PxDebugArrow(const PxVec3& pos, const PxVec3& vec) + : base(pos), tip(pos + vec), headLength(vec.magnitude()*0.15f) {} + + PxDebugArrow(const PxVec3& pos, const PxVec3& vec, PxReal headLength_) + : base(pos), tip(pos + vec), headLength(headLength_) {} + + PxVec3 base, tip; + PxReal headLength; + }; + PX_FORCE_INLINE void normalToTangents(const PxVec3& normal, PxVec3& tangent0, PxVec3& tangent1) + { + tangent0 = PxAbs(normal.x) < 0.70710678f ? PxVec3(0, -normal.z, normal.y) : PxVec3(-normal.y, normal.x, 0); + tangent0.normalize(); + tangent1 = normal.cross(tangent0); + } + PX_FORCE_INLINE PxRenderOutput& operator<<(PxRenderOutput& out, const PxDebugArrow& arrow) + { + PxVec3 t0 = arrow.tip - arrow.base, t1, t2; + + t0.normalize(); + normalToTangents(t0, t1, t2); + + const PxReal tipAngle = 0.25f; + t1 *= arrow.headLength * tipAngle; + t2 *= arrow.headLength * tipAngle * PxSqrt(3.0f); + PxVec3 headBase = arrow.tip - t0 * arrow.headLength; + + out << PxRenderOutput::LINES; + out << arrow.base << arrow.tip; + + out << PxRenderOutput::TRIANGLESTRIP; + out << arrow.tip; + out << headBase + t1 + t1; + out << headBase - t1 - t2; + out << headBase - t1 + t2; + out << arrow.tip; + out << headBase + t1 + t1; + return out; + } + + struct PxDebugBasis + { + PxDebugBasis(const PxVec3& ext, PxU32 cX = PxU32(PxDebugColor::eARGB_RED), + PxU32 cY = PxU32(PxDebugColor::eARGB_GREEN), PxU32 cZ = PxU32(PxDebugColor::eARGB_BLUE)) + : extends(ext), colorX(cX), colorY(cY), colorZ(cZ) {} + PxVec3 extends; + PxU32 colorX, colorY, colorZ; + }; + PX_FORCE_INLINE PxRenderOutput& operator<<(PxRenderOutput& out, const PxDebugBasis& basis) + { + const PxReal headLength = basis.extends.magnitude() * 0.15f; + out << basis.colorX << PxDebugArrow(PxVec3(0.0f), PxVec3(basis.extends.x, 0, 0), headLength); + out << basis.colorY << PxDebugArrow(PxVec3(0.0f), PxVec3(0, basis.extends.y, 0), headLength); + out << basis.colorZ << PxDebugArrow(PxVec3(0.0f), PxVec3(0, 0, basis.extends.z), headLength); + return out; + } + + struct PxDebugCircle + { + PxDebugCircle(PxU32 s, PxReal r) + : nSegments(s), radius(r) {} + PxU32 nSegments; + PxReal radius; + }; + PX_FORCE_INLINE PxRenderOutput& operator<<(PxRenderOutput& out, const PxDebugCircle& circle) + { + const PxF32 step = PxTwoPi / circle.nSegments; + PxF32 angle = 0; + out << PxRenderOutput::LINESTRIP; + for (PxU32 i = 0; i < circle.nSegments; i++, angle += step) + out << PxVec3(circle.radius * PxSin(angle), circle.radius * PxCos(angle), 0); + out << PxVec3(0, circle.radius, 0); + return out; + } + + struct PxDebugArc + { + PxDebugArc(PxU32 s, PxReal r, PxReal minAng, PxReal maxAng) + : nSegments(s), radius(r), minAngle(minAng), maxAngle(maxAng) {} + PxU32 nSegments; + PxReal radius; + PxReal minAngle, maxAngle; + }; + PX_FORCE_INLINE PxRenderOutput& operator<<(PxRenderOutput& out, const PxDebugArc& arc) + { + const PxF32 step = (arc.maxAngle - arc.minAngle) / arc.nSegments; + PxF32 angle = arc.minAngle; + out << PxRenderOutput::LINESTRIP; + for (PxU32 i = 0; i < arc.nSegments; i++, angle += step) + out << PxVec3(arc.radius * PxSin(angle), arc.radius * PxCos(angle), 0); + out << PxVec3(arc.radius * PxSin(arc.maxAngle), arc.radius * PxCos(arc.maxAngle), 0); + return out; + } + + PX_INLINE PxRenderOutput& PxRenderOutput::operator<<(Primitive prim) + { + mPrim = prim; + mVertexCount = 0; + return *this; + } + + PX_INLINE PxRenderOutput& PxRenderOutput::operator<<(PxU32 color) + { + mColor = color; + return *this; + } + + PX_INLINE PxRenderOutput& PxRenderOutput::operator<<(const PxMat44& transform) + { + mTransform = transform; + return *this; + } + + PX_INLINE PxRenderOutput& PxRenderOutput::operator<<(const PxTransform& t) + { + mTransform = PxMat44(t); + return *this; + } + + PX_INLINE PxRenderOutput& PxRenderOutput::operator<<(const PxVec3& vertexIn) + { + // apply transformation + const PxVec3 vertex = mTransform.transform(vertexIn); + ++mVertexCount; + + // add primitive to render buffer + switch (mPrim) + { + case POINTS: + mBuffer.addPoint(PxDebugPoint(vertex, mColor)); break; + case LINES: + if (mVertexCount == 2) + { + mBuffer.addLine(PxDebugLine(mVertex0, vertex, mColor)); + mVertexCount = 0; + } + break; + case LINESTRIP: + if (mVertexCount >= 2) + mBuffer.addLine(PxDebugLine(mVertex0, vertex, mColor)); + break; + case TRIANGLES: + if (mVertexCount == 3) + { + mBuffer.addTriangle(PxDebugTriangle(mVertex1, mVertex0, vertex, mColor)); + mVertexCount = 0; + } + break; + case TRIANGLESTRIP: + if (mVertexCount >= 3) + mBuffer.addTriangle(PxDebugTriangle( + (mVertexCount & 0x1) ? mVertex0 : mVertex1, + (mVertexCount & 0x1) ? mVertex1 : mVertex0, vertex, mColor)); + break; + } + + // cache the last 2 vertices (for strips) + if (1 < mVertexCount) + { + mVertex1 = mVertex0; + mVertex0 = vertex; + } + else + { + mVertex0 = vertex; + } + return *this; + } + + PX_INLINE PxDebugLine* PxRenderOutput::reserveSegments(PxU32 nbSegments) + { + return mBuffer.reserveLines(nbSegments); + } + + PX_INLINE PxDebugPoint* PxRenderOutput::reservePoints(PxU32 nbPoints) + { + return mBuffer.reservePoints(nbPoints); + } + + // PT: using the operators is just too slow. + PX_INLINE void PxRenderOutput::outputSegment(const PxVec3& v0, const PxVec3& v1) + { + PxDebugLine* segment = mBuffer.reserveLines(1); + segment->pos0 = v0; + segment->pos1 = v1; + segment->color0 = segment->color1 = mColor; + } + + PX_INLINE PxRenderOutput& PxRenderOutput::outputCapsule(PxF32 radius, PxF32 halfHeight, const PxMat44& absPose) + { + PxRenderOutput& out = *this; + + const PxVec3 vleft2(-halfHeight, 0.0f, 0.0f); + PxMat44 left2 = absPose; + left2.column3 += PxVec4(left2.rotate(vleft2), 0.0f); + out << left2 << PxDebugArc(100, radius, PxPi, PxTwoPi); + + PxMat44 rotPose = left2; + PxSwap(rotPose.column1, rotPose.column2); + rotPose.column1 = -rotPose.column1; + out << rotPose << PxDebugArc(100, radius, PxPi, PxTwoPi); + + PxSwap(rotPose.column0, rotPose.column2); + rotPose.column0 = -rotPose.column0; + out << rotPose << PxDebugCircle(100, radius); + + const PxVec3 vright2(halfHeight, 0.0f, 0.0f); + PxMat44 right2 = absPose; + right2.column3 += PxVec4(right2.rotate(vright2), 0.0f); + out << right2 << PxDebugArc(100, radius, 0.0f, PxPi); + + rotPose = right2; + PxSwap(rotPose.column1, rotPose.column2); + rotPose.column1 = -rotPose.column1; + out << rotPose << PxDebugArc(100, radius, 0.0f, PxPi); + + PxSwap(rotPose.column0, rotPose.column2); + rotPose.column0 = -rotPose.column0; + out << rotPose << PxDebugCircle(100, radius); + + out << absPose; + out.outputSegment(absPose.transform(PxVec3(-halfHeight, radius, 0)), + absPose.transform(PxVec3(halfHeight, radius, 0))); + out.outputSegment(absPose.transform(PxVec3(-halfHeight, -radius, 0)), + absPose.transform(PxVec3(halfHeight, -radius, 0))); + out.outputSegment(absPose.transform(PxVec3(-halfHeight, 0, radius)), + absPose.transform(PxVec3(halfHeight, 0, radius))); + out.outputSegment(absPose.transform(PxVec3(-halfHeight, 0, -radius)), + absPose.transform(PxVec3(halfHeight, 0, -radius))); + + return *this; + } + +#if PX_VC +#pragma warning(pop) +#endif + +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif diff --git a/Source/ThirdParty/PhysX/common/PxSerialFramework.h b/Source/ThirdParty/PhysX/common/PxSerialFramework.h index 0dfd0668a..22bc3c32f 100644 --- a/Source/ThirdParty/PhysX/common/PxSerialFramework.h +++ b/Source/ThirdParty/PhysX/common/PxSerialFramework.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_COMMON_NX_SERIAL_FRAMEWORK -#define PX_PHYSICS_COMMON_NX_SERIAL_FRAMEWORK +#ifndef PX_SERIAL_FRAMEWORK_H +#define PX_SERIAL_FRAMEWORK_H /** \addtogroup common @{ @@ -48,6 +46,7 @@ class PxSerializationContext; class PxRepXSerializer; class PxSerializer; class PxPhysics; +class PxCollection; //! Default serialization alignment #define PX_SERIAL_ALIGN 16 @@ -256,7 +255,7 @@ public: */ PX_INLINE void alignExtraData(PxU32 alignment = PX_SERIAL_ALIGN) { - size_t addr = reinterpret_cast(mExtraDataAddress); + size_t addr = size_t(mExtraDataAddress); addr = (addr+alignment-1)&~size_t(alignment-1); mExtraDataAddress = reinterpret_cast(addr); } @@ -271,11 +270,13 @@ protected: /** \brief Callback type for exporting binary meta data for a serializable type. +\deprecated Binary conversion and binary meta data are deprecated. + @see PxSerializationRegistry::registerBinaryMetaDataCallback \param stream Stream to store binary meta data. */ -typedef void (*PxBinaryMetaDataCallback)(PxOutputStream& stream); +typedef PX_DEPRECATED void (*PxBinaryMetaDataCallback)(PxOutputStream& stream); /** \brief Class serving as a registry for XML (RepX) and binary serializable types. @@ -319,13 +320,15 @@ public: /** \brief Register binary meta data callback + \deprecated Binary conversion and binary meta data are deprecated. + The callback is executed when calling PxSerialization::dumpBinaryMetaData. \param callback PxBinaryMetaDataCallback to be registered. @see PxBinaryMetaDataCallback, PxSerialization::dumpBinaryMetaData */ - virtual void registerBinaryMetaDataCallback(PxBinaryMetaDataCallback callback) = 0; + PX_DEPRECATED virtual void registerBinaryMetaDataCallback(PxBinaryMetaDataCallback callback) = 0; /** \brief Returns PxSerializer corresponding to type diff --git a/Source/ThirdParty/PhysX/common/PxSerializer.h b/Source/ThirdParty/PhysX/common/PxSerializer.h index b68b302cd..538f937c3 100644 --- a/Source/ThirdParty/PhysX/common/PxSerializer.h +++ b/Source/ThirdParty/PhysX/common/PxSerializer.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,11 +22,10 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - #ifndef PX_SERIALIZER_H #define PX_SERIALIZER_H /** \addtogroup extensions @@ -36,9 +34,9 @@ #include "foundation/PxAssert.h" #include "foundation/PxAllocatorCallback.h" +#include "foundation/PxFoundation.h" #include "common/PxSerialFramework.h" #include "common/PxCollection.h" -#include "PxFoundation.h" #if !PX_DOXYGEN @@ -193,7 +191,7 @@ public: virtual void exportData(PxBase& obj, PxSerializationContext& s) const { - PxAllocatorCallback& allocator = PxGetFoundation().getAllocatorCallback(); + PxAllocatorCallback& allocator = *PxGetAllocatorCallback(); T* copy = reinterpret_cast(allocator.allocate(sizeof(T), "TmpAllocExportData", __FILE__, __LINE__)); PxMemCopy(copy, &obj, sizeof(T)); copy->preExportDataReset(); @@ -248,14 +246,14 @@ private: Note: that the allocator used for creation needs to match with the one used in PX_DELETE_SERIALIZER_ADAPTER. */ #define PX_NEW_SERIALIZER_ADAPTER(x) \ - *new( PxGetFoundation().getAllocatorCallback().allocate(sizeof(PxSerializerDefaultAdapter), \ + *new( PxGetAllocatorCallback()->allocate(sizeof(PxSerializerDefaultAdapter), \ "PxSerializerDefaultAdapter", __FILE__, __LINE__ )) PxSerializerDefaultAdapter(#x) /** \brief Preprocessor Macro to simplify adapter deletion. */ #define PX_DELETE_SERIALIZER_ADAPTER(x) \ - { PxSerializer* s = x; if (s) { s->~PxSerializer(); PxGetFoundation().getAllocatorCallback().deallocate(s); } } + { PxSerializer* s = x; if (s) { s->~PxSerializer(); PxGetAllocatorCallback()->deallocate(s); } } #if !PX_DOXYGEN } // namespace physx diff --git a/Source/ThirdParty/PhysX/common/PxStringTable.h b/Source/ThirdParty/PhysX/common/PxStringTable.h index 2af440040..f5cc13467 100644 --- a/Source/ThirdParty/PhysX/common/PxStringTable.h +++ b/Source/ThirdParty/PhysX/common/PxStringTable.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,11 +22,10 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - #ifndef PX_STRING_TABLE_H #define PX_STRING_TABLE_H diff --git a/Source/ThirdParty/PhysX/common/PxTolerancesScale.h b/Source/ThirdParty/PhysX/common/PxTolerancesScale.h index c34f5322e..43434818a 100644 --- a/Source/ThirdParty/PhysX/common/PxTolerancesScale.h +++ b/Source/ThirdParty/PhysX/common/PxTolerancesScale.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_SCALE_H -#define PX_SCALE_H +#ifndef PX_TOLERANCES_SCALE_H +#define PX_TOLERANCES_SCALE_H /** \addtogroup common @{ @@ -42,13 +40,11 @@ namespace physx { #endif -class PxPhysics; - /** \brief Class to define the scale at which simulation runs. Most simulation tolerances are calculated in terms of the values here. -\note if you change the simulation scale, you will probablly also wish to change the scene's +\note if you change the simulation scale, you will probably also wish to change the scene's default value of gravity, and stable simulation will probably require changes to the scene's bounceThreshold also. */ @@ -57,8 +53,8 @@ class PxTolerancesScale { public: - /** brief - The approximate size of objects in the simulation. + /** + \brief The approximate size of objects in the simulation. For simulating roughly human-sized in metric units, 1 is a good choice. If simulation is done in centimetres, use 100 instead. This is used to @@ -66,8 +62,8 @@ public: */ PxReal length; - /** brief - The typical magnitude of velocities of objects in simulation. This is used to estimate + /** + \brief The typical magnitude of velocities of objects in simulation. This is used to estimate whether a contact should be treated as bouncing or resting based on its impact velocity, and a kinetic energy threshold below which the simulation may put objects to sleep. @@ -78,8 +74,11 @@ public: /** \brief constructor sets to default + + \param[in] defaultLength Default length + \param[in] defaultSpeed Default speed */ - PX_INLINE PxTolerancesScale(); + PX_INLINE PxTolerancesScale(float defaultLength=1.0f, float defaultSpeed=10.0f); /** \brief Returns true if the descriptor is valid. @@ -89,9 +88,9 @@ public: }; -PX_INLINE PxTolerancesScale::PxTolerancesScale(): - length(1.0f), - speed(10.0f) +PX_INLINE PxTolerancesScale::PxTolerancesScale(float defaultLength, float defaultSpeed) : + length (defaultLength), + speed (defaultSpeed) { } diff --git a/Source/ThirdParty/PhysX/common/PxTypeInfo.h b/Source/ThirdParty/PhysX/common/PxTypeInfo.h index 72b3c2dd4..8a84b3cb4 100644 --- a/Source/ThirdParty/PhysX/common/PxTypeInfo.h +++ b/Source/ThirdParty/PhysX/common/PxTypeInfo.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PX_PHYSICS_COMMON_PX_TYPEINFO -#define PX_PHYSICS_COMMON_PX_TYPEINFO +#ifndef PX_TYPE_INFO_H +#define PX_TYPE_INFO_H /** \addtogroup common @{ @@ -58,22 +57,45 @@ struct PxConcreteType eHEIGHTFIELD, eCONVEX_MESH, - eTRIANGLE_MESH_BVH33, + eTRIANGLE_MESH_BVH33, // PX_DEPRECATED eTRIANGLE_MESH_BVH34, + eTETRAHEDRON_MESH, + eSOFTBODY_MESH, eRIGID_DYNAMIC, eRIGID_STATIC, eSHAPE, eMATERIAL, + eSOFTBODY_MATERIAL, + eCLOTH_MATERIAL, + ePBD_MATERIAL, + eFLIP_MATERIAL, + eMPM_MATERIAL, + eCUSTOM_MATERIAL, eCONSTRAINT, eAGGREGATE, - eARTICULATION, eARTICULATION_REDUCED_COORDINATE, eARTICULATION_LINK, - eARTICULATION_JOINT, eARTICULATION_JOINT_REDUCED_COORDINATE, + eARTICULATION_SENSOR, + eARTICULATION_SPATIAL_TENDON, + eARTICULATION_FIXED_TENDON, + eARTICULATION_ATTACHMENT, + eARTICULATION_TENDON_JOINT, ePRUNING_STRUCTURE, - eBVH_STRUCTURE, + eBVH, + eSOFT_BODY, + eSOFT_BODY_STATE, + ePBD_PARTICLESYSTEM, + eFLIP_PARTICLESYSTEM, + eMPM_PARTICLESYSTEM, + eCUSTOM_PARTICLESYSTEM, + eFEM_CLOTH, + eHAIR_SYSTEM, + ePARTICLE_BUFFER, + ePARTICLE_DIFFUSE_BUFFER, + ePARTICLE_CLOTH_BUFFER, + ePARTICLE_RIGID_BUFFER, ePHYSX_CORE_COUNT, eFIRST_PHYSX_EXTENSION = 256, @@ -100,10 +122,17 @@ template struct PxTypeInfo {}; PX_DEFINE_TYPEINFO(PxBase, PxConcreteType::eUNDEFINED) PX_DEFINE_TYPEINFO(PxMaterial, PxConcreteType::eMATERIAL) +PX_DEFINE_TYPEINFO(PxFEMSoftBodyMaterial, PxConcreteType::eSOFTBODY_MATERIAL) +PX_DEFINE_TYPEINFO(PxFEMClothMaterial, PxConcreteType::eCLOTH_MATERIAL) +PX_DEFINE_TYPEINFO(PxPBDMaterial, PxConcreteType::ePBD_MATERIAL) +PX_DEFINE_TYPEINFO(PxFLIPMaterial, PxConcreteType::eFLIP_MATERIAL) +PX_DEFINE_TYPEINFO(PxMPMMaterial, PxConcreteType::eMPM_MATERIAL) +PX_DEFINE_TYPEINFO(PxCustomMaterial, PxConcreteType::eCUSTOM_MATERIAL) PX_DEFINE_TYPEINFO(PxConvexMesh, PxConcreteType::eCONVEX_MESH) PX_DEFINE_TYPEINFO(PxTriangleMesh, PxConcreteType::eUNDEFINED) PX_DEFINE_TYPEINFO(PxBVH33TriangleMesh, PxConcreteType::eTRIANGLE_MESH_BVH33) PX_DEFINE_TYPEINFO(PxBVH34TriangleMesh, PxConcreteType::eTRIANGLE_MESH_BVH34) +PX_DEFINE_TYPEINFO(PxTetrahedronMesh, PxConcreteType::eTETRAHEDRON_MESH) PX_DEFINE_TYPEINFO(PxHeightField, PxConcreteType::eHEIGHTFIELD) PX_DEFINE_TYPEINFO(PxActor, PxConcreteType::eUNDEFINED) PX_DEFINE_TYPEINFO(PxRigidActor, PxConcreteType::eUNDEFINED) @@ -111,14 +140,24 @@ PX_DEFINE_TYPEINFO(PxRigidBody, PxConcreteType::eUNDEFINED) PX_DEFINE_TYPEINFO(PxRigidDynamic, PxConcreteType::eRIGID_DYNAMIC) PX_DEFINE_TYPEINFO(PxRigidStatic, PxConcreteType::eRIGID_STATIC) PX_DEFINE_TYPEINFO(PxArticulationLink, PxConcreteType::eARTICULATION_LINK) -PX_DEFINE_TYPEINFO(PxArticulationJoint, PxConcreteType::eARTICULATION_JOINT) PX_DEFINE_TYPEINFO(PxArticulationJointReducedCoordinate, PxConcreteType::eARTICULATION_JOINT_REDUCED_COORDINATE) -PX_DEFINE_TYPEINFO(PxArticulation, PxConcreteType::eARTICULATION) PX_DEFINE_TYPEINFO(PxArticulationReducedCoordinate, PxConcreteType::eARTICULATION_REDUCED_COORDINATE) PX_DEFINE_TYPEINFO(PxAggregate, PxConcreteType::eAGGREGATE) PX_DEFINE_TYPEINFO(PxConstraint, PxConcreteType::eCONSTRAINT) PX_DEFINE_TYPEINFO(PxShape, PxConcreteType::eSHAPE) PX_DEFINE_TYPEINFO(PxPruningStructure, PxConcreteType::ePRUNING_STRUCTURE) +PX_DEFINE_TYPEINFO(PxParticleSystem, PxConcreteType::eUNDEFINED) +PX_DEFINE_TYPEINFO(PxPBDParticleSystem, PxConcreteType::ePBD_PARTICLESYSTEM) +PX_DEFINE_TYPEINFO(PxFLIPParticleSystem, PxConcreteType::eFLIP_PARTICLESYSTEM) +PX_DEFINE_TYPEINFO(PxMPMParticleSystem, PxConcreteType::eMPM_PARTICLESYSTEM) +PX_DEFINE_TYPEINFO(PxCustomParticleSystem, PxConcreteType::eCUSTOM_PARTICLESYSTEM) +PX_DEFINE_TYPEINFO(PxSoftBody, PxConcreteType::eSOFT_BODY) +PX_DEFINE_TYPEINFO(PxFEMCloth, PxConcreteType::eFEM_CLOTH) +PX_DEFINE_TYPEINFO(PxHairSystem, PxConcreteType::eHAIR_SYSTEM) +PX_DEFINE_TYPEINFO(PxParticleBuffer, PxConcreteType::ePARTICLE_BUFFER) +PX_DEFINE_TYPEINFO(PxParticleAndDiffuseBuffer, PxConcreteType::ePARTICLE_DIFFUSE_BUFFER) +PX_DEFINE_TYPEINFO(PxParticleClothBuffer, PxConcreteType::ePARTICLE_CLOTH_BUFFER) +PX_DEFINE_TYPEINFO(PxParticleRigidBuffer, PxConcreteType::ePARTICLE_RIGID_BUFFER) #if !PX_DOXYGEN } // namespace physx diff --git a/Source/ThirdParty/PhysX/common/windows/PxWindowsDelayLoadHook.h b/Source/ThirdParty/PhysX/common/windows/PxWindowsDelayLoadHook.h index 5a7b178d4..433b981ec 100644 --- a/Source/ThirdParty/PhysX/common/windows/PxWindowsDelayLoadHook.h +++ b/Source/ThirdParty/PhysX/common/windows/PxWindowsDelayLoadHook.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_DELAY_LOAD_HOOK -#define PX_PHYSICS_DELAY_LOAD_HOOK +#ifndef PX_WINDOWS_DELAY_LOAD_HOOK_H +#define PX_WINDOWS_DELAY_LOAD_HOOK_H #include "foundation/PxPreprocessor.h" #include "common/PxPhysXCommonConfig.h" diff --git a/Source/ThirdParty/PhysX/cooking/PxBVH33MidphaseDesc.h b/Source/ThirdParty/PhysX/cooking/PxBVH33MidphaseDesc.h index 25e3e137b..4642746a7 100644 --- a/Source/ThirdParty/PhysX/cooking/PxBVH33MidphaseDesc.h +++ b/Source/ThirdParty/PhysX/cooking/PxBVH33MidphaseDesc.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,11 +22,10 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - #ifndef PX_BVH_33_MIDPHASE_DESC_H #define PX_BVH_33_MIDPHASE_DESC_H /** \addtogroup cooking @@ -42,8 +40,11 @@ namespace physx { #endif -/** \brief Enumeration for mesh cooking hints. */ -struct PxMeshCookingHint +/** + * \brief Enumeration for mesh cooking hints. + * @deprecated + */ +struct PX_DEPRECATED PxMeshCookingHint { enum Enum { @@ -57,8 +58,9 @@ struct PxMeshCookingHint \brief Structure describing parameters affecting BVH33 midphase mesh structure. @see PxCookingParams, PxMidphaseDesc +@deprecated */ -struct PxBVH33MidphaseDesc +struct PX_DEPRECATED PxBVH33MidphaseDesc { /** \brief Controls the trade-off between mesh size and runtime performance. @@ -107,4 +109,5 @@ struct PxBVH33MidphaseDesc /** @} */ -#endif // PX_BVH_33_MIDPHASE_DESC_H +#endif + diff --git a/Source/ThirdParty/PhysX/cooking/PxBVH34MidphaseDesc.h b/Source/ThirdParty/PhysX/cooking/PxBVH34MidphaseDesc.h index 2c9933c45..100941874 100644 --- a/Source/ThirdParty/PhysX/cooking/PxBVH34MidphaseDesc.h +++ b/Source/ThirdParty/PhysX/cooking/PxBVH34MidphaseDesc.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,11 +22,10 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - #ifndef PX_BVH_34_MIDPHASE_DESC_H #define PX_BVH_34_MIDPHASE_DESC_H /** \addtogroup cooking @@ -42,6 +40,22 @@ namespace physx { #endif +/** +\brief Desired build strategy for PxMeshMidPhase::eBVH34 +*/ +struct PxBVH34BuildStrategy +{ + enum Enum + { + eFAST = 0, //!< Fast build strategy. Fast build speed, good runtime performance in most cases. Recommended for runtime mesh cooking. + eDEFAULT = 1, //!< Default build strategy. Medium build speed, good runtime performance in all cases. + eSAH = 2, //!< SAH build strategy. Slower builds, slightly improved runtime performance in some cases. + + eLAST + }; +}; + + /** \brief Structure describing parameters affecting BVH34 midphase mesh structure. @@ -57,16 +71,39 @@ struct PxBVH34MidphaseDesc smaller mesh sizes, but with worse runtime performance. Default value: 4 - Range: <4, 15> + Range: <2, 15> */ PxU32 numPrimsPerLeaf; + /** + \brief Desired build strategy for the BVH + + Default value: eDEFAULT + */ + PxBVH34BuildStrategy::Enum buildStrategy; + + /** + \brief Whether the tree should be quantized or not + + Quantized trees use up less memory, but the runtime dequantization (to retrieve the node bounds) might have + a measurable performance cost. In most cases the cost is too small to matter, and using less memory is more + important. Hence, the default is true. + + One important use case for non-quantized trees is deformable meshes. The refit function for the BVH is not + supported for quantized trees. + + Default value: true + */ + bool quantized; + /** \brief Desc initialization to default value. */ void setToDefault() { numPrimsPerLeaf = 4; + buildStrategy = PxBVH34BuildStrategy::eDEFAULT; + quantized = true; } /** @@ -75,7 +112,7 @@ struct PxBVH34MidphaseDesc */ bool isValid() const { - if(numPrimsPerLeaf < 4 || numPrimsPerLeaf > 15) + if(numPrimsPerLeaf < 2 || numPrimsPerLeaf > 15) return false; return true; } @@ -87,4 +124,5 @@ struct PxBVH34MidphaseDesc /** @} */ -#endif // PX_BVH_34_MIDPHASE_DESC_H +#endif + diff --git a/Source/ThirdParty/PhysX/cooking/PxBVHStructureDesc.h b/Source/ThirdParty/PhysX/cooking/PxBVHDesc.h similarity index 59% rename from Source/ThirdParty/PhysX/cooking/PxBVHStructureDesc.h rename to Source/ThirdParty/PhysX/cooking/PxBVHDesc.h index 62ff9de19..4a0aec9ad 100644 --- a/Source/ThirdParty/PhysX/cooking/PxBVHStructureDesc.h +++ b/Source/ThirdParty/PhysX/cooking/PxBVHDesc.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,21 +22,20 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_BVH_STRUCTURE_DESC_H -#define PX_BVH_STRUCTURE_DESC_H +#ifndef PX_BVH_DESC_H +#define PX_BVH_DESC_H /** \addtogroup cooking @{ */ #include "common/PxCoreUtilityTypes.h" -#include "common/PxPhysXCommonConfig.h" #include "foundation/PxTransform.h" #include "foundation/PxBounds3.h" +#include "geometry/PxBVHBuildStrategy.h" #if !PX_DOXYGEN namespace physx @@ -45,15 +43,14 @@ namespace physx #endif /** +\brief Descriptor class for #PxBVH. -\brief Descriptor class for #PxBVHStructure. - -@see PxBVHStructure +@see PxBVH */ -class PxBVHStructureDesc +class PxBVHDesc { public: - PX_INLINE PxBVHStructureDesc(); + PX_INLINE PxBVHDesc(); /** \brief Pointer to first bounding box. @@ -61,7 +58,38 @@ public: PxBoundedData bounds; /** - \brief Initialize the BVH structure descriptor + \brief Bounds enlargement + + Passed bounds are slightly enlarged before creating the BVH. This is done to avoid numerical issues when + e.g. raycasts just graze the bounds. The performed operation is: + + extents = (bounds.maximum - bounds.minimum)/2 + enlagedBounds.minimum = passedBounds.minium - extents * enlargement + enlagedBounds.maximum = passedBounds.maxium + extents * enlargement + + Users can pass pre-enlarged bounds to the BVH builder, in which case just set the enlargement value to zero. + + Default value: 0.01 + */ + float enlargement; + + /** + \brief Max primitives per leaf limit. + + Range: [0, 16)
+ Default value: 4 + */ + PxU32 numPrimsPerLeaf; + + /** + \brief Desired build strategy for the BVH + + Default value: eDEFAULT + */ + PxBVHBuildStrategy::Enum buildStrategy; + + /** + \brief Initialize the BVH descriptor */ PX_INLINE void setToDefault(); @@ -71,39 +99,46 @@ public: */ PX_INLINE bool isValid() const; - protected: }; - - -PX_INLINE PxBVHStructureDesc::PxBVHStructureDesc() +PX_INLINE PxBVHDesc::PxBVHDesc() : enlargement(0.01f), numPrimsPerLeaf(4), buildStrategy(PxBVHBuildStrategy::eDEFAULT) { } -PX_INLINE void PxBVHStructureDesc::setToDefault() +PX_INLINE void PxBVHDesc::setToDefault() { - *this = PxBVHStructureDesc(); + *this = PxBVHDesc(); } -PX_INLINE bool PxBVHStructureDesc::isValid() const +PX_INLINE bool PxBVHDesc::isValid() const { // Check BVH desc data if(!bounds.data) return false; - if(bounds.stride < sizeof(PxBounds3)) //should be at least one point's worth of data + if(bounds.stride < sizeof(PxBounds3)) //should be at least one bounds' worth of data return false; if(bounds.count == 0) return false; + if(enlargement<0.0f) + return false; + + if(numPrimsPerLeaf>=16) + return false; + return true; } + /** + * @deprecated + */ + typedef PX_DEPRECATED PxBVHDesc PxBVHStructureDesc; + #if !PX_DOXYGEN } // namespace physx #endif - /** @} */ -#endif // PX_BVH_STRUCTURE_DESC_H +#endif diff --git a/Source/ThirdParty/PhysX/cooking/PxConvexMeshDesc.h b/Source/ThirdParty/PhysX/cooking/PxConvexMeshDesc.h index 8aa939f74..390e2636e 100644 --- a/Source/ThirdParty/PhysX/cooking/PxConvexMeshDesc.h +++ b/Source/ThirdParty/PhysX/cooking/PxConvexMeshDesc.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_COLLISION_NXCONVEXMESHDESC -#define PX_COLLISION_NXCONVEXMESHDESC +#ifndef PX_CONVEX_MESH_DESC_H +#define PX_CONVEX_MESH_DESC_H /** \addtogroup cooking @{ */ @@ -38,12 +36,12 @@ #include "foundation/PxFlags.h" #include "common/PxCoreUtilityTypes.h" #include "geometry/PxConvexMesh.h" +#include "PxSDFDesc.h" #if !PX_DOXYGEN namespace physx { #endif - /** \brief Flags which describe the format and behavior of a convex mesh. */ @@ -121,8 +119,8 @@ struct PxConvexFlag eFAST_INERTIA_COMPUTATION = (1 << 6), /** - \brief Convex hulls are created with respect to GPU simulation limitations. Vertex limit is set to 64 and - vertex limit per face is internally set to 32. + \brief Convex hulls are created with respect to GPU simulation limitations. Vertex limit and polygon limit + is set to 64 and vertex limit per face is internally set to 32. \note Can be used only with eCOMPUTE_CONVEX flag. */ eGPU_COMPATIBLE = (1 << 7), @@ -148,6 +146,8 @@ PX_FLAGS_OPERATORS(PxConvexFlag::Enum,PxU16) /** \brief Descriptor class for #PxConvexMesh. \note The number of vertices and the number of convex polygons in a cooked convex mesh is limited to 256. +\note The number of vertices and the number of convex polygons in a GPU compatible convex mesh is limited to 64, +and the number of faces per vertex is limited to 32. @see PxConvexMesh PxConvexMeshGeometry PxShape PxPhysics.createConvexMesh() @@ -193,19 +193,31 @@ public: PxConvexFlags flags; /** - \brief Limits the number of vertices of the result convex mesh. Hard maximum limit is 256 + \brief Limits the number of vertices of the result convex mesh. Hard maximum limit is 255 and minimum limit is 4 if PxConvexFlag::ePLANE_SHIFTING is used, otherwise the minimum limit is 8. \note Vertex limit is only used when PxConvexFlag::eCOMPUTE_CONVEX is specified. \note The please see PxConvexFlag::ePLANE_SHIFTING for algorithm explanation + \note The maximum limit for GPU compatible convex meshes is 64. @see PxConvexFlag::ePLANE_SHIFTING Range: [4, 255]
Default: 255 */ - PxU16 vertexLimit; + PxU16 vertexLimit; + + /** + \brief Limits the number of polygons of the result convex mesh. Hard maximum limit is 255 + and minimum limit is 4. + + \note The maximum limit for GPU compatible convex meshes is 64. + + Range: [4, 255]
+ Default: 255 + */ + PxU16 polygonLimit; /** \brief Maximum number of vertices after quantization. The quantization is done during the vertex cleaning phase. @@ -218,6 +230,13 @@ public: */ PxU16 quantizedCount; + /** + \brief SDF descriptor. When this descriptor is set, signed distance field is calculated for this convex mesh. + + Default: NULL + */ + PxSDFDesc* sdfDesc; + /** \brief constructor sets to default. */ @@ -226,6 +245,8 @@ public: \brief (re)sets the structure to the default. */ PX_INLINE void setToDefault(); + + /** \brief Returns true if the descriptor is valid. @@ -235,8 +256,9 @@ public: }; PX_INLINE PxConvexMeshDesc::PxConvexMeshDesc() //constructor sets to default -: vertexLimit(255), quantizedCount(255) +: vertexLimit(255), polygonLimit(255), quantizedCount(255), sdfDesc(NULL) { + } PX_INLINE void PxConvexMeshDesc::setToDefault() @@ -292,10 +314,26 @@ PX_INLINE bool PxConvexMeshDesc::isValid() const return false; } - if(vertexLimit > 256) + if(vertexLimit > 255) { return false; } + + if (polygonLimit < 4) + { + return false; + } + + if (polygonLimit > 255) + { + return false; + } + + if (sdfDesc && !sdfDesc->isValid()) + { + return false; + } + return true; } diff --git a/Source/ThirdParty/PhysX/cooking/PxCooking.h b/Source/ThirdParty/PhysX/cooking/PxCooking.h index 94b492770..0ed9b93a1 100644 --- a/Source/ThirdParty/PhysX/cooking/PxCooking.h +++ b/Source/ThirdParty/PhysX/cooking/PxCooking.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,11 +22,10 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - #ifndef PX_COOKING_H #define PX_COOKING_H /** \addtogroup cooking @@ -39,18 +37,22 @@ #include "cooking/PxConvexMeshDesc.h" #include "cooking/PxTriangleMeshDesc.h" +#include "cooking/PxTetrahedronMeshDesc.h" #include "cooking/PxMidphaseDesc.h" -#include "cooking/PxBVHStructureDesc.h" +#include "cooking/PxBVHDesc.h" #include "geometry/PxTriangleMesh.h" -#include "geometry/PxBVHStructure.h" +#include "geometry/PxTetrahedronMesh.h" +#include "geometry/PxBVH.h" #if !PX_DOXYGEN namespace physx { #endif -class PxPhysicsInsertionCallback; +class PxInsertionCallback; class PxFoundation; +class PxAllocatorCallback; +class PxHeightFieldDesc; /** \brief Result from convex cooking. @@ -126,11 +128,8 @@ struct PxTriangleMeshCookingResult }; /** - \brief Enum for the set of mesh pre-processing parameters. - */ - struct PxMeshPreprocessingFlag { enum Enum @@ -138,7 +137,7 @@ struct PxMeshPreprocessingFlag /** \brief When set, mesh welding is performed. See PxCookingParams::meshWeldTolerance. Clean mesh must be enabled. */ - eWELD_VERTICES = 1 << 0, + eWELD_VERTICES = 1 << 0, /** \brief When set, mesh cleaning is disabled. This makes cooking faster. @@ -148,26 +147,36 @@ struct PxMeshPreprocessingFlag It is recommended to use only meshes that passed during validateTriangleMesh. */ - eDISABLE_CLEAN_MESH = 1 << 1, + eDISABLE_CLEAN_MESH = 1 << 1, /** \brief When set, active edges are set for each triangle edge. This makes cooking faster but slow up contact generation. */ - eDISABLE_ACTIVE_EDGES_PRECOMPUTE = 1 << 2, + eDISABLE_ACTIVE_EDGES_PRECOMPUTE = 1 << 2, /** \brief When set, 32-bit indices will always be created regardless of triangle count. \note By default mesh will be created with 16-bit indices for triangle count <= 0xFFFF and 32-bit otherwise. */ - eFORCE_32BIT_INDICES = 1 << 3 + eFORCE_32BIT_INDICES = 1 << 3, + + /** + \brief When set, a list of triangles will be created for each associated vertex in the mesh + */ + eENABLE_VERT_MAPPING = 1 << 4, + + /** + \brief When set, inertia tensor is calculated for the mesh + */ + eENABLE_INERTIA = 1 << 5 + }; }; typedef PxFlags PxMeshPreprocessingFlags; /** - \brief Structure describing parameters affecting mesh cooking. @see PxSetCookingParams() PxGetCookingParams() @@ -281,7 +290,7 @@ struct PxCookingParams @see PxBVH33MidphaseDesc, PxBVH34MidphaseDesc, PxMidphaseDesc - Default value: PxMeshMidPhase::eBVH33 + Default value: PxMeshMidPhase::eBVH34 */ PxMidphaseDesc midphaseDesc; @@ -294,6 +303,15 @@ struct PxCookingParams */ PxU32 gaussMapLimit; + /** + \brief Maximum mass ratio allowed on vertices touched by a single tet. If a any tetrahedron exceeds the mass ratio, the masses will get smoothed locally + until the maximum mass ratio is matched. Value should not be below 1. Smoothing might not fully converge for values <1.5. The smaller the maximum + allowed ratio, the better the stability during simulation. + + Default value: FLT_MAX + */ + PxReal maxWeightRatioInTet; + PxCookingParams(const PxTolerancesScale& sc): areaTestEpsilon (0.06f*sc.length*sc.length), planeTolerance (0.0007f), @@ -304,12 +322,18 @@ struct PxCookingParams scale (sc), meshPreprocessParams (0), meshWeldTolerance (0.f), - gaussMapLimit (32) + gaussMapLimit (32), + maxWeightRatioInTet (FLT_MAX) { } }; -class PxCooking +/** +\brief Provides methods to cook (where cooking means to prepare the data and convert it to the right format +potentially including the construction of acceleration structures and other support data) all kind of simulation data +@deprecated +*/ +class PX_DEPRECATED PxCooking { public: /** @@ -320,7 +344,7 @@ public: \note This function is required to be called to release foundation usage. */ - virtual void release() = 0; + virtual void release() = 0; /** \brief Sets cooking parameters @@ -329,7 +353,7 @@ public: @see getParams() */ - virtual void setParams(const PxCookingParams& params) = 0; + virtual void setParams(const PxCookingParams& params) = 0; /** \brief Gets cooking parameters @@ -338,14 +362,14 @@ public: @see PxCookingParams setParams() */ - virtual const PxCookingParams& getParams() const = 0; + virtual const PxCookingParams& getParams() const = 0; /** \brief Checks endianness is the same between cooking & target platforms \return True if there is and endian mismatch. */ - virtual bool platformMismatch() const = 0; + virtual bool platformMismatch() const = 0; /** \brief Cooks a triangle mesh. The results are written to the stream. @@ -356,29 +380,50 @@ public: cookTriangleMesh() allows a mesh description to be cooked into a binary stream suitable for loading and performing collision detection at runtime. - \param[in] desc The triangle mesh descriptor to read the mesh from. - \param[in] stream User stream to output the cooked data. - \param[out] condition Result from triangle mesh cooking. + \param[in] desc The triangle mesh descriptor to read the mesh from. + \param[in] stream User stream to output the cooked data. + \param[out] condition Result from triangle mesh cooking. \return true on success @see cookConvexMesh() setParams() PxPhysics.createTriangleMesh() PxTriangleMeshCookingResult::Enum */ - virtual bool cookTriangleMesh(const PxTriangleMeshDesc& desc, PxOutputStream& stream, PxTriangleMeshCookingResult::Enum* condition = NULL) const = 0; - + virtual bool cookTriangleMesh(const PxTriangleMeshDesc& desc, PxOutputStream& stream, PxTriangleMeshCookingResult::Enum* condition = NULL) const = 0; /** - \brief Cooks and creates a triangle mesh and inserts it into PxPhysics. + \brief Cooks and creates a triangle mesh without going through a stream. - \note PxPhysicsInsertionCallback can be obtained through PxPhysics::getPhysicsInsertionCallback(). + \note This method does the same as cookTriangleMesh, but the produced mesh is not stored + into a stream but is either directly inserted in PxPhysics, or created as a standalone + object. Use this method if you are unable to cook offline. - \param[in] desc The triangle mesh descriptor to read the mesh from. - \param[in] insertionCallback The insertion interface from PxPhysics. - \param[out] condition Result from triangle mesh cooking. + \note PxInsertionCallback can be obtained through PxPhysics::getPhysicsInsertionCallback() + or PxCooking::getStandaloneInsertionCallback(). + + \param[in] desc The triangle mesh descriptor to read the mesh from. + \param[in] insertionCallback The insertion interface from PxPhysics. + \param[out] condition Result from triangle mesh cooking. \return PxTriangleMesh pointer on success. - @see cookTriangleMesh() setParams() PxPhysics.createTriangleMesh() PxPhysicsInsertionCallback + @see cookTriangleMesh() setParams() PxPhysics.createTriangleMesh() PxInsertionCallback */ - virtual PxTriangleMesh* createTriangleMesh(const PxTriangleMeshDesc& desc, PxPhysicsInsertionCallback& insertionCallback, PxTriangleMeshCookingResult::Enum* condition = NULL) const = 0; + virtual PxTriangleMesh* createTriangleMesh(const PxTriangleMeshDesc& desc, PxInsertionCallback& insertionCallback, PxTriangleMeshCookingResult::Enum* condition = NULL) const = 0; + + /** + \brief Cooks and creates a triangle mesh without going through a stream. Convenience function for standalone objects. + + \note This method does the same as cookTriangleMesh, but the produced mesh is not stored + into a stream but is either directly inserted in PxPhysics, or created as a standalone + object. Use this method if you are unable to cook offline. + \return PxTriangleMesh pointer on success. + + \param[in] desc The triangle mesh descriptor to read the mesh from. + + @see cookTriangleMesh() PxPhysics.createTriangleMesh() PxInsertionCallback + */ + PX_FORCE_INLINE PxTriangleMesh* createTriangleMesh(const PxTriangleMeshDesc& desc) const + { + return createTriangleMesh(desc, const_cast(*this).getStandaloneInsertionCallback()); + } /** \brief Verifies if the triangle mesh is valid. Prints an error message for each inconsistency found. @@ -387,7 +432,7 @@ public: 1. There are no duplicate vertices (within specified vertexWeldTolerance. See PxCookingParams::meshWeldTolerance) 2. There are no large triangles (within specified PxTolerancesScale.) - \param[in] desc The triangle mesh descriptor to read the mesh from. + \param[in] desc The triangle mesh descriptor to read the mesh from. \return true if all the validity conditions hold, false otherwise. @@ -395,6 +440,202 @@ public: */ virtual bool validateTriangleMesh(const PxTriangleMeshDesc& desc) const = 0; + /** + \brief Cooks a softbody mesh. The results are written to the stream. + + To create a softbody mesh object it is necessary to first 'cook' the mesh data into + a form which allows the SDK to perform efficient collision detection and to store data + used during the FEM calculations. + + cookSoftBodyMesh() allows a mesh description to be cooked into a binary stream + suitable for loading and performing collision detection at runtime. + + Example + + \param[in] simulationMeshDesc The tetrahedron mesh descriptor to read the simulation mesh from. + \param[in] collisionMeshDesc The tetrahedron mesh descriptor to read the collision mesh from. + \param[in] softbodyDataDesc The softbody data descriptor to read mapping information from. + \param[in] stream User stream to output the cooked data. + \return true on success + + @see cookConvexMesh() setParams() PxPhysics.createTriangleMesh() PxTriangleMeshCookingResult::Enum + */ + virtual bool cookSoftBodyMesh(const PxTetrahedronMeshDesc& simulationMeshDesc, const PxTetrahedronMeshDesc& collisionMeshDesc, + const PxSoftBodySimulationDataDesc& softbodyDataDesc, PxOutputStream& stream) const = 0; + + /** + \brief Cooks and creates a softbody mesh without going through a stream. + + \note This method does the same as cookSoftBodyMesh, but the produced mesh is not stored + into a stream but is either directly inserted in PxPhysics, or created as a standalone + object. Use this method if you are unable to cook offline. + + \note PxInsertionCallback can be obtained through PxPhysics::getPhysicsInsertionCallback() + or PxCooking::getStandaloneInsertionCallback(). + + \param[in] simulationMeshDesc The tetrahedron mesh descriptor to read the simulation mesh from. + \param[in] collisionMeshDesc The tetrahedron mesh descriptor to read the collision mesh from. + \param[in] softbodyDataDesc The softbody data descriptor to read mapping information from. + \param[in] insertionCallback The insertion interface from PxPhysics. + \return PxSoftBodyMesh pointer on success. + + @see cookTriangleMesh() setParams() PxPhysics.createTriangleMesh() PxInsertionCallback + */ + virtual PxSoftBodyMesh* createSoftBodyMesh(const PxTetrahedronMeshDesc& simulationMeshDesc, const PxTetrahedronMeshDesc& collisionMeshDesc, + const PxSoftBodySimulationDataDesc& softbodyDataDesc, PxInsertionCallback& insertionCallback) const = 0; + + + /** + \brief Cooks and creates a softbody mesh without going through a stream. Convenience function for standalone objects. + + \note This method does the same as cookSoftBodyMesh, but the produced mesh is not stored + into a stream but is either directly inserted in PxPhysics, or created as a standalone + object. Use this method if you are unable to cook offline. + + \param[in] simulationMeshDesc The tetrahedron mesh descriptor to read the simulation mesh from. + \param[in] collisionMeshDesc The tetrahedron mesh descriptor to read the collision mesh from. + \param[in] softbodyDataDesc The softbody data descriptor to read mapping information from. + \return PxSoftBodyMesh pointer on success. + + @see cookTriangleMesh() PxPhysics.createTriangleMesh() PxInsertionCallback + */ + PX_FORCE_INLINE PxSoftBodyMesh* createSoftBodyMesh(const PxTetrahedronMeshDesc& simulationMeshDesc, const PxTetrahedronMeshDesc& collisionMeshDesc, + const PxSoftBodySimulationDataDesc& softbodyDataDesc) const + { + return createSoftBodyMesh(simulationMeshDesc, collisionMeshDesc, softbodyDataDesc, const_cast(*this).getStandaloneInsertionCallback()); + } + + /** + \brief Cooks a tetrahedron mesh. The results are written to the stream. + + To create a tetrahedron mesh object it is necessary to first 'cook' the mesh data into + a form which allows the SDK to perform efficient collision detection. + + cookTriangleMesh() allows a mesh description to be cooked into a binary stream + suitable for loading and performing collision detection at runtime. + + Example + + \param[in] meshDesc The tetrahedron mesh descriptor to read the mesh from. + \param[in] stream User stream to output the cooked data. + \return true on success + + @see cookConvexMesh() setParams() PxPhysics.createTetrahedronMesh() + */ + virtual bool cookTetrahedronMesh(const PxTetrahedronMeshDesc& meshDesc, PxOutputStream& stream) const = 0; + + /** + \brief Cooks and creates a tetrahedron mesh without going through a stream. + + \note This method does the same as cookTetrahedronMesh, but the produced mesh is not stored + into a stream but is either directly inserted in PxPhysics, or created as a standalone + object. Use this method if you are unable to cook offline. + + \note PxInsertionCallback can be obtained through PxPhysics::getPhysicsInsertionCallback() + or PxCooking::getStandaloneInsertionCallback(). + + \param[in] meshDesc The tetrahedron mesh descriptor to read the mesh from. + \param[in] insertionCallback The insertion interface from PxPhysics. + \return PxTetrahedronMesh pointer on success. + + @see cookTetrahedronMesh() setParams() PxInsertionCallback + */ + virtual PxTetrahedronMesh* createTetrahedronMesh(const PxTetrahedronMeshDesc& meshDesc, PxInsertionCallback& insertionCallback) const = 0; + + + /** + \brief Cooks and creates a tetrahedron mesh without going through a stream. Convenience function for standalone objects. + + \note This method does the same as cookTetrahedronMesh, but the produced mesh is not stored + into a stream but is either directly inserted in PxPhysics, or created as a standalone + object. Use this method if you are unable to cook offline. + + \param[in] meshDesc The tetrahedron mesh descriptor to read the mesh from. + \return PxTetrahedronMesh pointer on success. + + @see cookTetrahedronMesh() PxInsertionCallback + */ + PX_FORCE_INLINE PxTetrahedronMesh* createTetrahedronMesh(const PxTetrahedronMeshDesc& meshDesc) const + { + return createTetrahedronMesh(meshDesc, const_cast(*this).getStandaloneInsertionCallback()); + } + + /** + \brief Computes the mapping between collision and simulation mesh + + The softbody deformation is computed on the simulation mesh. To deform the collision mesh accordingly + it needs to be specified how its vertices need to be placed and updated inside the deformation mesh. + This method computes that embedding information. + + \param[in] simulationMesh A tetrahedral mesh that defines the shape of the simulation mesh which is used to compute the body's deformation + \param[in] collisionMesh A tetrahedral mesh that defines the shape of the collision mesh which is used for collision detection + \param[in] collisionData A data container that contains acceleration structures and surface information of the collision mesh + \param[in] vertexToTet Optional indices (array of integers) that specifies the index of the tetrahedron in the simulation mesh that + contains a collision mesh vertex. If not provided, the embedding will be computed internally. If the simulation mesh is obtained from + PxTetMaker::createVoxelTetrahedronMesh, then the vertexToTet map createVoxelTetrahedronMesh returned should be used here. + \return PxCollisionMeshMappingData pointer that describes how the collision mesh is embedded into the simulation mesh + + @see PxTetMaker::createVoxelTetrahedronMesh + */ + virtual PxCollisionMeshMappingData* computeModelsMapping(PxTetrahedronMeshData& simulationMesh, const PxTetrahedronMeshData& collisionMesh, + const PxSoftBodyCollisionData& collisionData, const PxBoundedData* vertexToTet = NULL) const = 0; + + /** + \brief Computes data to accelerate collision detection of tetrahedral meshes + + Computes data structures to speed up collision detection with tetrahedral meshes. + + \param[in] collisionMeshDesc Raw tetrahedral mesh descriptor wich will be used for collision detection + \return PxCollisionTetrahedronMeshData pointer that describes the collision mesh + + */ + virtual PxCollisionTetrahedronMeshData* computeCollisionData(const PxTetrahedronMeshDesc& collisionMeshDesc) const = 0; + + /** + \brief Computes data to accelerate collision detection of tetrahedral meshes + + Computes data to compute and store a softbody's deformation using FEM. + + \param[in] simulationMeshDesc Raw tetrahedral mesh descriptor wich will be used for FEM simulation + \return PxSimulationTetrahedronMeshData pointer that describes the simulation mesh + + */ + virtual PxSimulationTetrahedronMeshData* computeSimulationData(const PxTetrahedronMeshDesc& simulationMeshDesc) const = 0; + + /** + \brief Bundles all data required for softbody simulation + + Creates a container that provides everything to create a PxSoftBody + + \param[in] simulationMesh The geometry (tetrahedral mesh) to be used as simulation mesh + \param[in] simulationData Additional non-tetmesh data that contains mass information etc. for the simulation mesh + \param[in] collisionMesh The geometry (tetrahedral mesh) to be used for collision detection + \param[in] collisionData Additional non-tetmesh data that contains surface information, acceleration structures etc. for the simulation mesh + \param[in] mappingData Mapping that describes how the collision mesh's vertices are embedded into the simulation mesh + \param[in] insertionCallback The insertion interface from PxPhysics. + \return PxSoftBodyMesh pointer that represents a softbody mesh bundling all data (simulation mesh, collision mesh etc.) + + @see PxSoftBody createSoftBody() + */ + virtual PxSoftBodyMesh* assembleSoftBodyMesh(PxTetrahedronMeshData& simulationMesh, PxSoftBodySimulationData& simulationData, PxTetrahedronMeshData& collisionMesh, + PxSoftBodyCollisionData& collisionData, PxCollisionMeshMappingData& mappingData, PxInsertionCallback& insertionCallback) const = 0; + + /** + \brief Bundles all data required for softbody simulation + + Creates a container that provides everything to create a PxSoftBody + + \param[in] simulationMesh Container that provides all information about the simulation mesh (geometry, mass distribution etc.) + \param[in] collisionMesh Container that provides all information about the collision mesh (geometry, surface information, acceleration structures etc.) + \param[in] mappingData Mapping that describes how the collision mesh's vertices are embedded into the simulation mesh + \param[in] insertionCallback The insertion interface from PxPhysics. + \return PxSoftBodyMesh pointer that represents a softbody mesh bundling all data (simulation mesh, collision mesh etc.) + + @see PxSoftBody createSoftBody() + */ + virtual PxSoftBodyMesh* assembleSoftBodyMesh(PxSimulationTetrahedronMeshData& simulationMesh, PxCollisionTetrahedronMeshData& collisionMesh, + PxCollisionMeshMappingData& mappingData, PxInsertionCallback& insertionCallback) const = 0; + /** \brief Cooks a convex mesh. The results are written to the stream. @@ -408,9 +649,9 @@ public: \note The number of vertices and the number of convex polygons in a cooked convex mesh is limited to 255. \note If those limits are exceeded in either the user-provided data or the final cooked mesh, an error is reported. - \param[in] desc The convex mesh descriptor to read the mesh from. - \param[in] stream User stream to output the cooked data. - \param[out] condition Result from convex mesh cooking. + \param[in] desc The convex mesh descriptor to read the mesh from. + \param[in] stream User stream to output the cooked data. + \param[out] condition Result from convex mesh cooking. \return true on success. @see cookTriangleMesh() setParams() PxConvexMeshCookingResult::Enum @@ -418,21 +659,41 @@ public: virtual bool cookConvexMesh(const PxConvexMeshDesc& desc, PxOutputStream& stream, PxConvexMeshCookingResult::Enum* condition = NULL) const = 0; /** - \brief Cooks and creates a convex mesh and inserts it into PxPhysics. + \brief Cooks and creates a convex mesh without going through a stream. - \note This method does the same as cookConvexMesh, but the produced convex mesh is not stored - into a stream but is directly inserted in PxPhysics. Use this method if you are unable to cook offline. + \note This method does the same as cookConvexMesh, but the produced mesh is not stored + into a stream but is either directly inserted in PxPhysics, or created as a standalone + object. Use this method if you are unable to cook offline. - \note PxPhysicsInsertionCallback can be obtained through PxPhysics::getPhysicsInsertionCallback(). + \note PxInsertionCallback can be obtained through PxPhysics::getPhysicsInsertionCallback() + or PxCooking::getStandaloneInsertionCallback(). - \param[in] desc The convex mesh descriptor to read the mesh from. - \param[in] insertionCallback The insertion interface from PxPhysics. - \param[out] condition Result from convex mesh cooking. + \param[in] desc The convex mesh descriptor to read the mesh from. + \param[in] insertionCallback The insertion interface from PxPhysics. + \param[out] condition Result from convex mesh cooking. \return PxConvexMesh pointer on success - @see cookConvexMesh() setParams() PxPhysicsInsertionCallback + @see cookConvexMesh() setParams() PxInsertionCallback */ - virtual PxConvexMesh* createConvexMesh(const PxConvexMeshDesc& desc, PxPhysicsInsertionCallback& insertionCallback, PxConvexMeshCookingResult::Enum* condition = NULL) const = 0; + virtual PxConvexMesh* createConvexMesh(const PxConvexMeshDesc& desc, PxInsertionCallback& insertionCallback, PxConvexMeshCookingResult::Enum* condition = NULL) const = 0; + + + /** + \brief Cooks and creates a convex mesh without going through a stream. Convenience function for standalone objects. + + \note This method does the same as cookConvexMesh, but the produced mesh is not stored + into a stream but is either directly inserted in PxPhysics, or created as a standalone + object. Use this method if you are unable to cook offline. + + \param[in] desc The convex mesh descriptor to read the mesh from. + \return PxConvexMesh pointer on success + + @see cookConvexMesh() PxInsertionCallback + */ + PX_FORCE_INLINE PxConvexMesh* createConvexMesh(const PxConvexMeshDesc& desc) const + { + return createConvexMesh(desc, const_cast(*this).getStandaloneInsertionCallback()); + } /** \brief Verifies if the convex mesh is valid. Prints an error message for each inconsistency found. @@ -441,7 +702,7 @@ public: \note This function should be used if PxConvexFlag::eDISABLE_MESH_VALIDATION is planned to be used in release builds. - \param[in] desc The convex mesh descriptor to read the mesh from. + \param[in] desc The convex mesh descriptor to read the mesh from. \return true if all the validity conditions hold, false otherwise. @@ -449,7 +710,6 @@ public: */ virtual bool validateConvexMesh(const PxConvexMeshDesc& desc) const = 0; - /** \brief Computed hull polygons from given vertices and triangles. Polygons are needed for PxConvexMeshDesc rather than triangles. @@ -459,14 +719,14 @@ public: The provided PxAllocatorCallback does allocate the out array's. It is the user responsibility to deallocated those array's. - \param[in] mesh Simple triangle mesh containing vertices and triangles used to compute polygons. - \param[in] inCallback Memory allocator for out array allocations. - \param[out] nbVerts Number of vertices used by polygons. - \param[out] vertices Vertices array used by polygons. - \param[out] nbIndices Number of indices used by polygons. - \param[out] indices Indices array used by polygons. - \param[out] nbPolygons Number of created polygons. - \param[out] hullPolygons Polygons array. + \param[in] mesh Simple triangle mesh containing vertices and triangles used to compute polygons. + \param[in] inCallback Memory allocator for out array allocations. + \param[out] nbVerts Number of vertices used by polygons. + \param[out] vertices Vertices array used by polygons. + \param[out] nbIndices Number of indices used by polygons. + \param[out] indices Indices array used by polygons. + \param[out] nbPolygons Number of created polygons. + \param[out] hullPolygons Polygons array. \return true on success @see cookConvexMesh() PxConvexFlags PxConvexMeshDesc PxSimpleTriangleMesh @@ -482,8 +742,8 @@ public: cookHeightField() allows a heightfield description to be cooked into a binary stream suitable for loading and performing collision detection at runtime. - \param[in] desc The heightfield descriptor to read the HF from. - \param[in] stream User stream to output the cooked data. + \param[in] desc The heightfield descriptor to read the HF from. + \param[in] stream User stream to output the cooked data. \return true on success @see PxPhysics.createHeightField() @@ -493,43 +753,114 @@ public: /** \brief Cooks and creates a heightfield mesh and inserts it into PxPhysics. - \param[in] desc The heightfield descriptor to read the HF from. - \param[in] insertionCallback The insertion interface from PxPhysics. + \param[in] desc The heightfield descriptor to read the HF from. + \param[in] insertionCallback The insertion interface from PxPhysics. \return PxHeightField pointer on success - @see cookConvexMesh() setParams() PxPhysics.createTriangleMesh() PxPhysicsInsertionCallback + @see cookConvexMesh() setParams() PxPhysics.createTriangleMesh() PxInsertionCallback */ - virtual PxHeightField* createHeightField(const PxHeightFieldDesc& desc, PxPhysicsInsertionCallback& insertionCallback) const = 0; + virtual PxHeightField* createHeightField(const PxHeightFieldDesc& desc, PxInsertionCallback& insertionCallback) const = 0; + /** - \brief Cooks a bounding volume hierarchy structure. The results are written to the stream. + \brief Cooks and creates a heightfield mesh and inserts it into PxPhysics. Convenience function for standalone objects. - cookBVHStructure() allows a BVH structure description to be cooked into a binary stream + \param[in] desc The heightfield descriptor to read the HF from. + \return PxHeightField pointer on success + + @see cookConvexMesh() PxPhysics.createTriangleMesh() PxInsertionCallback + */ + PX_FORCE_INLINE PxHeightField* createHeightField(const PxHeightFieldDesc& desc) const + { + return createHeightField(desc, const_cast(*this).getStandaloneInsertionCallback()); + } + + /** + \brief Cooks a bounding volume hierarchy. The results are written to the stream. + + cookBVH() allows a BVH description to be cooked into a binary stream suitable for loading and performing BVH detection at runtime. - \param[in] desc The BVH structure descriptor. - \param[in] stream User stream to output the cooked data. + \param[in] desc The BVH descriptor. + \param[in] stream User stream to output the cooked data. \return true on success. - @see PxBVHStructure PxRigidActorExt::getRigidActorShapeLocalBoundsList + @see PxBVH PxRigidActorExt::getRigidActorShapeLocalBoundsList */ - virtual bool cookBVHStructure(const PxBVHStructureDesc& desc, PxOutputStream& stream) const = 0; + virtual bool cookBVH(const PxBVHDesc& desc, PxOutputStream& stream) const = 0; + /** - \brief Cooks and creates a bounding volume hierarchy structure and inserts it into PxPhysics. + \brief Backward compatibility helper. Cooks a bounding volume hierarchy. The results are written to the stream. - \note This method does the same as cookBVHStructure, but the produced BVH structure is not stored - into a stream but is directly inserted in PxPhysics. Use this method if you are unable to cook offline. - - \note PxPhysicsInsertionCallback can be obtained through PxPhysics::getPhysicsInsertionCallback(). - - \param[in] desc The BVH structure descriptor. - \param[in] insertionCallback The insertion interface from PxPhysics. - \return PxBVHStructure pointer on success - - @see cookBVHStructure() PxPhysicsInsertionCallback + \param[in] desc The BVH descriptor. + \param[in] stream User stream to output the cooked data. + \return true on success. + @deprecated */ - virtual PxBVHStructure* createBVHStructure(const PxBVHStructureDesc& desc, PxPhysicsInsertionCallback& insertionCallback) const = 0; + PX_DEPRECATED PX_FORCE_INLINE bool cookBVHStructure(const PxBVHStructureDesc& desc, PxOutputStream& stream) const + { + return cookBVH(desc, stream); + } + + /** + \brief Cooks and creates a bounding volume hierarchy without going through a stream. + + \note This method does the same as cookBVH, but the produced BVH is not stored + into a stream but is either directly inserted in PxPhysics, or created as a standalone + object. Use this method if you are unable to cook offline. + + \note PxInsertionCallback can be obtained through PxPhysics::getPhysicsInsertionCallback() + or PxCooking::getStandaloneInsertionCallback(). + + \param[in] desc The BVH descriptor. + \param[in] insertionCallback The insertion interface. + \return PxBVH pointer on success + + @see cookBVH() PxInsertionCallback + */ + virtual PxBVH* createBVH(const PxBVHDesc& desc, PxInsertionCallback& insertionCallback) const = 0; + + + /** + \brief Cooks and creates a bounding volume hierarchy without going through a stream. Convenience function for standalone objects. + + \note This method does the same as cookBVH, but the produced BVH is not stored + into a stream but is either directly inserted in PxPhysics, or created as a standalone + object. Use this method if you are unable to cook offline. + + \param[in] desc The BVH descriptor. + \return PxBVH pointer on success + + @see cookBVH() PxInsertionCallback + */ + PX_FORCE_INLINE PxBVH* createBVH(const PxBVHDesc& desc) const + { + return createBVH(desc, const_cast(*this).getStandaloneInsertionCallback()); + } + + /** + \brief Backward compatibility helper. Cooks and creates a bounding volume hierarchy without going through a stream. + + \param[in] desc The BVH descriptor. + \param[in] insertionCallback The insertion interface. + \return PxBVH pointer on success + @deprecated + */ + PX_DEPRECATED PX_FORCE_INLINE PxBVHStructure* createBVHStructure(const PxBVHStructureDesc& desc, PxInsertionCallback& insertionCallback) const + { + return createBVH(desc, insertionCallback); + } + + /** + \brief Gets standalone object insertion interface. + + This interface allows the creation of standalone objects that can exist without a PxPhysics or PxScene object. + + @see PxCooking::createTriangleMesh PxCooking::createHeightfield PxCooking::createTetrahedronMesh PxCooking::createBVH + */ + virtual PxInsertionCallback& getStandaloneInsertionCallback() = 0; + protected: virtual ~PxCooking(){} }; @@ -547,17 +878,100 @@ same executable as cooking, you should pass the Physics's copy of foundation (ac PxPhysics::getFoundation()) to the cooker. This will also ensure correct handling of memory for objects passed from the cooker to the SDK. -To use cooking in standalone mode, create an instance of the Foundation object with PxCreateCookingFoundation. +To use cooking in standalone mode, create an instance of the Foundation object with PxCreateFoundation. You should pass the same foundation object to all instances of the cooking interface. -\param[in] version the SDK version number -\param[in] foundation the foundation object associated with this instance of the cooking interface. -\param[in] params the parameters for this instance of the cooking interface +\param[in] version The SDK version number +\param[in] foundation The foundation object associated with this instance of the cooking interface. +\param[in] params The parameters for this instance of the cooking interface \return true on success. +@deprecated */ -PX_C_EXPORT PX_PHYSX_COOKING_API physx::PxCooking* PX_CALL_CONV PxCreateCooking(physx::PxU32 version, +PX_C_EXPORT PX_PHYSX_COOKING_API PX_DEPRECATED physx::PxCooking* PX_CALL_CONV PxCreateCooking(physx::PxU32 version, physx::PxFoundation& foundation, const physx::PxCookingParams& params); + + + +// Immediate cooking + +PX_C_EXPORT PX_PHYSX_COOKING_API physx::PxInsertionCallback* PxGetStandaloneInsertionCallback(); + +// BVH +PX_C_EXPORT PX_PHYSX_COOKING_API bool PxCookBVH(const physx::PxBVHDesc& desc, physx::PxOutputStream& stream); +PX_C_EXPORT PX_PHYSX_COOKING_API physx::PxBVH* PxCreateBVH(const physx::PxBVHDesc& desc, physx::PxInsertionCallback& insertionCallback); + +PX_FORCE_INLINE physx::PxBVH* PxCreateBVH(const physx::PxBVHDesc& desc) +{ + return PxCreateBVH(desc, *PxGetStandaloneInsertionCallback()); +} + +// Heightfield +PX_C_EXPORT PX_PHYSX_COOKING_API bool PxCookHeightField(const physx::PxHeightFieldDesc& desc, physx::PxOutputStream& stream); +PX_C_EXPORT PX_PHYSX_COOKING_API physx::PxHeightField* PxCreateHeightField(const physx::PxHeightFieldDesc& desc, physx::PxInsertionCallback& insertionCallback); + +PX_FORCE_INLINE physx::PxHeightField* PxCreateHeightField(const physx::PxHeightFieldDesc& desc) +{ + return PxCreateHeightField(desc, *PxGetStandaloneInsertionCallback()); +} + +// Convex meshes +PX_C_EXPORT PX_PHYSX_COOKING_API bool PxCookConvexMesh(const physx::PxCookingParams& params, const physx::PxConvexMeshDesc& desc, physx::PxOutputStream& stream, physx::PxConvexMeshCookingResult::Enum* condition=NULL); +PX_C_EXPORT PX_PHYSX_COOKING_API physx::PxConvexMesh* PxCreateConvexMesh(const physx::PxCookingParams& params, const physx::PxConvexMeshDesc& desc, physx::PxInsertionCallback& insertionCallback, physx::PxConvexMeshCookingResult::Enum* condition=NULL); + +PX_FORCE_INLINE physx::PxConvexMesh* PxCreateConvexMesh(const physx::PxCookingParams& params, const physx::PxConvexMeshDesc& desc) +{ + return PxCreateConvexMesh(params, desc, *PxGetStandaloneInsertionCallback()); +} + +PX_C_EXPORT PX_PHYSX_COOKING_API bool PxValidateConvexMesh(const physx::PxCookingParams& params, const physx::PxConvexMeshDesc& desc); +PX_C_EXPORT PX_PHYSX_COOKING_API bool PxComputeHullPolygons(const physx::PxCookingParams& params, const physx::PxSimpleTriangleMesh& mesh, physx::PxAllocatorCallback& inCallback, physx::PxU32& nbVerts, physx::PxVec3*& vertices, + physx::PxU32& nbIndices, physx::PxU32*& indices, physx::PxU32& nbPolygons, physx::PxHullPolygon*& hullPolygons); + +// Triangle meshes +PX_C_EXPORT PX_PHYSX_COOKING_API bool PxValidateTriangleMesh(const physx::PxCookingParams& params, const physx::PxTriangleMeshDesc& desc); +PX_C_EXPORT PX_PHYSX_COOKING_API physx::PxTriangleMesh* PxCreateTriangleMesh(const physx::PxCookingParams& params, const physx::PxTriangleMeshDesc& desc, physx::PxInsertionCallback& insertionCallback, physx::PxTriangleMeshCookingResult::Enum* condition=NULL); +PX_C_EXPORT PX_PHYSX_COOKING_API bool PxCookTriangleMesh(const physx::PxCookingParams& params, const physx::PxTriangleMeshDesc& desc, physx::PxOutputStream& stream, physx::PxTriangleMeshCookingResult::Enum* condition=NULL); + +PX_FORCE_INLINE physx::PxTriangleMesh* PxCreateTriangleMesh(const physx::PxCookingParams& params, const physx::PxTriangleMeshDesc& desc) +{ + return PxCreateTriangleMesh(params, desc, *PxGetStandaloneInsertionCallback()); +} + +// Tetrahedron & soft body meshes +PX_C_EXPORT PX_PHYSX_COOKING_API bool PxCookTetrahedronMesh(const physx::PxCookingParams& params, const physx::PxTetrahedronMeshDesc& meshDesc, physx::PxOutputStream& stream); +PX_C_EXPORT PX_PHYSX_COOKING_API physx::PxTetrahedronMesh* PxCreateTetrahedronMesh(const physx::PxCookingParams& params, const physx::PxTetrahedronMeshDesc& meshDesc, physx::PxInsertionCallback& insertionCallback); + +PX_FORCE_INLINE physx::PxTetrahedronMesh* PxCreateTetrahedronMesh(const physx::PxCookingParams& params, const physx::PxTetrahedronMeshDesc& meshDesc) +{ + return PxCreateTetrahedronMesh(params, meshDesc, *PxGetStandaloneInsertionCallback()); +} + +PX_C_EXPORT PX_PHYSX_COOKING_API bool PxCookSoftBodyMesh(const physx::PxCookingParams& params, const physx::PxTetrahedronMeshDesc& simulationMeshDesc, const physx::PxTetrahedronMeshDesc& collisionMeshDesc, + const physx::PxSoftBodySimulationDataDesc& softbodyDataDesc, physx::PxOutputStream& stream); + +PX_C_EXPORT PX_PHYSX_COOKING_API physx::PxSoftBodyMesh* PxCreateSoftBodyMesh(const physx::PxCookingParams& params, const physx::PxTetrahedronMeshDesc& simulationMeshDesc, const physx::PxTetrahedronMeshDesc& collisionMeshDesc, + const physx::PxSoftBodySimulationDataDesc& softbodyDataDesc, physx::PxInsertionCallback& insertionCallback); + +PX_FORCE_INLINE physx::PxSoftBodyMesh* PxCreateSoftBodyMesh(const physx::PxCookingParams& params, const physx::PxTetrahedronMeshDesc& simulationMeshDesc, const physx::PxTetrahedronMeshDesc& collisionMeshDesc, + const physx::PxSoftBodySimulationDataDesc& softbodyDataDesc) +{ + return PxCreateSoftBodyMesh(params, simulationMeshDesc, collisionMeshDesc, softbodyDataDesc, *PxGetStandaloneInsertionCallback()); +} + +PX_C_EXPORT PX_PHYSX_COOKING_API physx::PxCollisionMeshMappingData* PxComputeModelsMapping(const physx::PxCookingParams& params, physx::PxTetrahedronMeshData& simulationMesh, const physx::PxTetrahedronMeshData& collisionMesh, + const physx::PxSoftBodyCollisionData& collisionData, const physx::PxBoundedData* vertexToTet = NULL); + +PX_C_EXPORT PX_PHYSX_COOKING_API physx::PxCollisionTetrahedronMeshData* PxComputeCollisionData(const physx::PxCookingParams& params, const physx::PxTetrahedronMeshDesc& collisionMeshDesc); + +PX_C_EXPORT PX_PHYSX_COOKING_API physx::PxSimulationTetrahedronMeshData* PxComputeSimulationData(const physx::PxCookingParams& params, const physx::PxTetrahedronMeshDesc& simulationMeshDesc); + +PX_C_EXPORT PX_PHYSX_COOKING_API physx::PxSoftBodyMesh* PxAssembleSoftBodyMesh(physx::PxTetrahedronMeshData& simulationMesh, physx::PxSoftBodySimulationData& simulationData, physx::PxTetrahedronMeshData& collisionMesh, + physx::PxSoftBodyCollisionData& collisionData, physx::PxCollisionMeshMappingData& mappingData, physx::PxInsertionCallback& insertionCallback); + +PX_C_EXPORT PX_PHYSX_COOKING_API physx::PxSoftBodyMesh* PxAssembleSoftBodyMesh_Sim(physx::PxSimulationTetrahedronMeshData& simulationMesh, physx::PxCollisionTetrahedronMeshData& collisionMesh, + physx::PxCollisionMeshMappingData& mappingData, physx::PxInsertionCallback& insertionCallback); + /** @} */ #endif diff --git a/Source/ThirdParty/PhysX/cooking/PxCookingInternal.h b/Source/ThirdParty/PhysX/cooking/PxCookingInternal.h new file mode 100644 index 000000000..73972a87d --- /dev/null +++ b/Source/ThirdParty/PhysX/cooking/PxCookingInternal.h @@ -0,0 +1,56 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_COOKING_INTERNAL_H +#define PX_COOKING_INTERNAL_H +/** \addtogroup cooking +@{ +*/ + +#include "cooking/PxCooking.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + struct PxTriangleMeshInternalData; + struct PxBVHInternalData; + class PxTriangleMesh; + class PxBVH; + +#if !PX_DOXYGEN +} // namespace physx +#endif + + PX_C_EXPORT PX_PHYSX_COOKING_API physx::PxTriangleMesh* PX_CALL_CONV PxCreateTriangleMeshInternal(const physx::PxTriangleMeshInternalData& data, const physx::PxCooking& cooking); + + PX_C_EXPORT PX_PHYSX_COOKING_API physx::PxBVH* PX_CALL_CONV PxCreateBVHInternal(const physx::PxBVHInternalData& data, const physx::PxCooking& cooking); + +/** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/cooking/PxMidphaseDesc.h b/Source/ThirdParty/PhysX/cooking/PxMidphaseDesc.h index fda59c996..ee63e01c1 100644 --- a/Source/ThirdParty/PhysX/cooking/PxMidphaseDesc.h +++ b/Source/ThirdParty/PhysX/cooking/PxMidphaseDesc.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,11 +22,10 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - #ifndef PX_MIDPHASE_DESC_H #define PX_MIDPHASE_DESC_H /** \addtogroup cooking @@ -52,7 +50,7 @@ namespace physx class PxMidphaseDesc { public: - PX_FORCE_INLINE PxMidphaseDesc() { setToDefault(PxMeshMidPhase::eBVH33); } + PX_FORCE_INLINE PxMidphaseDesc() { setToDefault(PxMeshMidPhase::eBVH34); } /** \brief Returns type of midphase mesh structure. @@ -100,7 +98,11 @@ public: return false; } - PX_FORCE_INLINE PxMidphaseDesc& operator=(PxMeshMidPhase::Enum descType) + /** + \brief Assignment operator + \return this + */ + PX_FORCE_INLINE PxMidphaseDesc& operator=(PxMeshMidPhase::Enum descType) { setToDefault(descType); return *this; @@ -116,4 +118,5 @@ protected: /** @} */ -#endif // PX_MIDPHASE_DESC_UNION_H +#endif + diff --git a/Source/ThirdParty/PhysX/cooking/PxSDFDesc.h b/Source/ThirdParty/PhysX/cooking/PxSDFDesc.h new file mode 100644 index 000000000..4f37a2ad0 --- /dev/null +++ b/Source/ThirdParty/PhysX/cooking/PxSDFDesc.h @@ -0,0 +1,196 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_SDF_DESC_H +#define PX_SDF_DESC_H +/** \addtogroup cooking +@{ +*/ + +#include "PxPhysXConfig.h" +#include "geometry/PxSimpleTriangleMesh.h" +#include "foundation/PxBounds3.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + /** + \brief A helper structure to define dimensions in 3D + */ + struct PxDim3 + { + PxU32 x, y, z; + }; + + /** + \brief Defines the number of bits per subgrid pixel + */ + class PxSdfBitsPerSubgridPixel + { + public: + enum Enum + { + e8_BIT_PER_PIXEL = 1, //!< 8 bit per subgrid pixel (values will be stored as normalized integers) + e16_BIT_PER_PIXEL = 2, //!< 16 bit per subgrid pixel (values will be stored as normalized integers) + e32_BIT_PER_PIXEL = 4 //!< 32 bit per subgrid pixel (values will be stored as floats in world scale units) + }; + }; + + /** + \brief A structure describing signed distance field for mesh. + */ + class PxSDFDesc + { + public: + + /** + \brief Pointer to first sdf array element. + */ + PxBoundedData sdf; + + /** + \brief Dimensions of sdf + */ + PxDim3 dims; + + /** + \brief The Lower bound of the original mesh + */ + PxVec3 meshLower; + + /** + \brief The spacing of each sdf voxel + */ + PxReal spacing; + + + /** + \brief The number of cells in a sparse subgrid block (full block has subgridSize^3 cells and (subgridSize+1)^3 samples). If set to zero, this indicates that only a dense background grid SDF is used without sparse blocks + */ + PxU32 subgridSize; + + /** + \brief Enumeration that defines the number of bits per subgrid pixel (either 32, 16 or 8bits) + */ + PxSdfBitsPerSubgridPixel::Enum bitsPerSubgridPixel; + + /** + \brief Number of subgrid blocks in the 3d texture. The full texture dimension will be sdfSubgrids3DTexBlockDim*(subgridSize+1). + */ + PxDim3 sdfSubgrids3DTexBlockDim; + + /** + \brief The data to create the 3d texture containg the packed subgrid blocks. Stored as PxU8 to support multiple formats (8, 16 and 32 bits per pixel) + */ + PxBoundedData sdfSubgrids; + + /** + \brief Array with start indices into the subgrid texture for every subgrid block. 10bits for z coordinate, 10bits for y and 10bits for x. Encoding is as follows: slot = (z << 20) | (y << 10) | x + */ + PxBoundedData sdfStartSlots; + + /** + \brief The minimum value over all subgrid blocks. Used if normalized textures are used which is the case for 8 and 16bit formats + */ + PxReal subgridsMinSdfValue; + + /** + \brief The maximum value over all subgrid blocks. Used if normalized textures are used which is the case for 8 and 16bit formats + */ + PxReal subgridsMaxSdfValue; + + /** + \brief The bounds of the sdf. If left unassigned (empty), the bounds of the mesh will be used + */ + PxBounds3 sdfBounds; + + /** + \brief Narrow band thickness as a fraction of the bounds diagonal length. Every subgrid block that + overlaps with the narrow band around the mesh surface will be kept providing high resultion around the mesh surface. + The valid range of this parameter is (0, 1). The higher the value, the more subgrids will get created, the more memory will be required. + */ + PxReal narrowBandThicknessRelativeToSdfBoundsDiagonal; + + /** + \brief The number of threads that are launched to compute the signed distance field + */ + PxU32 numThreadsForSdfConstruction; + + /** + \brief Constructor + */ + PX_INLINE PxSDFDesc(); + + /** + \brief Returns true if the descriptor is valid. + \return true if the current settings are valid + */ + PX_INLINE bool isValid() const; + }; + + PX_INLINE PxSDFDesc::PxSDFDesc() + { + sdf.data = NULL; + dims.x = 0; + dims.y = 0; + dims.z = 0; + spacing = 0; + meshLower = PxVec3(PxZero); + subgridSize = 0; + subgridsMinSdfValue = 0.0f; + subgridsMaxSdfValue = 0.0f; + sdfBounds = PxBounds3::empty(); + bitsPerSubgridPixel = PxSdfBitsPerSubgridPixel::e16_BIT_PER_PIXEL; + narrowBandThicknessRelativeToSdfBoundsDiagonal = 0.01f; + numThreadsForSdfConstruction = 1; + } + + PX_INLINE bool PxSDFDesc::isValid() const + { + // Check validity of user's input(if any) + if (sdf.data) + { + if (dims.x < 1 || dims.y < 1 || dims.z < 1) + return false; + if (!meshLower.isFinite()) + return false; + if (spacing <= 0) + return false; + } + + return true; + } + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/cooking/PxTetrahedronMeshDesc.h b/Source/ThirdParty/PhysX/cooking/PxTetrahedronMeshDesc.h new file mode 100644 index 000000000..5d68d02d0 --- /dev/null +++ b/Source/ThirdParty/PhysX/cooking/PxTetrahedronMeshDesc.h @@ -0,0 +1,233 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_TETRAHEDRON_MESH_DESC_H +#define PX_TETRAHEDRON_MESH_DESC_H +/** \addtogroup cooking +@{ +*/ + +#include "PxPhysXConfig.h" +#include "foundation/PxVec3.h" +#include "foundation/PxFlags.h" +#include "common/PxCoreUtilityTypes.h" +#include "geometry/PxSimpleTriangleMesh.h" +#include "foundation/PxArray.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + /** + \brief Descriptor class for #PxTetrahedronMesh (contains only pure geometric data). + + @see PxTetrahedronMesh PxShape + */ + class PxTetrahedronMeshDesc + { + public: + + /** + \brief Defines the tetrahedron structure of a mesh. + */ + enum PxMeshFormat + { + eTET_MESH, //!< Normal tetmesh with arbitrary tetrahedra + eHEX_MESH //!< 6 tetrahedra in a row will form a hexahedron + }; + + + /** + Optional pointer to first material index, or NULL. There are PxTetrahedronMesh::numTriangles indices in total. + Caller may add materialIndexStride bytes to the pointer to access the next triangle. + + When a tetrahedron mesh collides with another object, a material is required at the collision point. + If materialIndices is NULL, then the material of the PxShape instance is used. + Otherwise, if the point of contact is on a tetrahedron with index i, then the material index is determined as: + PxFEMMaterialTableIndex index = *(PxFEMMaterialTableIndex *)(((PxU8*)materialIndices) + materialIndexStride * i); + + If the contact point falls on a vertex or an edge, a tetrahedron adjacent to the vertex or edge is selected, and its index + used to look up a material. The selection is arbitrary but consistent over time. + + Default: NULL + + @see materialIndexStride + */ + PxTypedStridedData materialIndices; + + /** + \brief Pointer to first vertex point. + */ + PxBoundedData points; + + /** + \brief Pointer to first tetrahedron. + + Caller may add tetrhedronStrideBytes bytes to the pointer to access the next tetrahedron. + + These are quadruplets of 0 based indices: + vert0 vert1 vert2 vert3 + vert0 vert1 vert2 vert3 + vert0 vert1 vert2 vert3 + ... + + where vertex is either a 32 or 16 bit unsigned integer. There are numTetrahedrons*4 indices. + + This is declared as a void pointer because it is actually either an PxU16 or a PxU32 pointer. + */ + PxBoundedData tetrahedrons; + + + /** + \brief Flags bits, combined from values of the enum ::PxMeshFlag + */ + PxMeshFlags flags; + + /** + \brief Used for simulation meshes only. Defines if this tet mesh should be simulated as a tet mesh, + or if a set of tetrahedra should be used to represent another shape, e.g. a hexahedral mesh constructed + from 6 elements. + */ + PxU16 tetsPerElement; + + /** + \brief Constructor to build an empty tetmesh description + */ + PxTetrahedronMeshDesc() + { + points.count = 0; + points.stride = 0; + points.data = NULL; + + tetrahedrons.count = 0; + tetrahedrons.stride = 0; + tetrahedrons.data = NULL; + + tetsPerElement = 1; + } + + /** + \brief Constructor to build a tetmeshdescription that links to the vertices and indices provided + */ + PxTetrahedronMeshDesc(physx::PxArray& meshVertices, physx::PxArray& meshTetIndices, const PxTetrahedronMeshDesc::PxMeshFormat meshFormat = eTET_MESH) + { + points.count = meshVertices.size(); + points.stride = sizeof(float) * 3; + points.data = meshVertices.begin(); + + tetrahedrons.count = meshTetIndices.size() / 4; + tetrahedrons.stride = sizeof(int) * 4; + tetrahedrons.data = meshTetIndices.begin(); + + if (meshFormat == eTET_MESH) + tetsPerElement = 1; + else + tetsPerElement = 6; + } + + PX_INLINE bool isValid() const + { + // Check geometry of the collision mesh + if (points.count < 4) //at least 1 tetrahedron's worth of points + return false; + if ((!tetrahedrons.data) && (points.count % 4)) // Non-indexed mesh => we must ensure the geometry defines an implicit number of tetrahedrons // i.e. numVertices can't be divided by 4 + return false; + if (points.count > 0xffff && flags & PxMeshFlag::e16_BIT_INDICES) + return false; + if (!points.data) + return false; + if (points.stride < sizeof(PxVec3)) //should be at least one point's worth of data + return false; + + //add more validity checks here + if (materialIndices.data && materialIndices.stride < sizeof(PxFEMMaterialTableIndex)) + return false; + + // The tetrahedrons pointer is not mandatory + if (tetrahedrons.data) + { + // Indexed collision mesh + PxU32 limit = (flags & PxMeshFlag::e16_BIT_INDICES) ? sizeof(PxU16) * 4 : sizeof(PxU32) * 4; + if (tetrahedrons.stride < limit) + return false; + } + + //The model can only be either a tetmesh (1 tet per element), or have 5 or 6 tets per hex element, otherwise invalid. + if (tetsPerElement != 1 && tetsPerElement != 6) + return false; + + return true; + } + }; + + ///** + //\brief Descriptor class for #PxSoftBodyMesh (contains only additional data used for softbody simulation). + + //@see PxSoftBodyMesh PxShape + //*/ + class PxSoftBodySimulationDataDesc + { + public: + /** + \brief Pointer to first index of tetrahedron that contains the vertex at the same location in the vertex buffer. + if left unassigned it will be computed automatically. If a point is inside multiple tetrahedra (ambiguous case), the frist one found will be taken. + */ + PxBoundedData vertexToTet; + + /** + \brief Constructor to build an empty simulation description + */ + PxSoftBodySimulationDataDesc() + { + vertexToTet.count = 0; + vertexToTet.stride = 0; + vertexToTet.data = NULL; + } + + /** + \brief Constructor to build a simulation description with a defined vertex to tetrahedron mapping + */ + PxSoftBodySimulationDataDesc(physx::PxArray& vertToTet) + { + vertexToTet.count = vertToTet.size(); + vertexToTet.stride = sizeof(PxI32); + vertexToTet.data = vertToTet.begin(); + } + + PX_INLINE bool isValid() const + { + return true; + } + }; + +#if !PX_DOXYGEN +} // namespace physx +#endif + + /** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/cooking/PxTriangleMeshDesc.h b/Source/ThirdParty/PhysX/cooking/PxTriangleMeshDesc.h index d3b8ea6d4..10f52913d 100644 --- a/Source/ThirdParty/PhysX/cooking/PxTriangleMeshDesc.h +++ b/Source/ThirdParty/PhysX/cooking/PxTriangleMeshDesc.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,25 +22,26 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_COLLISION_NXTRIANGLEMESHDESC -#define PX_COLLISION_NXTRIANGLEMESHDESC +#ifndef PX_TRIANGLE_MESH_DESC_H +#define PX_TRIANGLE_MESH_DESC_H /** \addtogroup cooking @{ */ #include "PxPhysXConfig.h" #include "geometry/PxSimpleTriangleMesh.h" +#include "PxSDFDesc.h" #if !PX_DOXYGEN namespace physx { #endif + /** \brief Descriptor class for #PxTriangleMesh. @@ -73,10 +73,17 @@ public: */ PxTypedStridedData materialIndices; + /** + \brief SDF descriptor. When this descriptor is set, signed distance field is calculated for this convex mesh. + + Default: NULL + */ + PxSDFDesc* sdfDesc; + /** \brief Constructor sets to default. */ - PX_INLINE PxTriangleMeshDesc(); + PX_INLINE PxTriangleMeshDesc(); /** \brief (re)sets the structure to the default. @@ -90,9 +97,11 @@ public: PX_INLINE bool isValid() const; }; + PX_INLINE PxTriangleMeshDesc::PxTriangleMeshDesc() //constructor sets to default { - PxSimpleTriangleMesh::setToDefault(); + PxSimpleTriangleMesh::setToDefault(); + sdfDesc = NULL; } PX_INLINE void PxTriangleMeshDesc::setToDefault() @@ -109,9 +118,14 @@ PX_INLINE bool PxTriangleMeshDesc::isValid() const //add more validity checks here if (materialIndices.data && materialIndices.stride < sizeof(PxMaterialTableIndex)) return false; + + if (sdfDesc && !sdfDesc->isValid()) + return false; + return PxSimpleTriangleMesh::isValid(); } + #if !PX_DOXYGEN } // namespace physx #endif diff --git a/Source/ThirdParty/PhysX/cooking/Pxc.h b/Source/ThirdParty/PhysX/cooking/Pxc.h index ab28adf00..d7dc67826 100644 --- a/Source/ThirdParty/PhysX/cooking/Pxc.h +++ b/Source/ThirdParty/PhysX/cooking/Pxc.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,19 +22,18 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_COOKING_NX -#define PX_COOKING_NX +#ifndef PXC_H +#define PXC_H #include "foundation/Px.h" // define API function declaration #if !defined PX_PHYSX_STATIC_LIB - #if (PX_WINDOWS_FAMILY || PX_XBOXONE || PX_PS4) + #if (PX_WINDOWS_FAMILY || PX_PS4 || PX_PS5) #if defined PX_PHYSX_COOKING_EXPORTS #define PX_PHYSX_COOKING_API __declspec(dllexport) #else diff --git a/Source/ThirdParty/PhysX/cudamanager/PxCudaContext.h b/Source/ThirdParty/PhysX/cudamanager/PxCudaContext.h new file mode 100644 index 000000000..15e192691 --- /dev/null +++ b/Source/ThirdParty/PhysX/cudamanager/PxCudaContext.h @@ -0,0 +1,182 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. + +#ifndef PX_CUDA_CONTEX_H +#define PX_CUDA_CONTEX_H + +#include "foundation/PxPreprocessor.h" + +#if PX_SUPPORT_GPU_PHYSX + +#include "PxCudaTypes.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + struct PxCudaKernelParam + { + void* data; + size_t size; + }; + + // workaround for not being able to forward declare enums in PxCudaTypes.h. + // provides different automatic casting depending on whether cuda.h was included beforehand or not. + template + struct PxCUenum + { + PxU32 value; + + PxCUenum(CUenum e) { value = PxU32(e); } + operator CUenum() const { return CUenum(value); } + }; + +#ifdef CUDA_VERSION + typedef PxCUenum PxCUjit_option; + typedef PxCUenum PxCUresult; +#else + typedef PxCUenum PxCUjit_option; + typedef PxCUenum PxCUresult; +#endif + +#define PX_CUDA_KERNEL_PARAM(X) { (void*)&X, sizeof(X) } +#define PX_CUDA_KERNEL_PARAM2(X) (void*)&X + + class PxDeviceAllocatorCallback; + /** + Cuda Context + */ + class PxCudaContext + { + protected: + virtual ~PxCudaContext() {} + + PxDeviceAllocatorCallback* mAllocatorCallback; + + public: + virtual void release() = 0; + + virtual PxCUresult memAlloc(CUdeviceptr *dptr, size_t bytesize) = 0; + + virtual PxCUresult memFree(CUdeviceptr dptr) = 0; + + virtual PxCUresult memHostAlloc(void **pp, size_t bytesize, unsigned int Flags) = 0; + + virtual PxCUresult memFreeHost(void *p) = 0; + + virtual PxCUresult memHostGetDevicePointer(CUdeviceptr *pdptr, void *p, unsigned int Flags) = 0; + + virtual PxCUresult moduleLoadDataEx(CUmodule *module, const void *image, unsigned int numOptions, PxCUjit_option *options, void **optionValues) = 0; + + virtual PxCUresult moduleGetFunction(CUfunction *hfunc, CUmodule hmod, const char *name) = 0; + + virtual PxCUresult moduleUnload(CUmodule hmod) = 0; + + virtual PxCUresult streamCreate(CUstream *phStream, unsigned int Flags) = 0; + + virtual PxCUresult streamCreateWithPriority(CUstream *phStream, unsigned int flags, int priority) = 0; + + virtual PxCUresult streamFlush(CUstream hStream) = 0; + + virtual PxCUresult streamWaitEvent(CUstream hStream, CUevent hEvent, unsigned int Flags) = 0; + + virtual PxCUresult streamDestroy(CUstream hStream) = 0; + + virtual PxCUresult streamSynchronize(CUstream hStream) = 0; + + virtual PxCUresult eventCreate(CUevent *phEvent, unsigned int Flags) = 0; + + virtual PxCUresult eventRecord(CUevent hEvent, CUstream hStream) = 0; + + virtual PxCUresult eventQuery(CUevent hEvent) = 0; + + virtual PxCUresult eventSynchronize(CUevent hEvent) = 0; + + virtual PxCUresult eventDestroy(CUevent hEvent) = 0; + + virtual PxCUresult launchKernel( + CUfunction f, + unsigned int gridDimX, + unsigned int gridDimY, + unsigned int gridDimZ, + unsigned int blockDimX, + unsigned int blockDimY, + unsigned int blockDimZ, + unsigned int sharedMemBytes, + CUstream hStream, + PxCudaKernelParam* kernelParams, + size_t kernelParamsSizeInBytes, + void** extra = NULL + ) = 0; + + // PT: same as above but without copying the kernel params to a local stack before the launch + // i.e. the kernelParams data is passed directly to the kernel. + virtual PxCUresult launchKernel( + CUfunction f, + PxU32 gridDimX, PxU32 gridDimY, PxU32 gridDimZ, + PxU32 blockDimX, PxU32 blockDimY, PxU32 blockDimZ, + PxU32 sharedMemBytes, + CUstream hStream, + void** kernelParams, + void** extra = NULL + ) = 0; + + virtual PxCUresult memcpyDtoH(void *dstHost, CUdeviceptr srcDevice, size_t ByteCount) = 0; + + virtual PxCUresult memcpyDtoHAsync(void *dstHost, CUdeviceptr srcDevice, size_t ByteCount, CUstream hStream) = 0; + + virtual PxCUresult memcpyHtoD(CUdeviceptr dstDevice, const void *srcHost, size_t ByteCount) = 0; + + virtual PxCUresult memcpyHtoDAsync(CUdeviceptr dstDevice, const void *srcHost, size_t ByteCount, CUstream hStream) = 0; + + virtual PxCUresult memcpyDtoDAsync(CUdeviceptr dstDevice, CUdeviceptr srcDevice, size_t ByteCount, CUstream hStream) = 0; + + virtual PxCUresult memcpyDtoD(CUdeviceptr dstDevice, CUdeviceptr srcDevice, size_t ByteCount) = 0; + + virtual PxCUresult memcpyPeerAsync(CUdeviceptr dstDevice, CUcontext dstContext, CUdeviceptr srcDevice, CUcontext srcContext, size_t ByteCount, CUstream hStream) = 0; + + virtual PxCUresult memsetD32Async(CUdeviceptr dstDevice, unsigned int ui, size_t N, CUstream hStream) = 0; + + virtual PxCUresult memsetD8Async(CUdeviceptr dstDevice, unsigned char uc, size_t N, CUstream hStream) = 0; + + virtual PxCUresult memsetD32(CUdeviceptr dstDevice, unsigned int ui, size_t N) = 0; + + virtual PxCUresult memsetD16(CUdeviceptr dstDevice, unsigned short uh, size_t N) = 0; + + virtual PxCUresult memsetD8(CUdeviceptr dstDevice, unsigned char uc, size_t N) = 0; + + virtual PxCUresult getLastError() = 0; + + PxDeviceAllocatorCallback* getAllocatorCallback() { return mAllocatorCallback; } + }; + +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif // PX_SUPPORT_GPU_PHYSX +#endif + diff --git a/Source/ThirdParty/PhysX/cudamanager/PxCudaContextManager.h b/Source/ThirdParty/PhysX/cudamanager/PxCudaContextManager.h index dbf6a021c..49aa0dfc2 100644 --- a/Source/ThirdParty/PhysX/cudamanager/PxCudaContextManager.h +++ b/Source/ThirdParty/PhysX/cudamanager/PxCudaContextManager.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,11 +22,10 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. - -#ifndef PXCUDACONTEXTMANAGER_PXCUDACONTEXTMANAGER_H -#define PXCUDACONTEXTMANAGER_PXCUDACONTEXTMANAGER_H +#ifndef PX_CUDA_CONTEXT_MANAGER_H +#define PX_CUDA_CONTEXT_MANAGER_H #include "foundation/PxPreprocessor.h" @@ -36,17 +34,16 @@ #include "foundation/PxSimpleTypes.h" #include "foundation/PxErrorCallback.h" #include "foundation/PxFlags.h" -#include "task/PxTaskDefine.h" -#include "cudamanager/PxCudaMemoryManager.h" -/* Forward decl to avoid inclusion of cuda.h */ -typedef struct CUctx_st *CUcontext; -typedef struct CUgraphicsResource_st *CUgraphicsResource; -typedef int CUdevice; +#include "PxCudaTypes.h" +#if !PX_DOXYGEN namespace physx -{ - +{ +#endif + +class PxCudaContext; + /** \brief Possible graphic/CUDA interoperability modes for context */ struct PxCudaInteropMode { @@ -76,6 +73,31 @@ struct PxCudaInteropRegisterFlag }; }; +/** +\brief An interface class that the user can implement in order for PhysX to use a user-defined device memory allocator. +*/ +class PxDeviceAllocatorCallback +{ +public: + + /** + \brief Allocated device memory. + \param[in] ptr Pointer to store the allocated address + \param[in] size The amount of memory required + \return A boolean indicates the operation succeed or fail + */ + virtual bool memAlloc(void** ptr, size_t size) = 0; + + /** + \brief Frees device memory. + \param[in] ptr The memory to free + \return A boolean indicates the operation succeed or fail + */ + virtual bool memFree(void* ptr) = 0; + +protected: + virtual ~PxDeviceAllocatorCallback() {} +}; /** \brief collection of set bits defined in NxCudaInteropRegisterFlag. @@ -104,12 +126,8 @@ public: * If the user provides a context for the PxCudaContextManager, the context * _must_ have either been created on the GPU ordinal returned by * PxGetSuggestedCudaDeviceOrdinal() or on your graphics device. - * - * It is perfectly acceptable to allocate device or host pinned memory from - * the context outside the scope of the PxCudaMemoryManager, so long as you - * manage its eventual cleanup. */ - CUcontext *ctx; + CUcontext* ctx; /** * \brief D3D device pointer or OpenGl context handle @@ -118,9 +136,8 @@ public: * created. In that case, the created context will be bound to this * graphics device. */ - void *graphicsDevice; + void* graphicsDevice; -#if PX_SUPPORT_GPU_PHYSX /** * \brief Application-specific GUID * @@ -128,9 +145,18 @@ public: * so that patches for new architectures can be released for your game.You can obtain a GUID for your * application from Nvidia. */ - const char* appGUID; -#endif - /** + const char* appGUID; + + /** + * \brief Application-specific device memory allocator + * + * the application can implement an device memory allocator, which inherites PxDeviceAllocatorCallback, and + * pass that to the PxCudaContextManagerDesc. The SDK will use that allocator to allocate device memory instead of + * using the defaul CUDA device memory allocator. + */ + PxDeviceAllocatorCallback* deviceAllocator; + + /** * \brief The CUDA/Graphics interop mode of this context * * If ctx is NULL, this value describes the nature of the graphicsDevice @@ -139,75 +165,189 @@ public: */ PxCudaInteropMode::Enum interopMode; - - /** - * \brief Size of persistent memory - * - * This memory is allocated up front and stays allocated until the - * PxCudaContextManager is released. Size is in bytes, has to be power of two - * and bigger than the page size. Set to 0 to only use dynamic pages. - * - * Note: On Vista O/S and above, there is a per-memory allocation overhead - * to every CUDA work submission, so we recommend that you carefully tune - * this initial base memory size to closely approximate the amount of - * memory your application will consume. - - Note: This is currently not used by PxSceneFlag::eENABLE_GPU_DYNAMICS. Memory allocation properties are configured - for GPU rigid bodies using PxSceneDesc::gpuDynamicsConfig. - */ - uint32_t memoryBaseSize[PxCudaBufferMemorySpace::COUNT]; - - /** - * \brief Size of memory pages - * - * The memory manager will dynamically grow and shrink in blocks multiple of - * this page size. Size has to be power of two and bigger than 0. - - Note: This is currently not used by PxSceneFlag::eENABLE_GPU_DYNAMICS. Memory allocation properties are configured - for GPU rigid bodies using PxSceneDesc::gpuDynamicsConfig. - */ - uint32_t memoryPageSize[PxCudaBufferMemorySpace::COUNT]; - - /** - * \brief Maximum size of memory that the memory manager will allocate - - Note: This is currently not used by PxSceneFlag::eENABLE_GPU_DYNAMICS. Memory allocation properties are configured - for GPU rigid bodies using PxSceneDesc::gpuDynamicsConfig. - */ - uint32_t maxMemorySize[PxCudaBufferMemorySpace::COUNT]; - - PX_INLINE PxCudaContextManagerDesc() + PX_INLINE PxCudaContextManagerDesc() : + ctx (NULL), + graphicsDevice (NULL), + appGUID (NULL), + deviceAllocator (NULL), + interopMode (PxCudaInteropMode::NO_INTEROP) { - ctx = NULL; - interopMode = PxCudaInteropMode::NO_INTEROP; - graphicsDevice = 0; -#if PX_SUPPORT_GPU_PHYSX - appGUID = NULL; -#endif - for(uint32_t i = 0; i < PxCudaBufferMemorySpace::COUNT; i++) - { - memoryBaseSize[i] = 0; - memoryPageSize[i] = 2 * 1024*1024; - maxMemorySize[i] = UINT32_MAX; - } } }; +/** +\brief A cuda kernel index providing an index to the cuda module and the function name +*/ +struct PxKernelIndex +{ + PxU32 moduleIndex; + const char* functionName; +}; /** - * \brief Manages memory, thread locks, and task scheduling for a CUDA context + * \brief Manages thread locks, and task scheduling for a CUDA context * * A PxCudaContextManager manages access to a single CUDA context, allowing it to - * be shared between multiple scenes. Memory allocations are dynamic: starting - * with an initial heap size and growing on demand by a configurable page size. - * The context must be acquired from the manager before using any CUDA APIs. + * be shared between multiple scenes. + * The context must be acquired from the manager before using any CUDA APIs unless stated differently. * - * The PxCudaContextManager is based on the CUDA driver API and explictly does not + * The PxCudaContextManager is based on the CUDA driver API and explicitly does not * support the CUDA runtime API (aka, CUDART). */ class PxCudaContextManager { public: + /** + * \brief Schedules clear operation for a device memory buffer on the specified stream + * + * The cuda context will get acquired automatically + */ + template + void clearDeviceBufferAsync(T* deviceBuffer, PxU32 numElements, CUstream stream, PxI32 value = 0) + { + clearDeviceBufferAsyncInternal(deviceBuffer, numElements * sizeof(T), stream, value); + } + + /** + * \brief Copies a device buffer to the host + * + * The cuda context will get acquired automatically + */ + template + void copyDToH(T* hostBuffer, const T* deviceBuffer, PxU32 numElements) + { + copyDToHInternal(hostBuffer, deviceBuffer, numElements * sizeof(T)); + } + + /** + * \brief Copies a host buffer to the device + * + * The cuda context will get acquired automatically + */ + template + void copyHToD(T* deviceBuffer, const T* hostBuffer, PxU32 numElements) + { + copyHToDInternal(deviceBuffer, hostBuffer, numElements * sizeof(T)); + } + + /** + * \brief Schedules device to host copy operation on the specified stream + * + * The cuda context will get acquired automatically + */ + template + void copyDToHAsync(T* hostBuffer, const T* deviceBuffer, PxU32 numElements, CUstream stream) + { + copyDToHAsyncInternal(hostBuffer, deviceBuffer, numElements * sizeof(T), stream); + } + + /** + * \brief Schedules host to device copy operation on the specified stream + * + * The cuda context will get acquired automatically + */ + template + void copyHToDAsync(T* deviceBuffer, const T* hostBuffer, PxU32 numElements, CUstream stream) + { + copyHToDAsyncInternal(deviceBuffer, hostBuffer, numElements * sizeof(T), stream); + } + + /** + * \brief Schedules device to device copy operation on the specified stream + * + * The cuda context will get acquired automatically + */ + template + void copyDToDAsync(T* dstDeviceBuffer, const T* srcDeviceBuffer, PxU32 numElements, CUstream stream) + { + copyDToDAsyncInternal(dstDeviceBuffer, srcDeviceBuffer, numElements * sizeof(T), stream); + } + + /** + * \brief Allocates a device buffer + * + * The cuda context will get acquired automatically + */ + template + void allocDeviceBuffer(T*& deviceBuffer, PxU32 numElements, const char* filename = __FILE__, PxI32 line = __LINE__) + { + void* ptr = allocDeviceBufferInternal(numElements * sizeof(T), filename, line); + deviceBuffer = reinterpret_cast(ptr); + } + + /** + * \brief Allocates a device buffer and returns the pointer to the memory + * + * The cuda context will get acquired automatically + */ + template + T* allocDeviceBuffer(PxU32 numElements, const char* filename = __FILE__, PxI32 line = __LINE__) + { + void* ptr = allocDeviceBufferInternal(numElements * sizeof(T), filename, line); + return reinterpret_cast(ptr); + } + + /** + * \brief Frees a device buffer + * + * The cuda context will get acquired automatically + */ + template + void freeDeviceBuffer(T*& deviceBuffer) + { + freeDeviceBufferInternal(deviceBuffer); + deviceBuffer = NULL; + } + + /** + * \brief Allocates a pinned host buffer + * + * A pinned host buffer can be used on the gpu after getting a mapped device pointer from the pinned host buffer pointer, see getMappedDevicePtr + * The cuda context will get acquired automatically + * @see getMappedDevicePtr + */ + template + void allocPinnedHostBuffer(T*& pinnedHostBuffer, PxU32 numElements, const char* filename = __FILE__, PxI32 line = __LINE__) + { + void* ptr = allocPinnedHostBufferInternal(numElements * sizeof(T), filename, line); + pinnedHostBuffer = reinterpret_cast(ptr); + } + + /** + * \brief Allocates a pinned host buffer and returns the pointer to the memory + * + * A pinned host buffer can be used on the gpu after getting a mapped device pointer from the pinned host buffer pointer, see getMappedDevicePtr + * The cuda context will get acquired automatically + * @see getMappedDevicePtr + */ + template + T* allocPinnedHostBuffer(PxU32 numElements, const char* filename = __FILE__, PxI32 line = __LINE__) + { + void* ptr = allocPinnedHostBufferInternal(numElements * sizeof(T), filename, line); + return reinterpret_cast(ptr); + } + + /** + * \brief Frees a pinned host buffer + * + * The cuda context will get acquired automatically + */ + template + void freePinnedHostBuffer(T*& pinnedHostBuffer) + { + freePinnedHostBufferInternal(pinnedHostBuffer); + pinnedHostBuffer = NULL; + } + + /** + * \brief Gets a mapped pointer from a pinned host buffer that can be used in cuda kernels directly + * + * Data access performance with a mapped pinned host pointer will be slower than using a device pointer directly + * but the changes done in the kernel will be available on the host immediately. + * The cuda context will get acquired automatically + */ + virtual CUdeviceptr getMappedDevicePtr(void* pinnedHostBuffer) = 0; + /** * \brief Acquire the CUDA context for the current thread * @@ -232,13 +372,10 @@ public: */ virtual CUcontext getContext() = 0; - /** - * \brief Return the PxCudaMemoryManager instance associated with this - * CUDA context - * Note: This is currently not used by PxSceneFlag::eENABLE_GPU_DYNAMICS. Memory allocation properties are configured - * for GPU rigid bodies using PxSceneDesc::gpuDynamicsConfig. - */ - virtual PxCudaMemoryManager *getMemoryManager() = 0; + /** + * \brief Return the CudaContext + */ + virtual PxCudaContext* getCudaContext() = 0; /** * \brief Context manager has a valid CUDA context @@ -298,7 +435,7 @@ public: * \param buffer [IN] GLuint buffer index to be mapped to cuda * \param flags [IN] cuda interop registration flags */ - virtual bool registerResourceInCudaGL(CUgraphicsResource &resource, uint32_t buffer, PxCudaInteropRegisterFlags flags = PxCudaInteropRegisterFlags()) = 0; + virtual bool registerResourceInCudaGL(CUgraphicsResource& resource, uint32_t buffer, PxCudaInteropRegisterFlags flags = PxCudaInteropRegisterFlags()) = 0; /** * \brief Register a rendering resource with CUDA @@ -320,7 +457,7 @@ public: * \param resourcePointer [IN] A pointer to either IDirect3DResource9, or ID3D10Device, or ID3D11Resource to be registered. * \param flags [IN] cuda interop registration flags */ - virtual bool registerResourceInCudaD3D(CUgraphicsResource &resource, void *resourcePointer, PxCudaInteropRegisterFlags flags = PxCudaInteropRegisterFlags()) = 0; + virtual bool registerResourceInCudaD3D(CUgraphicsResource& resource, void* resourcePointer, PxCudaInteropRegisterFlags flags = PxCudaInteropRegisterFlags()) = 0; /** * \brief Unregister a rendering resource with CUDA @@ -340,14 +477,17 @@ public: */ virtual int usingDedicatedGPU() const = 0; + /** + * \brief Get the cuda modules that have been loaded into this context on construction + * \return Pointer to the cuda modules + */ + virtual CUmodule* getCuModules() = 0; + /** * \brief Release the PxCudaContextManager * - * When the manager instance is released, it also releases its - * PxCudaMemoryManager. Before the memory manager is released, it - * frees all allocated memory pages. If the PxCudaContextManager - * created the CUDA context it was responsible for, it also frees - * that context. + * If the PxCudaContextManager created the CUDA context it was + * responsible for, it also frees that context. * * Do not release the PxCudaContextManager if there are any scenes * using it. Those scenes must be released first. @@ -361,8 +501,31 @@ protected: * \brief protected destructor, use release() method */ virtual ~PxCudaContextManager() {} + + virtual void* allocDeviceBufferInternal(PxU32 numBytes, const char* filename = NULL, PxI32 line = -1) = 0; + virtual void* allocPinnedHostBufferInternal(PxU32 numBytes, const char* filename = NULL, PxI32 line = -1) = 0; + + virtual void freeDeviceBufferInternal(void* deviceBuffer) = 0; + virtual void freePinnedHostBufferInternal(void* pinnedHostBuffer) = 0; + + virtual void clearDeviceBufferAsyncInternal(void* deviceBuffer, PxU32 numBytes, CUstream stream, PxI32 value) = 0; + + virtual void copyDToHAsyncInternal(void* hostBuffer, const void* deviceBuffer, PxU32 numBytes, CUstream stream) = 0; + virtual void copyHToDAsyncInternal(void* deviceBuffer, const void* hostBuffer, PxU32 numBytes, CUstream stream) = 0; + virtual void copyDToDAsyncInternal(void* dstDeviceBuffer, const void* srcDeviceBuffer, PxU32 numBytes, CUstream stream) = 0; + + virtual void copyDToHInternal(void* hostBuffer, const void* deviceBuffer, PxU32 numBytes) = 0; + virtual void copyHToDInternal(void* deviceBuffer, const void* hostBuffer, PxU32 numBytes) = 0; }; +#define PX_DEVICE_ALLOC(cudaContextManager, deviceBuffer, numElements) cudaContextManager->allocDeviceBuffer(deviceBuffer, numElements, __FILE__, __LINE__) +#define PX_DEVICE_ALLOC_T(T, cudaContextManager, numElements) cudaContextManager->allocDeviceBuffer(numElements, __FILE__, __LINE__) +#define PX_DEVICE_FREE(cudaContextManager, deviceBuffer) cudaContextManager->freeDeviceBuffer(deviceBuffer); + +#define PX_PINNED_HOST_ALLOC(cudaContextManager, pinnedHostBuffer, numElements) cudaContextManager->allocPinnedHostBuffer(pinnedHostBuffer, numElements, __FILE__, __LINE__) +#define PX_PINNED_HOST_ALLOC_T(T, cudaContextManager, numElements) cudaContextManager->allocPinnedHostBuffer(numElements, __FILE__, __LINE__) +#define PX_PINNED_HOST_FREE(cudaContextManager, pinnedHostBuffer) cudaContextManager->freePinnedHostBuffer(pinnedHostBuffer); + /** * \brief Convenience class for holding CUDA lock within a scope */ @@ -393,7 +556,9 @@ protected: PxCudaContextManager* mCtx; }; -} // end physx namespace +#if !PX_DOXYGEN +} // namespace physx +#endif #endif // PX_SUPPORT_GPU_PHYSX -#endif // PXCUDACONTEXTMANAGER_PXCUDACONTEXTMANAGER_H +#endif diff --git a/Source/ThirdParty/PhysX/cudamanager/PxCudaMemoryManager.h b/Source/ThirdParty/PhysX/cudamanager/PxCudaMemoryManager.h deleted file mode 100644 index 83dc2cce9..000000000 --- a/Source/ThirdParty/PhysX/cudamanager/PxCudaMemoryManager.h +++ /dev/null @@ -1,281 +0,0 @@ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of NVIDIA CORPORATION nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. - -#ifndef PXCUDACONTEXTMANAGER_PXCUDAMEMORYMANAGER_H -#define PXCUDACONTEXTMANAGER_PXCUDAMEMORYMANAGER_H - -#include "foundation/PxPreprocessor.h" - -#if PX_SUPPORT_GPU_PHYSX - -#include "task/PxTaskDefine.h" - -// some macros to keep the source code more readable -#define PX_ALLOC_INFO(name, ID) __FILE__, __LINE__, name, physx::PxAllocId::ID -#define PX_ALLOC_INFO_PARAMS_DECL(p0, p1, p2, p3) const char* file = p0, int line = p1, const char* allocName = p2, physx::PxAllocId::Enum allocId = physx::PxAllocId::p3 -#define PX_ALLOC_INFO_PARAMS_DEF() const char* file, int line, const char* allocName, physx::PxAllocId::Enum allocId -#define PX_ALLOC_INFO_PARAMS_INPUT() file, line, allocName, allocId -#define PX_ALLOC_INFO_PARAMS_INPUT_INFO(info) info.getFileName(), info.getLine(), info.getAllocName(), info.getAllocId() - -#ifndef NULL // don't want to include -#define NULL 0 -#endif - -namespace physx -{ - -PX_PUSH_PACK_DEFAULT - -/** \brief ID of the Feature which owns/allocated memory from the heap - * - * Maximum of 64k IDs allowed. - */ -struct PxAllocId -{ - /** - * \brief ID of the Feature which owns/allocated memory from the heap - */ - enum Enum - { - UNASSIGNED, //!< default - APEX, //!< APEX stuff not further classified - PARTICLES, //!< all particle related - GPU_UTIL, //!< e.g. RadixSort (used in SPH and deformable self collision) - CLOTH, //!< all cloth related - NUM_IDS //!< number of IDs, be aware that ApexHeapStats contains PxAllocIdStats[NUM_IDS] - }; -}; - -/// \brief memory type managed by a heap -struct PxCudaBufferMemorySpace -{ - /** - * \brief memory type managed by a heap - */ - enum Enum - { - T_GPU, - T_PINNED_HOST, - T_WRITE_COMBINED, - T_HOST, - COUNT - }; -}; - -/// \brief class to track allocation statistics, see PxgMirrored -class PxAllocInfo -{ -public: - /** - * \brief AllocInfo default constructor - */ - PxAllocInfo() {} - - /** - * \brief AllocInfo constructor that initializes all of the members - */ - PxAllocInfo(const char* file, int line, const char* allocName, PxAllocId::Enum allocId) - : mFileName(file) - , mLine(line) - , mAllocName(allocName) - , mAllocId(allocId) - {} - - /// \brief get the allocation file name - inline const char* getFileName() const - { - return mFileName; - } - - /// \brief get the allocation line - inline int getLine() const - { - return mLine; - } - - /// \brief get the allocation name - inline const char* getAllocName() const - { - return mAllocName; - } - - /// \brief get the allocation ID - inline PxAllocId::Enum getAllocId() const - { - return mAllocId; - } - -private: - const char* mFileName; - int mLine; - const char* mAllocName; - PxAllocId::Enum mAllocId; -}; - -/// \brief statistics collected per AllocationId by HeapManager. -struct PxAllocIdStats -{ - size_t size; //!< currently allocated memory by this ID - size_t maxSize; //!< max allocated memory by this ID - size_t elements; //!< number of current allocations by this ID - size_t maxElements; //!< max number of allocations by this ID -}; - -class PxCudaMemoryManager; -typedef size_t PxCudaBufferPtr; - -/// \brief Hint flag to tell how the buffer will be used -struct PxCudaBufferFlags -{ -/// \brief Enumerations for the hint flag to tell how the buffer will be used - enum Enum - { - F_READ = (1 << 0), - F_WRITE = (1 << 1), - F_READ_WRITE = F_READ | F_WRITE - }; -}; - - -/// \brief Memory statistics struct returned by CudaMemMgr::getStats() -struct PxCudaMemoryManagerStats -{ - - size_t heapSize; //!< Size of all pages allocated for this memory type (allocated + free). - size_t totalAllocated; //!< Size occupied by the current allocations. - size_t maxAllocated; //!< High water mark of allocations since the SDK was created. - PxAllocIdStats allocIdStats[PxAllocId::NUM_IDS]; //!< Stats for each allocation ID, see PxAllocIdStats -}; - - -/// \brief Buffer type: made of hint flags and the memory space (Device Memory, Pinned Host Memory, ...) -struct PxCudaBufferType -{ - /// \brief PxCudaBufferType copy constructor - PX_INLINE PxCudaBufferType(const PxCudaBufferType& t) - : memorySpace(t.memorySpace) - , flags(t.flags) - {} - - /// \brief PxCudaBufferType constructor to explicitely assign members - PX_INLINE PxCudaBufferType(PxCudaBufferMemorySpace::Enum _memSpace, PxCudaBufferFlags::Enum _flags) - : memorySpace(_memSpace) - , flags(_flags) - {} - - PxCudaBufferMemorySpace::Enum memorySpace; //!< specifies which memory space for the buffer - PxCudaBufferFlags::Enum flags; //!< specifies the usage flags for the buffer -}; - - -/// \brief Buffer which keeps informations about allocated piece of memory. -class PxCudaBuffer -{ -public: - /// Retrieves the manager over which the buffer was allocated. - virtual PxCudaMemoryManager* getCudaMemoryManager() const = 0; - - /// Releases the buffer and the memory it used, returns true if successful. - virtual bool free() = 0; - - /// Realloc memory. Use to shrink or resize the allocated chunk of memory of this buffer. - /// Returns true if successful. Fails if the operation would change the address and need a memcopy. - /// In that case the user has to allocate, copy and free the memory with separate steps. - /// Realloc to size 0 always returns false and doesn't change the state. - virtual bool realloc(size_t size, PX_ALLOC_INFO_PARAMS_DECL(NULL, 0, NULL, UNASSIGNED)) = 0; - - /// Returns the type of the allocated memory. - virtual const PxCudaBufferType& getType() const = 0; - - /// Returns the pointer to the allocated memory. - virtual PxCudaBufferPtr getPtr() const = 0; - - /// Returns the size of the allocated memory. - virtual size_t getSize() const = 0; - -protected: - /// \brief protected destructor - virtual ~PxCudaBuffer() {} -}; - - -/// \brief Allocator class for different kinds of CUDA related memory. -class PxCudaMemoryManager -{ -public: - /// Allocate memory of given type and size. Returns a CudaBuffer if successful. Returns NULL if failed. - virtual PxCudaBuffer* alloc(const PxCudaBufferType& type, size_t size, PX_ALLOC_INFO_PARAMS_DECL(NULL, 0, NULL, UNASSIGNED)) = 0; - - /// Basic heap allocator without PxCudaBuffer - virtual PxCudaBufferPtr alloc(PxCudaBufferMemorySpace::Enum memorySpace, size_t size, PX_ALLOC_INFO_PARAMS_DECL(NULL, 0, NULL, UNASSIGNED)) = 0; - - /// Basic heap deallocator without PxCudaBuffer - virtual bool free(PxCudaBufferMemorySpace::Enum memorySpace, PxCudaBufferPtr addr) = 0; - - /// Basic heap realloc without PxCudaBuffer - virtual bool realloc(PxCudaBufferMemorySpace::Enum memorySpace, PxCudaBufferPtr addr, size_t size, PX_ALLOC_INFO_PARAMS_DECL(NULL, 0, NULL, UNASSIGNED)) = 0; - - /// Retrieve stats for the memory of given type. See PxCudaMemoryManagerStats. - virtual void getStats(const PxCudaBufferType& type, PxCudaMemoryManagerStats& outStats) = 0; - - /// Ensure that a given amount of free memory is available. Triggers CUDA allocations in size of (2^n * pageSize) if necessary. - /// Returns false if page allocations failed. - virtual bool reserve(const PxCudaBufferType& type, size_t size) = 0; - - /// Set the page size. The managed memory grows by blocks 2^n * pageSize. Page allocations trigger CUDA driver allocations, - /// so the page size should be reasonably big. Returns false if input size was invalid, i.e. not power of two. - /// Default is 2 MB. - virtual bool setPageSize(const PxCudaBufferType& type, size_t size) = 0; - - /// Set the upper limit until which pages of a given memory type can be allocated. - /// Reducing the max when it is already hit does not shrink the memory until it is deallocated by releasing the buffers which own the memory. - virtual bool setMaxMemorySize(const PxCudaBufferType& type, size_t size) = 0; - - /// Returns the base size. The base memory block stays persistently allocated over the SDKs life time. - virtual size_t getBaseSize(const PxCudaBufferType& type) = 0; - - /// Returns the currently set page size. The memory grows and shrinks in blocks of size (2^n pageSize) - virtual size_t getPageSize(const PxCudaBufferType& type) = 0; - - /// Returns the upper limit until which the manager is allowed to allocate additional pages from the CUDA driver. - virtual size_t getMaxMemorySize(const PxCudaBufferType& type) = 0; - - /// Get device mapped pinned host mem ptr. Operation only valid for memory space PxCudaBufferMemorySpace::T_PINNED_HOST. - virtual PxCudaBufferPtr getMappedPinnedPtr(PxCudaBufferPtr hostPtr) = 0; - -protected: - /// \brief protected destructor - virtual ~PxCudaMemoryManager() {} -}; - -PX_POP_PACK - - -} // end physx namespace - -#endif // PX_SUPPORT_GPU_PHYSX -#endif // PXCUDACONTEXTMANAGER_PXCUDAMEMORYMANAGER_H diff --git a/Source/ThirdParty/PhysX/cudamanager/PxCudaTypes.h b/Source/ThirdParty/PhysX/cudamanager/PxCudaTypes.h new file mode 100644 index 000000000..97ee47d88 --- /dev/null +++ b/Source/ThirdParty/PhysX/cudamanager/PxCudaTypes.h @@ -0,0 +1,70 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. + +#ifndef PX_CUDA_TYPES_H +#define PX_CUDA_TYPES_H + +//type definitions to avoid forced inclusion of cuda.h +//if cuda.h is needed anyway, please include it before PxCudaContextManager.h, PxCudaContext.h or PxCudaTypes.h + +#include "foundation/PxPreprocessor.h" + +#if PX_SUPPORT_GPU_PHYSX +#ifndef CUDA_VERSION + +#include "foundation/PxSimpleTypes.h" + +#if PX_LINUX && !PX_A64 +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wc++98-compat-pedantic" +#endif + +#if PX_P64_FAMILY +typedef unsigned long long CUdeviceptr; +#else +typedef unsigned int CUdeviceptr; +#endif + +#if PX_LINUX && !PX_A64 +#pragma GCC diagnostic pop +#endif + +typedef int CUdevice; + +typedef struct CUctx_st* CUcontext; +typedef struct CUmod_st* CUmodule; +typedef struct CUfunc_st* CUfunction; +typedef struct CUstream_st* CUstream; +typedef struct CUevent_st* CUevent; +typedef struct CUgraphicsResource_st* CUgraphicsResource; + +#endif + +#else +typedef struct CUstream_st* CUstream; // We declare some callbacks taking CUstream as an argument even when building with PX_SUPPORT_GPU_PHYSX = 0. +#endif // PX_SUPPORT_GPU_PHYSX +#endif + diff --git a/Source/ThirdParty/PhysX/extensions/PxBinaryConverter.h b/Source/ThirdParty/PhysX/extensions/PxBinaryConverter.h index ec790a72d..f2421e651 100644 --- a/Source/ThirdParty/PhysX/extensions/PxBinaryConverter.h +++ b/Source/ThirdParty/PhysX/extensions/PxBinaryConverter.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,11 +22,10 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - #ifndef PX_BINARY_CONVERTER_H #define PX_BINARY_CONVERTER_H /** \addtogroup extensions @@ -41,7 +39,7 @@ namespace physx { #endif -struct PxConverterReportMode +struct PX_DEPRECATED PxConverterReportMode { enum Enum { @@ -55,6 +53,8 @@ struct PxConverterReportMode /** \brief Binary converter for serialized streams. +\deprecated Binary conversion and binary meta data are deprecated. + The binary converter class is targeted at converting binary streams from authoring platforms, such as windows, osx or linux to any game runtime platform supported by PhysX. Particularly it is currently not supported to run the converter on a platforms that has an endian mismatch @@ -65,7 +65,7 @@ of this class for each thread. @see PxSerialization.createBinaryConverter */ -class PxBinaryConverter +class PX_DEPRECATED PxBinaryConverter { public: diff --git a/Source/ThirdParty/PhysX/extensions/PxBroadPhaseExt.h b/Source/ThirdParty/PhysX/extensions/PxBroadPhaseExt.h index d5562192d..614fb89fb 100644 --- a/Source/ThirdParty/PhysX/extensions/PxBroadPhaseExt.h +++ b/Source/ThirdParty/PhysX/extensions/PxBroadPhaseExt.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_EXTENSIONS_BROAD_PHASE_H -#define PX_PHYSICS_EXTENSIONS_BROAD_PHASE_H +#ifndef PX_BROAD_PHASE_EXT_H +#define PX_BROAD_PHASE_EXT_H /** \addtogroup extensions @{ */ diff --git a/Source/ThirdParty/PhysX/extensions/PxCollectionExt.h b/Source/ThirdParty/PhysX/extensions/PxCollectionExt.h index 85e8bee42..d17f5ddc0 100644 --- a/Source/ThirdParty/PhysX/extensions/PxCollectionExt.h +++ b/Source/ThirdParty/PhysX/extensions/PxCollectionExt.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,11 +22,10 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - #ifndef PX_COLLECTION_EXT_H #define PX_COLLECTION_EXT_H /** \addtogroup extensions @@ -42,6 +40,9 @@ namespace physx { #endif + class PxCollection; + class PxScene; + class PxCollectionExt { public: @@ -75,7 +76,6 @@ namespace physx */ static void remove(PxCollection& collection, PxType concreteType, PxCollection* to = NULL); - /** \brief Collects all objects in PxPhysics that are shareable across multiple scenes. @@ -95,9 +95,9 @@ namespace physx /** \brief Collects all objects from a PxScene. - This function creates a new collection from all objects that where added to the specified + This function creates a new collection from all objects that were added to the specified PxScene. Instances of the following types are included: PxActor, PxAggregate, - PxArticulation and PxJoint (other PxConstraint types are not included). + PxArticulationReducedCoordinate and PxJoint (other PxConstraint types are not included). This is a helper function to ease the creation of collections for serialization. The function PxSerialization.complete() can be used to complete the collection with required objects prior to diff --git a/Source/ThirdParty/PhysX/extensions/PxConstraintExt.h b/Source/ThirdParty/PhysX/extensions/PxConstraintExt.h index 6c7a916bd..0a585e8d0 100644 --- a/Source/ThirdParty/PhysX/extensions/PxConstraintExt.h +++ b/Source/ThirdParty/PhysX/extensions/PxConstraintExt.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_EXTENSIONS_CONSTRAINT_H -#define PX_PHYSICS_EXTENSIONS_CONSTRAINT_H +#ifndef PX_CONSTRAINT_EXT_H +#define PX_CONSTRAINT_EXT_H #include "foundation/PxPreprocessor.h" @@ -55,8 +53,9 @@ struct PxConstraintExtIDs enum Enum { eJOINT, - eVEHICLE_SUSP_LIMIT, - eVEHICLE_STICKY_TYRE, + eVEHICLE_SUSP_LIMIT_DEPRECATED, + eVEHICLE_STICKY_TYRE_DEPRECATED, + eVEHICLE_JOINT, eNEXT_FREE_ID, eINVALID_ID = 0x7fffffff }; diff --git a/Source/ThirdParty/PhysX/extensions/PxContactJoint.h b/Source/ThirdParty/PhysX/extensions/PxContactJoint.h index b3f149b77..a49ec1aa6 100644 --- a/Source/ThirdParty/PhysX/extensions/PxContactJoint.h +++ b/Source/ThirdParty/PhysX/extensions/PxContactJoint.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PX_CONTACTJOINT_H -#define PX_CONTACTJOINT_H +#ifndef PX_CONTACT_JOINT_H +#define PX_CONTACT_JOINT_H #include "extensions/PxJoint.h" @@ -126,8 +125,8 @@ namespace physx */ virtual PxReal getPenetration() const = 0; - virtual PxReal getResititution() const = 0; - virtual void setResititution(const PxReal resititution) = 0; + virtual PxReal getRestitution() const = 0; + virtual void setRestitution(const PxReal restitution) = 0; virtual PxReal getBounceThreshold() const = 0; virtual void setBounceThreshold(const PxReal bounceThreshold) = 0; diff --git a/Source/ThirdParty/PhysX/extensions/PxConvexMeshExt.h b/Source/ThirdParty/PhysX/extensions/PxConvexMeshExt.h index 5b33980df..0db30b9fe 100644 --- a/Source/ThirdParty/PhysX/extensions/PxConvexMeshExt.h +++ b/Source/ThirdParty/PhysX/extensions/PxConvexMeshExt.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_EXTENSIONS_CONVEX_MESH_H -#define PX_PHYSICS_EXTENSIONS_CONVEX_MESH_H +#ifndef PX_CONVEX_MESH_EXT_H +#define PX_CONVEX_MESH_EXT_H /** \addtogroup extensions @{ */ diff --git a/Source/ThirdParty/PhysX/extensions/PxCustomGeometryExt.h b/Source/ThirdParty/PhysX/extensions/PxCustomGeometryExt.h new file mode 100644 index 000000000..c9bdf6404 --- /dev/null +++ b/Source/ThirdParty/PhysX/extensions/PxCustomGeometryExt.h @@ -0,0 +1,173 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_CUSTOM_GEOMETRY_EXT_H +#define PX_CUSTOM_GEOMETRY_EXT_H +/** \addtogroup extensions + @{ +*/ + +#include +#include + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +class PxGeometry; +class PxMassProperties; +class PxGeometryHolder; +struct PxContactPoint; + +/** +\brief Pre-made custom geometry callbacks implementations. +*/ +class PxCustomGeometryExt +{ +public: + + /// \cond PRIVATE + struct BaseConvexCallbacks : PxCustomGeometry::Callbacks, PxGjkQuery::Support + { + float margin; + + BaseConvexCallbacks(float _margin) : margin(_margin) {} + + // override PxCustomGeometry::Callbacks + virtual PxBounds3 getLocalBounds(const PxGeometry& geometry) const; + virtual bool generateContacts(const PxGeometry& geom0, const PxGeometry& geom1, const PxTransform& pose0, const PxTransform& pose1, + const PxReal contactDistance, const PxReal meshContactMargin, const PxReal toleranceLength, + PxContactBuffer& contactBuffer) const; + virtual PxU32 raycast(const PxVec3& origin, const PxVec3& unitDir, const PxGeometry& geom, const PxTransform& pose, + PxReal maxDist, PxHitFlags hitFlags, PxU32 maxHits, PxGeomRaycastHit* rayHits, PxU32 stride, PxRaycastThreadContext*) const; + virtual bool overlap(const PxGeometry& geom0, const PxTransform& pose0, const PxGeometry& geom1, const PxTransform& pose1, PxOverlapThreadContext*) const; + virtual bool sweep(const PxVec3& unitDir, const PxReal maxDist, + const PxGeometry& geom0, const PxTransform& pose0, const PxGeometry& geom1, const PxTransform& pose1, + PxGeomSweepHit& sweepHit, PxHitFlags hitFlags, const PxReal inflation, PxSweepThreadContext*) const; + virtual bool usePersistentContactManifold(const PxGeometry& geometry, PxReal& breakingThreshold) const; + + // override PxGjkQuery::Support + virtual PxReal getMargin() const { return margin; } + + protected: + + // Substitute geometry + virtual bool useSubstituteGeometry(PxGeometryHolder& geom, PxTransform& preTransform, const PxContactPoint& p, const PxTransform& pose0, const PxVec3& pos1) const = 0; + }; + /// \endcond + + /** + \brief Cylinder geometry callbacks + */ + struct CylinderCallbacks : BaseConvexCallbacks + { + /// \brief Cylinder height + float height; + /// \brief Cylinder radius + float radius; + /// \brief Cylinder axis + int axis; + + /** + \brief Construct cylinder geometry callbacks object + + \param[in] height The cylinder height. + \param[in] radius The cylinder radius. + \param[in] axis The cylinder axis (0 - X, 1 - Y, 2 - Z). + \param[in] margin The cylinder margin. + */ + CylinderCallbacks(float height, float radius, int axis = 0, float margin = 0); + + /// \cond PRIVATE + // override PxCustomGeometry::Callbacks + DECLARE_CUSTOM_GEOMETRY_TYPE + virtual void visualize(const PxGeometry&, PxRenderOutput&, const PxTransform&, const PxBounds3&) const; + virtual void computeMassProperties(const PxGeometry& geometry, PxMassProperties& massProperties) const; + + // override PxGjkQuery::Support + virtual PxVec3 supportLocal(const PxVec3& dir) const; + + protected: + + // Substitute geometry + virtual bool useSubstituteGeometry(PxGeometryHolder& geom, PxTransform& preTransform, const PxContactPoint& p, const PxTransform& pose0, const PxVec3& pos1) const; + + // Radius at height + float getRadiusAtHeight(float height) const; + /// \endcond + }; + + /** + \brief Cone geometry callbacks + */ + struct ConeCallbacks : BaseConvexCallbacks + { + /// \brief Cone height + float height; + /// \brief Cone radius + float radius; + /// \brief Cone axis + int axis; + + /** + \brief Construct cone geometry callbacks object + + \param[in] height The cylinder height. + \param[in] radius The cylinder radius. + \param[in] axis The cylinder axis (0 - X, 1 - Y, 2 - Z). + \param[in] margin The cylinder margin. + */ + ConeCallbacks(float height, float radius, int axis = 0, float margin = 0); + + /// \cond PRIVATE + // override PxCustomGeometry::Callbacks + DECLARE_CUSTOM_GEOMETRY_TYPE + virtual void visualize(const PxGeometry&, PxRenderOutput&, const PxTransform&, const PxBounds3&) const; + virtual void computeMassProperties(const PxGeometry& geometry, PxMassProperties& massProperties) const; + + // override PxGjkQuery::Support + virtual PxVec3 supportLocal(const PxVec3& dir) const; + + protected: + + // Substitute geometry + virtual bool useSubstituteGeometry(PxGeometryHolder& geom, PxTransform& preTransform, const PxContactPoint& p, const PxTransform& pose0, const PxVec3& pos1) const; + + // Radius at height + float getRadiusAtHeight(float height) const; + /// \endcond + }; +}; + +#if !PX_DOXYGEN +} +#endif + +/** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/extensions/PxCustomSceneQuerySystem.h b/Source/ThirdParty/PhysX/extensions/PxCustomSceneQuerySystem.h new file mode 100644 index 000000000..b245fa0a1 --- /dev/null +++ b/Source/ThirdParty/PhysX/extensions/PxCustomSceneQuerySystem.h @@ -0,0 +1,191 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_NEW_SCENE_QUERY_SYSTEM_H +#define PX_NEW_SCENE_QUERY_SYSTEM_H +/** \addtogroup extensions + @{ +*/ + +#include "PxSceneQuerySystem.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + /** + \brief A custom scene query system. + + This is an example of a custom scene query system. It augments the PxSceneQuerySystem API to support an arbitrary number + of "pruners", instead of the usual hardcoded two. + + It might not be possible to support the whole PxSceneQuerySystem API in this context. See the source code for details. + + @see PxSceneQuerySystem + */ + class PxCustomSceneQuerySystem : public PxSceneQuerySystem + { + public: + PxCustomSceneQuerySystem() {} + virtual ~PxCustomSceneQuerySystem() {} + + /** + \brief Adds a pruner to the system. + + The internal PhysX scene-query system uses two regular pruners (one for static shapes, one for dynamic shapes) and an optional + compound pruner. Our custom scene query system supports an arbitrary number of regular pruners. + + This can be useful to reduce the load on each pruner, in particular during updates, when internal trees are rebuilt in the + background. On the other hand this implementation simply iterates over all created pruners to perform queries, so their cost + might increase if a large number of pruners is used. + + In any case this serves as an example of how the PxSceneQuerySystem API can be used to customize scene queries. + + \param[in] primaryType Desired primary (main) type for the new pruner + \param[in] secondaryType Secondary type when primary type is PxPruningStructureType::eDYNAMIC_AABB_TREE. + \param[in] preallocated Optional number of preallocated shapes in the new pruner + + \return A pruner index + + @see PxCustomSceneQuerySystem PxSceneQueryUpdateMode PxCustomSceneQuerySystemAdapter PxSceneDesc::sceneQuerySystem + */ + virtual PxU32 addPruner(PxPruningStructureType::Enum primaryType, PxDynamicTreeSecondaryPruner::Enum secondaryType, PxU32 preallocated=0) = 0; + + /** + \brief Start custom build-steps for all pruners + + This function is used in combination with customBuildstep() and finishCustomBuildstep() to let users take control + of the pruners' build-step & commit calls - basically the pruners' update functions. These functions should be used + with the PxSceneQueryUpdateMode::eBUILD_DISABLED_COMMIT_DISABLED update mode, otherwise the build-steps will happen + automatically in fetchResults. For N pruners it can be more efficient to use these custom build-step functions to + perform the updates in parallel: + + - call startCustomBuildstep() first (one synchronous call) + - for each pruner, call customBuildstep() (asynchronous calls from multiple threads) + - once it is done, call finishCustomBuildstep() to finish the update (synchronous call) + + The multi-threaded update is more efficient here than what it is in PxScene, because the "flushShapes()" call is + also multi-threaded (while it is not in PxScene). + + Note that users are responsible for locks here, and these calls should not overlap with other SQ calls. In particular + one should not add new objects to the SQ system or perform queries while these calls are happening. + + \return The number of pruners in the system. + + @see customBuildstep finishCustomBuildstep PxSceneQueryUpdateMode + */ + virtual PxU32 startCustomBuildstep() = 0; + + /** + \brief Perform a custom build-step for a given pruner. + + \param[in] index Pruner index (should be between 0 and the number returned by startCustomBuildstep) + + @see startCustomBuildstep finishCustomBuildstep + */ + virtual void customBuildstep(PxU32 index) = 0; + + /** + \brief Finish custom build-steps + + Call this function once after all the customBuildstep() calls are done. + + @see startCustomBuildstep customBuildstep + */ + virtual void finishCustomBuildstep() = 0; + }; + + /** + \brief An adapter class to customize the object-to-pruner mapping. + + In the regular PhysX code static shapes went to the static pruner, and dynamic shapes went to the + dynamic pruner. + + This class is a replacement for this mapping when N user-defined pruners are involved. + */ + class PxCustomSceneQuerySystemAdapter + { + public: + PxCustomSceneQuerySystemAdapter() {} + virtual ~PxCustomSceneQuerySystemAdapter() {} + + /** + \brief Gets a pruner index for an actor/shape. + + This user-defined function tells the system in which pruner a given actor/shape should go. + + \note The returned index must be valid, i.e. it must have been previously returned to users by PxCustomSceneQuerySystem::addPruner. + + \param[in] actor The actor + \param[in] shape The shape + + \return A pruner index for this actor/shape. + + @see PxRigidActor PxShape PxCustomSceneQuerySystem::addPruner + */ + virtual PxU32 getPrunerIndex(const PxRigidActor& actor, const PxShape& shape) const = 0; + + /** + \brief Pruner filtering callback. + + This will be called for each query to validate whether it should process a given pruner. + + \param[in] prunerIndex The index of currently processed pruner + \param[in] context The query context + \param[in] filterData The query's filter data + \param[in] filterCall The query's filter callback + + \return True to process the pruner, false to skip it entirely + */ + virtual bool processPruner(PxU32 prunerIndex, const PxQueryThreadContext* context, const PxQueryFilterData& filterData, PxQueryFilterCallback* filterCall) const = 0; + }; + + /** + \brief Creates a custom scene query system. + + This is similar to PxCreateExternalSceneQuerySystem, except this function creates a PxCustomSceneQuerySystem object. + It can be plugged to PxScene the same way, via PxSceneDesc::sceneQuerySystem. + + \param[in] sceneQueryUpdateMode Desired update mode + \param[in] contextID Context ID parameter, sent to the profiler + \param[in] adapter Adapter class implementing our extended API + \param[in] usesTreeOfPruners True to keep pruners themselves in a BVH, which might increase query performance if a lot of pruners are involved + + \return A custom SQ system instance + + @see PxCustomSceneQuerySystem PxSceneQueryUpdateMode PxCustomSceneQuerySystemAdapter PxSceneDesc::sceneQuerySystem + */ + PxCustomSceneQuerySystem* PxCreateCustomSceneQuerySystem(PxSceneQueryUpdateMode::Enum sceneQueryUpdateMode, PxU64 contextID, const PxCustomSceneQuerySystemAdapter& adapter, bool usesTreeOfPruners=false); + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/extensions/PxD6Joint.h b/Source/ThirdParty/PhysX/extensions/PxD6Joint.h index 0b1cb6c36..84eab70f9 100644 --- a/Source/ThirdParty/PhysX/extensions/PxD6Joint.h +++ b/Source/ThirdParty/PhysX/extensions/PxD6Joint.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PX_D6JOINT_H -#define PX_D6JOINT_H +#ifndef PX_D6_JOINT_H +#define PX_D6_JOINT_H /** \addtogroup extensions @{ */ @@ -429,7 +428,8 @@ public: Default the identity transform \param[in] pose The goal drive pose if positional drive is in use. - \param[in] autowake Whether to wake the joint rigids up if it is asleep. + \param[in] autowake If true and the attached actors are in a scene, this call wakes them up and increases their + wake counters to #PxSceneDesc::wakeCounterResetValue if the counter value is below the reset value. @see setDrivePosition() */ @@ -449,7 +449,8 @@ public: \param[in] linear The goal velocity for linear drive \param[in] angular The goal velocity for angular drive - \param[in] autowake Whether to wake the joint rigids up if it is asleep. + \param[in] autowake If true and the attached actors are in a scene, this call wakes them up and increases their + wake counters to #PxSceneDesc::wakeCounterResetValue if the counter value is below the reset value. @see getDriveVelocity() */ @@ -482,8 +483,10 @@ public: \param[in] tolerance the linear tolerance threshold @see getProjectionLinearTolerance() PxJoint::setConstraintFlags() PxConstraintFlag::ePROJECTION + + @deprecated */ - virtual void setProjectionLinearTolerance(PxReal tolerance) = 0; + PX_DEPRECATED virtual void setProjectionLinearTolerance(PxReal tolerance) = 0; /** \brief Get the linear tolerance threshold for projection. @@ -491,8 +494,10 @@ public: \return the linear tolerance threshold @see setProjectionLinearTolerance() + + @deprecated */ - virtual PxReal getProjectionLinearTolerance() const = 0; + PX_DEPRECATED virtual PxReal getProjectionLinearTolerance() const = 0; /** \brief Set the angular tolerance threshold for projection. Projection is enabled if @@ -514,8 +519,10 @@ public: Angular projection is implemented only for the case of two or three locked angular degrees of freedom. @see getProjectionAngularTolerance() PxJoint::setConstraintFlag() PxConstraintFlag::ePROJECTION + + @deprecated */ - virtual void setProjectionAngularTolerance(PxReal tolerance) = 0; + PX_DEPRECATED virtual void setProjectionAngularTolerance(PxReal tolerance) = 0; /** \brief Get the angular tolerance threshold for projection. @@ -523,8 +530,10 @@ public: \return tolerance the angular tolerance threshold in radians @see setProjectionAngularTolerance() + + @deprecated */ - virtual PxReal getProjectionAngularTolerance() const = 0; + PX_DEPRECATED virtual PxReal getProjectionAngularTolerance() const = 0; /** \brief Returns string name of PxD6Joint, used for serialization diff --git a/Source/ThirdParty/PhysX/extensions/PxD6JointCreate.h b/Source/ThirdParty/PhysX/extensions/PxD6JointCreate.h index 8459dce58..39f16963e 100644 --- a/Source/ThirdParty/PhysX/extensions/PxD6JointCreate.h +++ b/Source/ThirdParty/PhysX/extensions/PxD6JointCreate.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PX_D6JOINT_CREATE_H -#define PX_D6JOINT_CREATE_H +#ifndef PX_D6_JOINT_CREATE_H +#define PX_D6_JOINT_CREATE_H #include "common/PxPhysXCommonConfig.h" diff --git a/Source/ThirdParty/PhysX/extensions/PxDefaultAllocator.h b/Source/ThirdParty/PhysX/extensions/PxDefaultAllocator.h index 8c24172d0..940abd928 100644 --- a/Source/ThirdParty/PhysX/extensions/PxDefaultAllocator.h +++ b/Source/ThirdParty/PhysX/extensions/PxDefaultAllocator.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,11 +22,10 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - #ifndef PX_DEFAULT_ALLOCATOR_H #define PX_DEFAULT_ALLOCATOR_H /** \addtogroup extensions @@ -89,14 +87,14 @@ PX_FORCE_INLINE void platformAlignedFree(void* ptr) class PxDefaultAllocator : public PxAllocatorCallback { public: - void* allocate(size_t size, const char*, const char*, int) + virtual void* allocate(size_t size, const char*, const char*, int) { void* ptr = platformAlignedAlloc(size); - PX_ASSERT((reinterpret_cast(ptr) & 15)==0); + PX_ASSERT((size_t(ptr) & 15)==0); return ptr; } - void deallocate(void* ptr) + virtual void deallocate(void* ptr) { platformAlignedFree(ptr); } diff --git a/Source/ThirdParty/PhysX/extensions/PxDefaultCpuDispatcher.h b/Source/ThirdParty/PhysX/extensions/PxDefaultCpuDispatcher.h index 8ad081ccf..9aadb99fd 100644 --- a/Source/ThirdParty/PhysX/extensions/PxDefaultCpuDispatcher.h +++ b/Source/ThirdParty/PhysX/extensions/PxDefaultCpuDispatcher.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_EXTENSIONS_DEFAULT_CPU_DISPATCHER_H -#define PX_PHYSICS_EXTENSIONS_DEFAULT_CPU_DISPATCHER_H +#ifndef PX_DEFAULT_CPU_DISPATCHER_H +#define PX_DEFAULT_CPU_DISPATCHER_H /** \addtogroup extensions @{ */ @@ -47,7 +45,7 @@ namespace physx @see PxDefaultCpuDispatcherCreate() PxCpuDispatcher */ -class PxDefaultCpuDispatcher: public PxCpuDispatcher +class PxDefaultCpuDispatcher : public PxCpuDispatcher { public: /** @@ -77,18 +75,45 @@ public: }; +/** +\brief If a thread ends up waiting for work it will find itself in a spin-wait loop until work becomes available. +Three strategies are available to limit wasted cycles. +The strategies are as follows: +a) wait until a work task signals the end of the spin-wait period. +b) yield the thread by providing a hint to reschedule thread execution, thereby allowing other threads to run. +c) yield the processor by informing it that it is waiting for work and requesting it to more efficiently use compute resources. +*/ +struct PxDefaultCpuDispatcherWaitForWorkMode +{ + enum Enum + { + eWAIT_FOR_WORK, + eYIELD_THREAD, + eYIELD_PROCESSOR + }; +}; + + /** \brief Create default dispatcher, extensions SDK needs to be initialized first. \param[in] numThreads Number of worker threads the dispatcher should use. \param[in] affinityMasks Array with affinity mask for each thread. If not defined, default masks will be used. +\param[in] mode is the strategy employed when a busy-wait is encountered. +\param[in] yieldProcessorCount specifies the number of times a OS-specific yield processor command will be executed +during each cycle of a busy-wait in the event that the specified mode is eYIELD_PROCESSOR \note numThreads may be zero in which case no worker thread are initialized and simulation tasks will be executed on the thread that calls PxScene::simulate() +\note yieldProcessorCount must be greater than zero if eYIELD_PROCESSOR is the chosen mode and equal to zero for all other modes. + +\note eYIELD_THREAD and eYIELD_PROCESSOR modes will use compute resources even if the simulation is not running. +It is left to users to keep threads inactive, if so desired, when no simulation is running. + @see PxDefaultCpuDispatcher */ -PxDefaultCpuDispatcher* PxDefaultCpuDispatcherCreate(PxU32 numThreads, PxU32* affinityMasks = NULL); +PxDefaultCpuDispatcher* PxDefaultCpuDispatcherCreate(PxU32 numThreads, PxU32* affinityMasks = NULL, PxDefaultCpuDispatcherWaitForWorkMode::Enum mode = PxDefaultCpuDispatcherWaitForWorkMode::eWAIT_FOR_WORK, PxU32 yieldProcessorCount = 0); #if !PX_DOXYGEN } // namespace physx diff --git a/Source/ThirdParty/PhysX/extensions/PxDefaultErrorCallback.h b/Source/ThirdParty/PhysX/extensions/PxDefaultErrorCallback.h index cec365e96..38227f5b5 100644 --- a/Source/ThirdParty/PhysX/extensions/PxDefaultErrorCallback.h +++ b/Source/ThirdParty/PhysX/extensions/PxDefaultErrorCallback.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,15 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PX_PHYSICS_EXTENSIONS_DEFAULT_ERROR_CALLBACK_H -#define PX_PHYSICS_EXTENSIONS_DEFAULT_ERROR_CALLBACK_H +#ifndef PX_DEFAULT_ERROR_CALLBACK_H +#define PX_DEFAULT_ERROR_CALLBACK_H +/** \addtogroup extensions + @{ +*/ #include "foundation/PxErrorCallback.h" #include "PxPhysXConfig.h" @@ -49,14 +51,15 @@ namespace physx class PxDefaultErrorCallback : public PxErrorCallback { public: - PxDefaultErrorCallback(); - ~PxDefaultErrorCallback(); + PxDefaultErrorCallback(); + virtual ~PxDefaultErrorCallback(); - virtual void reportError(PxErrorCode::Enum code, const char* message, const char* file, int line); + virtual void reportError(PxErrorCode::Enum code, const char* message, const char* file, int line) PX_OVERRIDE; }; #if !PX_DOXYGEN } // namespace physx #endif +/** @} */ #endif diff --git a/Source/ThirdParty/PhysX/extensions/PxDefaultSimulationFilterShader.h b/Source/ThirdParty/PhysX/extensions/PxDefaultSimulationFilterShader.h index 70d88af5e..f6fd7bebc 100644 --- a/Source/ThirdParty/PhysX/extensions/PxDefaultSimulationFilterShader.h +++ b/Source/ThirdParty/PhysX/extensions/PxDefaultSimulationFilterShader.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_EXTENSIONS_DEFAULTSIMULATIONFILTERSHADER_H -#define PX_PHYSICS_EXTENSIONS_DEFAULTSIMULATIONFILTERSHADER_H +#ifndef PX_DEFAULT_SIMULATION_FILTER_SHADER_H +#define PX_DEFAULT_SIMULATION_FILTER_SHADER_H /** \addtogroup extensions @{ */ diff --git a/Source/ThirdParty/PhysX/extensions/PxDefaultStreams.h b/Source/ThirdParty/PhysX/extensions/PxDefaultStreams.h index 0b33ec4ce..199d261b5 100644 --- a/Source/ThirdParty/PhysX/extensions/PxDefaultStreams.h +++ b/Source/ThirdParty/PhysX/extensions/PxDefaultStreams.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_EXTENSIONS_DEFAULT_STREAMS_H -#define PX_PHYSICS_EXTENSIONS_DEFAULT_STREAMS_H +#ifndef PX_DEFAULT_STREAMS_H +#define PX_DEFAULT_STREAMS_H /** \addtogroup extensions @{ */ @@ -37,7 +35,7 @@ #include #include "common/PxPhysXCommonConfig.h" #include "foundation/PxIO.h" -#include "PxFoundation.h" +#include "foundation/PxFoundation.h" typedef FILE* PxFileHandle; @@ -55,7 +53,7 @@ namespace physx class PxDefaultMemoryOutputStream: public PxOutputStream { public: - PxDefaultMemoryOutputStream(PxAllocatorCallback &allocator = PxGetFoundation().getAllocatorCallback()); + PxDefaultMemoryOutputStream(PxAllocatorCallback &allocator = *PxGetAllocatorCallback()); virtual ~PxDefaultMemoryOutputStream(); virtual PxU32 write(const void* src, PxU32 count); diff --git a/Source/ThirdParty/PhysX/extensions/PxDistanceJoint.h b/Source/ThirdParty/PhysX/extensions/PxDistanceJoint.h index ab6ae2d51..5a34b58e5 100644 --- a/Source/ThirdParty/PhysX/extensions/PxDistanceJoint.h +++ b/Source/ThirdParty/PhysX/extensions/PxDistanceJoint.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PX_DISTANCEJOINT_H -#define PX_DISTANCEJOINT_H +#ifndef PX_DISTANCE_JOINT_H +#define PX_DISTANCE_JOINT_H /** \addtogroup extensions @{ */ @@ -204,6 +203,34 @@ public: */ virtual PxReal getDamping() const = 0; + /** + \brief Set the contact distance for the min & max distance limits. + + This is similar to the PxJointLimitParameters::contactDistance parameter for regular limits. + + The two most common values are 0 and infinite. Infinite means the internal constraints are + always created, resulting in the best simulation quality but slower performance. Zero means + the internal constraints are only created when the limits are violated, resulting in best + performance but worse simulation quality. + + Default 0.0f + Range [0, PX_MAX_F32) + + \param[in] contactDistance The contact distance + + @see PxJointLimitParameters::contactDistance getContactDistance() + */ + virtual void setContactDistance(PxReal contactDistance) = 0; + + /** + \brief Get the contact distance. + + \return the contact distance + + @see PxJointLimitParameters::contactDistance setContactDistance() + */ + virtual PxReal getContactDistance() const = 0; + /** \brief Set the flags specific to the Distance Joint. diff --git a/Source/ThirdParty/PhysX/extensions/PxExtensionsAPI.h b/Source/ThirdParty/PhysX/extensions/PxExtensionsAPI.h index 46142bc94..fc30edb88 100644 --- a/Source/ThirdParty/PhysX/extensions/PxExtensionsAPI.h +++ b/Source/ThirdParty/PhysX/extensions/PxExtensionsAPI.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,11 +22,10 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - #ifndef PX_EXTENSIONS_API_H #define PX_EXTENSIONS_API_H /** \addtogroup extensions @@ -44,6 +42,8 @@ #include "extensions/PxRevoluteJoint.h" #include "extensions/PxSphericalJoint.h" #include "extensions/PxD6Joint.h" +#include "extensions/PxGearJoint.h" +#include "extensions/PxRackAndPinionJoint.h" #include "extensions/PxDefaultSimulationFilterShader.h" #include "extensions/PxDefaultErrorCallback.h" #include "extensions/PxDefaultStreams.h" @@ -59,6 +59,11 @@ #include "extensions/PxBroadPhaseExt.h" #include "extensions/PxMassProperties.h" #include "extensions/PxSceneQueryExt.h" +#include "extensions/PxSceneQuerySystemExt.h" +#include "extensions/PxCustomSceneQuerySystem.h" +#include "extensions/PxConvexMeshExt.h" +#include "extensions/PxSamplingExt.h" +#include "extensions/PxTetrahedronMeshExt.h" /** \brief Initialize the PhysXExtensions library. @@ -70,7 +75,6 @@ This should be called before calling any functions or methods in extensions whic @see PxCloseExtensions PxFoundation PxPhysics */ - PX_C_EXPORT bool PX_CALL_CONV PxInitExtensions(physx::PxPhysics& physics, physx::PxPvd* pvd); /** \brief Shut down the PhysXExtensions library. @@ -81,8 +85,8 @@ This function should be called to cleanly shut down the PhysXExtensions library @see PxInitExtensions */ - PX_C_EXPORT void PX_CALL_CONV PxCloseExtensions(); /** @} */ -#endif // PX_EXTENSIONS_API_H +#endif + diff --git a/Source/ThirdParty/PhysX/extensions/PxFixedJoint.h b/Source/ThirdParty/PhysX/extensions/PxFixedJoint.h index e68aaa194..a2a29397b 100644 --- a/Source/ThirdParty/PhysX/extensions/PxFixedJoint.h +++ b/Source/ThirdParty/PhysX/extensions/PxFixedJoint.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PX_FIXEDJOINT_H -#define PX_FIXEDJOINT_H +#ifndef PX_FIXED_JOINT_H +#define PX_FIXED_JOINT_H /** \addtogroup extensions @{ */ @@ -83,8 +82,10 @@ public: \param[in] tolerance the linear tolerance threshold @see getProjectionLinearTolerance() PxJoint::setConstraintFlags() PxConstraintFlag::ePROJECTION + + @deprecated */ - virtual void setProjectionLinearTolerance(PxReal tolerance) = 0; + PX_DEPRECATED virtual void setProjectionLinearTolerance(PxReal tolerance) = 0; /** \brief Get the linear tolerance threshold for projection. @@ -92,8 +93,10 @@ public: \return the linear tolerance threshold @see setProjectionLinearTolerance() PxJoint::setConstraintFlag() + + @deprecated */ - virtual PxReal getProjectionLinearTolerance() const = 0; + PX_DEPRECATED virtual PxReal getProjectionLinearTolerance() const = 0; /** \brief Set the angular tolerance threshold for projection. Projection is enabled if @@ -112,8 +115,10 @@ public: \param[in] tolerance the angular tolerance threshold in radians @see getProjectionAngularTolerance() PxJoint::setConstraintFlag() PxConstraintFlag::ePROJECTION + + @deprecated */ - virtual void setProjectionAngularTolerance(PxReal tolerance) = 0; + PX_DEPRECATED virtual void setProjectionAngularTolerance(PxReal tolerance) = 0; /** \brief Get the angular tolerance threshold for projection. @@ -121,8 +126,10 @@ public: \return the angular tolerance threshold in radians @see setProjectionAngularTolerance() + + @deprecated */ - virtual PxReal getProjectionAngularTolerance() const = 0; + PX_DEPRECATED virtual PxReal getProjectionAngularTolerance() const = 0; /** \brief Returns string name of PxFixedJoint, used for serialization diff --git a/Source/ThirdParty/PhysX/extensions/PxGearJoint.h b/Source/ThirdParty/PhysX/extensions/PxGearJoint.h new file mode 100644 index 000000000..28f42f83a --- /dev/null +++ b/Source/ThirdParty/PhysX/extensions/PxGearJoint.h @@ -0,0 +1,121 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_GEAR_JOINT_H +#define PX_GEAR_JOINT_H +/** \addtogroup extensions + @{ +*/ + +#include "extensions/PxJoint.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + class PxGearJoint; + + /** + \brief Create a gear Joint. + + \param[in] physics The physics SDK + \param[in] actor0 An actor to which the joint is attached. NULL may be used to attach the joint to a specific point in the world frame + \param[in] localFrame0 The position and orientation of the joint relative to actor0 + \param[in] actor1 An actor to which the joint is attached. NULL may be used to attach the joint to a specific point in the world frame + \param[in] localFrame1 The position and orientation of the joint relative to actor1 + + @see PxGearJoint + */ + PxGearJoint* PxGearJointCreate(PxPhysics& physics, PxRigidActor* actor0, const PxTransform& localFrame0, PxRigidActor* actor1, const PxTransform& localFrame1); + + /** + \brief A joint that connects two existing revolute joints and constrains their relative angular velocity and position with respect to each other. + + @see PxGearJointCreate PxJoint + */ + class PxGearJoint : public PxJoint + { + public: + + /** + \brief Set the hinge/revolute joints connected by the gear joint. + + The passed joints can be either PxRevoluteJoint, PxD6Joint or PxArticulationJointReducedCoordinate. + The joints must define degrees of freedom around the twist axis. They cannot be null. + + Note that these joints are only used to compute the positional error correction term, + used to adjust potential drift between jointed actors. The gear joint can run without + calling this function, but in that case some visible overlap may develop over time between + the teeth of the gear meshes. + + \note Calling this function resets the internal positional error correction term. + + \param[in] hinge0 The first hinge joint + \param[in] hinge1 The second hinge joint + \return true if success + */ + virtual bool setHinges(const PxBase* hinge0, const PxBase* hinge1) = 0; + + /** + \brief Set the desired gear ratio. + + For two gears with n0 and n1 teeth respectively, the gear ratio is n0/n1. + + \note You may need to use a negative gear ratio if the joint frames of involved actors are not oriented in the same direction. + + \note Calling this function resets the internal positional error correction term. + + \param[in] ratio Desired ratio between the two hinges. + */ + virtual void setGearRatio(float ratio) = 0; + + /** + \brief Get the gear ratio. + + \return Current ratio + */ + virtual float getGearRatio() const = 0; + + virtual const char* getConcreteTypeName() const { return "PxGearJoint"; } + + protected: + + PX_INLINE PxGearJoint(PxType concreteType, PxBaseFlags baseFlags) : PxJoint(concreteType, baseFlags) {} + + PX_INLINE PxGearJoint(PxBaseFlags baseFlags) : PxJoint(baseFlags) {} + + virtual bool isKindOf(const char* name) const { return !::strcmp("PxGearJoint", name) || PxJoint::isKindOf(name); } + }; + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/extensions/PxGjkQueryExt.h b/Source/ThirdParty/PhysX/extensions/PxGjkQueryExt.h new file mode 100644 index 000000000..afaeb14be --- /dev/null +++ b/Source/ThirdParty/PhysX/extensions/PxGjkQueryExt.h @@ -0,0 +1,212 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_GJK_QUERY_EXT_H +#define PX_GJK_QUERY_EXT_H + +#include "geometry/PxGjkQuery.h" +#include "geometry/PxGeometry.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +class PxSphereGeometry; +class PxCapsuleGeometry; +class PxBoxGeometry; +class PxConvexMeshGeometry; +class PxContactBuffer; +class PxConvexMesh; + +/** +\brief Pre-made support mapping for built-in convex geometry types. +*/ +class PxGjkQueryExt +{ +public: + /** + \brief Pre-made support mapping for a sphere + */ + struct SphereSupport : PxGjkQuery::Support + { + PxReal radius; + + /** + \brief Default constructor + */ + SphereSupport(); + /** + \brief Constructs a SphereSupport for a sphere radius + */ + SphereSupport(PxReal radius); + /** + \brief Constructs a SphereSupport for a PxSphereGeometry + */ + SphereSupport(const PxSphereGeometry& geom); + + virtual PxReal getMargin() const; + virtual PxVec3 supportLocal(const PxVec3& dir) const; + }; + + /** + \brief Pre-made support mapping for a capsule + */ + struct CapsuleSupport : PxGjkQuery::Support + { + PxReal radius, halfHeight; + + /** + \brief Default constructor + */ + CapsuleSupport(); + /** + \brief Constructs a CapsuleSupport for capsule radius and halfHeight + */ + CapsuleSupport(PxReal radius, PxReal halfHeight); + /** + \brief Constructs a CapsuleSupport for a PxCapsuleGeometry + */ + CapsuleSupport(const PxCapsuleGeometry& geom); + + virtual PxReal getMargin() const; + virtual PxVec3 supportLocal(const PxVec3& dir) const; + }; + + /** + \brief Pre-made support mapping for a box + */ + struct BoxSupport : PxGjkQuery::Support + { + PxVec3 halfExtents; + PxReal margin; + + /** + \brief Default constructor + */ + BoxSupport(); + /** + \brief Constructs a BoxSupport for a box halfExtents with optional margin + */ + BoxSupport(const PxVec3& halfExtents, PxReal margin = 0); + /** + \brief Constructs a BoxSupport for a PxBoxGeometry + */ + BoxSupport(const PxBoxGeometry& box, PxReal margin = 0); + + virtual PxReal getMargin() const; + virtual PxVec3 supportLocal(const PxVec3& dir) const; + }; + + /** + \brief Pre-made support mapping for a convex mesh + */ + struct ConvexMeshSupport : PxGjkQuery::Support + { + const PxConvexMesh* convexMesh; + PxVec3 scale; + PxQuat scaleRotation; + PxReal margin; + + /** + \brief Default constructor + */ + ConvexMeshSupport(); + /** + \brief Constructs a BoxSupport for a PxConvexMesh + */ + ConvexMeshSupport(const PxConvexMesh& convexMesh, const PxVec3& scale = PxVec3(1), const PxQuat& scaleRotation = PxQuat(PxIdentity), PxReal margin = 0); + /** + \brief Constructs a BoxSupport for a PxConvexMeshGeometry + */ + ConvexMeshSupport(const PxConvexMeshGeometry& convexMesh, PxReal margin = 0); + + virtual PxReal getMargin() const; + virtual PxVec3 supportLocal(const PxVec3& dir) const; + }; + + /** + \brief Pre-made support mapping for any PhysX's convex geometry (sphere, capsule, box, convex mesh) + */ + struct ConvexGeomSupport : PxGjkQuery::Support + { + /** + \brief Default constructor + */ + ConvexGeomSupport(); + /** + \brief Constructs a BoxSupport for a PxGeometry + */ + ConvexGeomSupport(const PxGeometry& geom, PxReal margin = 0); + /** + \brief Destructor + */ + ~ConvexGeomSupport(); + + /** + \brief Returns false if ConvexGeomSupport was constructed from non-convex geometry + */ + bool isValid() const; + + virtual PxReal getMargin() const; + virtual PxVec3 supportLocal(const PxVec3& dir) const; + + private: + PxGeometryType::Enum mType; + union { + void* alignment; + PxU8 sphere[sizeof(SphereSupport)]; + PxU8 capsule[sizeof(CapsuleSupport)]; + PxU8 box[sizeof(BoxSupport)]; + PxU8 convexMesh[sizeof(ConvexMeshSupport)]; + } mSupport; + }; + + /** + \brief Generates a contact point between two shapes using GJK-EPA algorithm + + \param[in] a Shape A support mapping + \param[in] b Shape B support mapping + \param[in] poseA Shape A transformation + \param[in] poseB Shape B transformation + \param[in] contactDistance The distance at which contacts begin to be generated between the shapes + \param[in] toleranceLength The toleranceLength. Used for scaling distance-based thresholds internally to produce appropriate results given simulations in different units + \param[out] contactBuffer A buffer to store the contact + + \return True if there is a contact. + */ + static bool generateContacts(const PxGjkQuery::Support& a, const PxGjkQuery::Support& b, const PxTransform& poseA, const PxTransform& poseB, + PxReal contactDistance, PxReal toleranceLength, PxContactBuffer& contactBuffer); + +}; + +#if !PX_DOXYGEN +} +#endif + +#endif diff --git a/Source/ThirdParty/PhysX/extensions/PxJoint.h b/Source/ThirdParty/PhysX/extensions/PxJoint.h index 43e8785d3..0d469c00b 100644 --- a/Source/ThirdParty/PhysX/extensions/PxJoint.h +++ b/Source/ThirdParty/PhysX/extensions/PxJoint.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PX_JOINTCONSTRAINT_H -#define PX_JOINTCONSTRAINT_H +#ifndef PX_JOINT_H +#define PX_JOINT_H /** \addtogroup extensions @{ */ @@ -64,18 +63,22 @@ struct PxJointConcreteType eDISTANCE, eD6, eCONTACT, + eGEAR, + eRACK_AND_PINION, eLast }; }; -PX_DEFINE_TYPEINFO(PxJoint, PxConcreteType::eUNDEFINED) -PX_DEFINE_TYPEINFO(PxD6Joint, PxJointConcreteType::eD6) -PX_DEFINE_TYPEINFO(PxDistanceJoint, PxJointConcreteType::eDISTANCE) -PX_DEFINE_TYPEINFO(PxContactJoint, PxJointConcreteType::eCONTACT) -PX_DEFINE_TYPEINFO(PxFixedJoint, PxJointConcreteType::eFIXED) -PX_DEFINE_TYPEINFO(PxPrismaticJoint, PxJointConcreteType::ePRISMATIC) -PX_DEFINE_TYPEINFO(PxRevoluteJoint, PxJointConcreteType::eREVOLUTE) -PX_DEFINE_TYPEINFO(PxSphericalJoint, PxJointConcreteType::eSPHERICAL) +PX_DEFINE_TYPEINFO(PxJoint, PxConcreteType::eUNDEFINED) +PX_DEFINE_TYPEINFO(PxRackAndPinionJoint, PxJointConcreteType::eRACK_AND_PINION) +PX_DEFINE_TYPEINFO(PxGearJoint, PxJointConcreteType::eGEAR) +PX_DEFINE_TYPEINFO(PxD6Joint, PxJointConcreteType::eD6) +PX_DEFINE_TYPEINFO(PxDistanceJoint, PxJointConcreteType::eDISTANCE) +PX_DEFINE_TYPEINFO(PxContactJoint, PxJointConcreteType::eCONTACT) +PX_DEFINE_TYPEINFO(PxFixedJoint, PxJointConcreteType::eFIXED) +PX_DEFINE_TYPEINFO(PxPrismaticJoint, PxJointConcreteType::ePRISMATIC) +PX_DEFINE_TYPEINFO(PxRevoluteJoint, PxJointConcreteType::eREVOLUTE) +PX_DEFINE_TYPEINFO(PxSphericalJoint, PxJointConcreteType::eSPHERICAL) /** diff --git a/Source/ThirdParty/PhysX/extensions/PxJointLimit.h b/Source/ThirdParty/PhysX/extensions/PxJointLimit.h index 2f89138a9..c00cbacb6 100644 --- a/Source/ThirdParty/PhysX/extensions/PxJointLimit.h +++ b/Source/ThirdParty/PhysX/extensions/PxJointLimit.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PX_EXTENSIONS_JOINT_LIMIT -#define PX_EXTENSIONS_JOINT_LIMIT +#ifndef PX_JOINT_LIMIT_H +#define PX_JOINT_LIMIT_H /** \addtogroup extensions @{ */ @@ -101,8 +100,8 @@ public: PxReal damping; /** - \brief the distance inside the limit value at which the limit will be considered to be active by the - solver. As this value is made larger, the limit becomes active more quickly. It thus becomes less + \brief The distance inside the limit value at which the limit will be considered to be active by the + solver. As this value is made larger, the limit becomes active more quickly. It thus becomes less likely to violate the extents of the limit, but more expensive. The contact distance should be less than the limit angle or distance, and in the case of a pair limit, @@ -113,16 +112,18 @@ public: Default: depends on the joint + \note This is deprecated in PhysX 5.1 + @see PxPhysics::getTolerancesScale() */ - PxReal contactDistance; + PxReal contactDistance_deprecated; PxJointLimitParameters() : restitution (0.0f), bounceThreshold (0.0f), stiffness (0.0f), damping (0.0f), - contactDistance (0.0f) + contactDistance_deprecated (0.0f) { } @@ -131,7 +132,7 @@ public: bounceThreshold (p.bounceThreshold), stiffness (p.stiffness), damping (p.damping), - contactDistance (p.contactDistance) + contactDistance_deprecated (p.contactDistance_deprecated) { } @@ -146,7 +147,7 @@ public: PxIsFinite(stiffness) && stiffness >= 0 && PxIsFinite(damping) && damping >= 0 && PxIsFinite(bounceThreshold) && bounceThreshold >= 0 && - PxIsFinite(contactDistance) && contactDistance >= 0; + PxIsFinite(contactDistance_deprecated) && contactDistance_deprecated >= 0; } PX_INLINE bool isSoft() const @@ -182,16 +183,16 @@ public: /** \brief construct a linear hard limit - \param[in] scale A PxTolerancesScale struct. Should be the same as used when creating the PxPhysics object. - \param[in] extent The extent of the limit - \param[in] contactDist The distance from the limit at which it becomes active. Default is 0.01f scaled by the tolerance length scale + \param[in] scale A PxTolerancesScale struct. Should be the same as used when creating the PxPhysics object. + \param[in] extent The extent of the limit + \param[in] contactDist_deprecated The distance from the limit at which it becomes active. Default is 0.01f scaled by the tolerance length scale. This is deprecated in PhysX 5.1. @see PxJointLimitParameters PxTolerancesScale */ - PxJointLinearLimit(const PxTolerancesScale& scale, PxReal extent, PxReal contactDist = -1.0f) + PxJointLinearLimit(const PxTolerancesScale& scale, PxReal extent, PxReal contactDist_deprecated = -1.0f) : value(extent) { - PxJointLimitParameters::contactDistance = contactDist == -1.0f ? 0.01f*scale.length : contactDist; + PxJointLimitParameters::contactDistance_deprecated = contactDist_deprecated == -1.0f ? 0.01f*scale.length : contactDist_deprecated; } /** @@ -246,18 +247,18 @@ public: /** \brief Construct a linear hard limit pair. The lower distance value must be less than the upper distance value. - \param[in] scale A PxTolerancesScale struct. Should be the same as used when creating the PxPhysics object. - \param[in] lowerLimit The lower distance of the limit - \param[in] upperLimit The upper distance of the limit - \param[in] contactDist The distance from the limit at which it becomes active. Default is the lesser of 0.01f scaled by the tolerance length scale, and 0.49 * (upperLimit - lowerLimit) + \param[in] scale A PxTolerancesScale struct. Should be the same as used when creating the PxPhysics object. + \param[in] lowerLimit The lower distance of the limit + \param[in] upperLimit The upper distance of the limit + \param[in] contactDist_deprecated The distance from the limit at which it becomes active. Default is the lesser of 0.01f scaled by the tolerance length scale, and 0.49 * (upperLimit - lowerLimit). This is deprecated in PhysX 5.1. @see PxJointLimitParameters PxTolerancesScale */ - PxJointLinearLimitPair(const PxTolerancesScale& scale, PxReal lowerLimit = -PX_MAX_F32/3.0f, PxReal upperLimit = PX_MAX_F32/3.0f, PxReal contactDist = -1.0f) : + PxJointLinearLimitPair(const PxTolerancesScale& scale, PxReal lowerLimit = -PX_MAX_F32/3.0f, PxReal upperLimit = PX_MAX_F32/3.0f, PxReal contactDist_deprecated = -1.0f) : upper(upperLimit), lower(lowerLimit) { - PxJointLimitParameters::contactDistance = contactDist == -1.0f ? PxMin(scale.length * 0.01f, (upperLimit*0.49f-lowerLimit*0.49f)) : contactDist; + PxJointLimitParameters::contactDistance_deprecated = contactDist_deprecated == -1.0f ? PxMin(scale.length * 0.01f, (upperLimit*0.49f-lowerLimit*0.49f)) : contactDist_deprecated; bounceThreshold = 2.0f*scale.length; } @@ -315,17 +316,17 @@ public: The lower value must be less than the upper value. - \param[in] lowerLimit The lower angle of the limit - \param[in] upperLimit The upper angle of the limit - \param[in] contactDist The distance from the limit at which it becomes active. Default is the lesser of 0.1 radians, and 0.49 * (upperLimit - lowerLimit) + \param[in] lowerLimit The lower angle of the limit + \param[in] upperLimit The upper angle of the limit + \param[in] contactDist_deprecated The distance from the limit at which it becomes active. Default is the lesser of 0.1 radians, and 0.49 * (upperLimit - lowerLimit). This is deprecated in PhysX 5.1. @see PxJointLimitParameters */ - PxJointAngularLimitPair(PxReal lowerLimit, PxReal upperLimit, PxReal contactDist = -1.0f) : + PxJointAngularLimitPair(PxReal lowerLimit, PxReal upperLimit, PxReal contactDist_deprecated = -1.0f) : upper(upperLimit), lower(lowerLimit) { - PxJointLimitParameters::contactDistance = contactDist ==-1.0f ? PxMin(0.1f, 0.49f*(upperLimit-lowerLimit)) : contactDist; + PxJointLimitParameters::contactDistance_deprecated = contactDist_deprecated ==-1.0f ? PxMin(0.1f, 0.49f*(upperLimit-lowerLimit)) : contactDist_deprecated; bounceThreshold = 0.5f; } @@ -396,17 +397,17 @@ public: /** \brief Construct a cone hard limit. - \param[in] yLimitAngle The limit angle from the Y-axis of the constraint frame - \param[in] zLimitAngle The limit angle from the Z-axis of the constraint frame - \param[in] contactDist The distance from the limit at which it becomes active. Default is the lesser of 0.1 radians, and 0.49 * the lower of the limit angles + \param[in] yLimitAngle The limit angle from the Y-axis of the constraint frame + \param[in] zLimitAngle The limit angle from the Z-axis of the constraint frame + \param[in] contactDist_deprecated The distance from the limit at which it becomes active. Default is the lesser of 0.1 radians, and 0.49 * the lower of the limit angles. This is deprecated in PhysX 5.1. @see PxJointLimitParameters */ - PxJointLimitCone(PxReal yLimitAngle, PxReal zLimitAngle, PxReal contactDist = -1.0f) : + PxJointLimitCone(PxReal yLimitAngle, PxReal zLimitAngle, PxReal contactDist_deprecated = -1.0f) : yAngle(yLimitAngle), zAngle(zLimitAngle) { - PxJointLimitParameters::contactDistance = contactDist == -1.0f ? PxMin(0.1f, PxMin(yLimitAngle, zLimitAngle)*0.49f) : contactDist; + PxJointLimitParameters::contactDistance_deprecated = contactDist_deprecated == -1.0f ? PxMin(0.1f, PxMin(yLimitAngle, zLimitAngle)*0.49f) : contactDist_deprecated; bounceThreshold = 0.5f; } @@ -493,29 +494,29 @@ public: /** \brief Construct a pyramid hard limit. - \param[in] yLimitAngleMin The minimum limit angle from the Y-axis of the constraint frame - \param[in] yLimitAngleMax The maximum limit angle from the Y-axis of the constraint frame - \param[in] zLimitAngleMin The minimum limit angle from the Z-axis of the constraint frame - \param[in] zLimitAngleMax The maximum limit angle from the Z-axis of the constraint frame - \param[in] contactDist The distance from the limit at which it becomes active. Default is the lesser of 0.1 radians, and 0.49 * the lower of the limit angles + \param[in] yLimitAngleMin The minimum limit angle from the Y-axis of the constraint frame + \param[in] yLimitAngleMax The maximum limit angle from the Y-axis of the constraint frame + \param[in] zLimitAngleMin The minimum limit angle from the Z-axis of the constraint frame + \param[in] zLimitAngleMax The maximum limit angle from the Z-axis of the constraint frame + \param[in] contactDist_deprecated The distance from the limit at which it becomes active. Default is the lesser of 0.1 radians, and 0.49 * the lower of the limit angles. This is deprecated in PhysX 5.1. @see PxJointLimitParameters */ - PxJointLimitPyramid(PxReal yLimitAngleMin, PxReal yLimitAngleMax, PxReal zLimitAngleMin, PxReal zLimitAngleMax, PxReal contactDist = -1.0f) : + PxJointLimitPyramid(PxReal yLimitAngleMin, PxReal yLimitAngleMax, PxReal zLimitAngleMin, PxReal zLimitAngleMax, PxReal contactDist_deprecated = -1.0f) : yAngleMin(yLimitAngleMin), yAngleMax(yLimitAngleMax), zAngleMin(zLimitAngleMin), zAngleMax(zLimitAngleMax) { - if(contactDist == -1.0f) + if(contactDist_deprecated == -1.0f) { const PxReal contactDistY = PxMin(0.1f, 0.49f*(yLimitAngleMax - yLimitAngleMin)); const PxReal contactDistZ = PxMin(0.1f, 0.49f*(zLimitAngleMax - zLimitAngleMin)); - PxJointLimitParameters::contactDistance = contactDist == PxMin(contactDistY, contactDistZ); + PxJointLimitParameters::contactDistance_deprecated = contactDist_deprecated == PxMin(contactDistY, contactDistZ); } else { - PxJointLimitParameters::contactDistance = contactDist; + PxJointLimitParameters::contactDistance_deprecated = contactDist_deprecated; } bounceThreshold = 0.5f; diff --git a/Source/ThirdParty/PhysX/extensions/PxMassProperties.h b/Source/ThirdParty/PhysX/extensions/PxMassProperties.h index 9f44bf1eb..a7acf5985 100644 --- a/Source/ThirdParty/PhysX/extensions/PxMassProperties.h +++ b/Source/ThirdParty/PhysX/extensions/PxMassProperties.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_EXTENSIONS_MASS_PROPERTIES_H -#define PX_PHYSICS_EXTENSIONS_MASS_PROPERTIES_H +#ifndef PX_MASS_PROPERTIES_H +#define PX_MASS_PROPERTIES_H /** \addtogroup extensions @{ */ @@ -47,6 +45,9 @@ #include "geometry/PxCapsuleGeometry.h" #include "geometry/PxConvexMeshGeometry.h" #include "geometry/PxConvexMesh.h" +#include "geometry/PxCustomGeometry.h" +#include "geometry/PxTriangleMeshGeometry.h" +#include "geometry/PxTriangleMesh.h" #if !PX_DOXYGEN namespace physx @@ -135,20 +136,47 @@ public: const PxMeshScale& s = c.scale; mass = unscaledMass * s.scale.x * s.scale.y * s.scale.z; - centerOfMass = s.rotation.rotate(s.scale.multiply(s.rotation.rotateInv(unscaledCoM))); + centerOfMass = s.transform(unscaledCoM); inertiaTensor = scaleInertia(unscaledInertiaTensorCOM, s.rotation, s.scale); } break; - case PxGeometryType::eHEIGHTFIELD: - case PxGeometryType::ePLANE: + case PxGeometryType::eCUSTOM: + { + *this = PxMassProperties(); + static_cast(geometry).callbacks->computeMassProperties(geometry, *this); + } + break; + case PxGeometryType::eTRIANGLEMESH: - case PxGeometryType::eINVALID: - case PxGeometryType::eGEOMETRY_COUNT: + { + const PxTriangleMeshGeometry& g = static_cast(geometry); + + PxVec3 unscaledCoM; + PxMat33 unscaledInertiaTensorNonCOM; // inertia tensor of convex mesh in mesh local space + PxMat33 unscaledInertiaTensorCOM; + PxReal unscaledMass; + g.triangleMesh->getMassInformation(unscaledMass, unscaledInertiaTensorNonCOM, unscaledCoM); + + // inertia tensor relative to center of mass + unscaledInertiaTensorCOM[0][0] = unscaledInertiaTensorNonCOM[0][0] - unscaledMass * PxReal((unscaledCoM.y*unscaledCoM.y + unscaledCoM.z*unscaledCoM.z)); + unscaledInertiaTensorCOM[1][1] = unscaledInertiaTensorNonCOM[1][1] - unscaledMass * PxReal((unscaledCoM.z*unscaledCoM.z + unscaledCoM.x*unscaledCoM.x)); + unscaledInertiaTensorCOM[2][2] = unscaledInertiaTensorNonCOM[2][2] - unscaledMass * PxReal((unscaledCoM.x*unscaledCoM.x + unscaledCoM.y*unscaledCoM.y)); + unscaledInertiaTensorCOM[0][1] = unscaledInertiaTensorCOM[1][0] = (unscaledInertiaTensorNonCOM[0][1] + unscaledMass * PxReal(unscaledCoM.x*unscaledCoM.y)); + unscaledInertiaTensorCOM[1][2] = unscaledInertiaTensorCOM[2][1] = (unscaledInertiaTensorNonCOM[1][2] + unscaledMass * PxReal(unscaledCoM.y*unscaledCoM.z)); + unscaledInertiaTensorCOM[0][2] = unscaledInertiaTensorCOM[2][0] = (unscaledInertiaTensorNonCOM[0][2] + unscaledMass * PxReal(unscaledCoM.z*unscaledCoM.x)); + + const PxMeshScale& s = g.scale; + mass = unscaledMass * s.scale.x * s.scale.y * s.scale.z; + centerOfMass = s.transform(unscaledCoM); + inertiaTensor = scaleInertia(unscaledInertiaTensorCOM, s.rotation, s.scale); + } + break; + + default: { *this = PxMassProperties(); } - break; } PX_ASSERT(inertiaTensor.column0.isFinite() && inertiaTensor.column1.isFinite() && inertiaTensor.column2.isFinite()); @@ -229,7 +257,8 @@ public: \brief Rotate an inertia tensor around the center of mass \param[in] inertia The inertia tensor to rotate. - \param[in] q The rotation to apply to the inertia tensor. + \param[in] q The rotation from the new to the old coordinate frame, i.e. q.rotate(v) transforms + the coordinates of vector v from the old to the new coordinate frame. \return The rotated inertia tensor. */ PX_FORCE_INLINE static PxMat33 rotateInertia(const PxMat33& inertia, const PxQuat& q) @@ -247,8 +276,9 @@ public: \brief Non-uniform scaling of the inertia tensor \param[in] inertia The inertia tensor to scale. - \param[in] scaleRotation The frame of the provided scaling factors. - \param[in] scale The scaling factor for each axis (relative to the frame specified in scaleRotation). + \param[in] scaleRotation The rotation from the scaling frame to the frame that inertia is expressed in. + I.e. scaleRotation.rotate(v) transforms the coordinates of vertex v from inertia's frame to the scaling-axes frame. + \param[in] scale The scaling factor for each axis (relative to the frame specified with scaleRotation). \return The scaled inertia tensor. */ static PxMat33 scaleInertia(const PxMat33& inertia, const PxQuat& scaleRotation, const PxVec3& scale) diff --git a/Source/ThirdParty/PhysX/extensions/PxParticleClothCooker.h b/Source/ThirdParty/PhysX/extensions/PxParticleClothCooker.h new file mode 100644 index 000000000..537e86f6c --- /dev/null +++ b/Source/ThirdParty/PhysX/extensions/PxParticleClothCooker.h @@ -0,0 +1,119 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_PARTICLE_CLOTH_COOKER_H +#define PX_PARTICLE_CLOTH_COOKER_H +/** \addtogroup extensions + @{ +*/ + +#include "foundation/PxSimpleTypes.h" +#include "foundation/PxVec4.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +namespace ExtGpu +{ + +/** +\brief Holds all the information for a particle cloth constraint used in the PxParticleClothCooker. +*/ +struct PxParticleClothConstraint +{ + enum + { + eTYPE_INVALID_CONSTRAINT = 0, + eTYPE_HORIZONTAL_CONSTRAINT = 1, + eTYPE_VERTICAL_CONSTRAINT = 2, + eTYPE_DIAGONAL_CONSTRAINT = 4, + eTYPE_BENDING_CONSTRAINT = 8, + eTYPE_DIAGONAL_BENDING_CONSTRAINT = 16, + eTYPE_ALL = eTYPE_HORIZONTAL_CONSTRAINT | eTYPE_VERTICAL_CONSTRAINT | eTYPE_DIAGONAL_CONSTRAINT | eTYPE_BENDING_CONSTRAINT | eTYPE_DIAGONAL_BENDING_CONSTRAINT + }; + PxU32 particleIndexA; //!< The first particle index of this constraint. + PxU32 particleIndexB; //!< The second particle index of this constraint. + PxReal length; //!< The distance between particle A and B. + PxU32 constraintType; //!< The type of constraint, see the constraint type enum. +}; + +/* +\brief Generates PxParticleClothConstraint constraints that connect the individual particles of a particle cloth. +*/ +class PxParticleClothCooker +{ +public: + virtual void release() = 0; + + /** + \brief Generate the constraint list and triangle index list. + + \param[in] constraints A pointer to an array of PxParticleClothConstraint constraints. If NULL, the cooker will generate all the constraints. Otherwise, the user-provided constraints will be added. + \param[in] numConstraints The number of user-provided PxParticleClothConstraint s. + */ + virtual void cookConstraints(const PxParticleClothConstraint* constraints = NULL, const PxU32 numConstraints = 0) = 0; + + virtual PxU32* getTriangleIndices() = 0; //!< \return A pointer to the triangle indices. + virtual PxU32 getTriangleIndicesCount() = 0; //!< \return The number of triangle indices. + virtual PxParticleClothConstraint* getConstraints() = 0; //!< \return A pointer to the PxParticleClothConstraint constraints. + virtual PxU32 getConstraintCount() = 0; //!< \return The number of constraints. + virtual void calculateMeshVolume() = 0; //!< Computes the volume of a closed mesh and the contraintScale. Expects vertices in local space - 'close' to origin. + virtual PxReal getMeshVolume() = 0; //!< \return The mesh volume calculated by PxParticleClothCooker::calculateMeshVolume. + +protected: + virtual ~PxParticleClothCooker() {} +}; + +} // namespace ExtGpu + +/** +\brief Creates a PxParticleClothCooker. + +\param[in] vertexCount The number of vertices of the particle cloth. +\param[in] inVertices The vertex positions of the particle cloth. +\param[in] triangleIndexCount The number of triangles of the cloth mesh. +\param[in] inTriangleIndices The triangle indices of the cloth mesh +\param[in] constraintTypeFlags The types of constraints to generate. See PxParticleClothConstraint. +\param[in] verticalDirection The vertical direction of the cloth mesh. This is needed to generate the correct horizontal and vertical constraints to model shear stiffness. +\param[in] bendingConstraintMaxAngle The maximum angle considered in the bending constraints. + +\return A pointer to the new PxParticleClothCooker. +*/ +ExtGpu::PxParticleClothCooker* PxCreateParticleClothCooker(PxU32 vertexCount, physx::PxVec4* inVertices, PxU32 triangleIndexCount, PxU32* inTriangleIndices, + PxU32 constraintTypeFlags = ExtGpu::PxParticleClothConstraint::eTYPE_ALL, PxVec3 verticalDirection = PxVec3(0.0f,1.0f,0.0f), PxReal bendingConstraintMaxAngle = 20.0f/360.0f*PxTwoPi +); + + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/extensions/PxParticleExt.h b/Source/ThirdParty/PhysX/extensions/PxParticleExt.h new file mode 100644 index 000000000..4ad9c5e80 --- /dev/null +++ b/Source/ThirdParty/PhysX/extensions/PxParticleExt.h @@ -0,0 +1,394 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_PARTICLE_EXT_H +#define PX_PARTICLE_EXT_H +/** \addtogroup extensions + @{ +*/ + +#include "PxParticleSystem.h" +#include "PxParticleBuffer.h" +#include "foundation/PxArray.h" +#include "foundation/PxHashMap.h" +#include "foundation/PxUserAllocated.h" +#include "PxAttachment.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +namespace ExtGpu +{ + +/** +\brief Structure to define user-defined particle state when constructing a new particle system. +*/ +struct PxParticleBufferDesc +{ + PxVec4* positions; + PxVec4* velocities; + PxU32* phases; + PxParticleVolume* volumes; + PxU32 numActiveParticles; + PxU32 maxParticles; + PxU32 numVolumes; + PxU32 maxVolumes; + + PxParticleBufferDesc() : positions(NULL), velocities(NULL), phases(NULL), volumes(NULL), numActiveParticles(0), maxParticles(0), numVolumes(0), maxVolumes(0) { } +}; + +/** +\brief Structure to define user-defined particle state when constructing a new particle system that includes diffuse particles. +*/ +struct PxParticleAndDiffuseBufferDesc : public PxParticleBufferDesc +{ + PxDiffuseParticleParams diffuseParams; + PxU32 maxDiffuseParticles; + PxU32 maxActiveDiffuseParticles; + + PxParticleAndDiffuseBufferDesc() : PxParticleBufferDesc() { } +}; + +/** +\brief Structure to define user-defined particle state when constructing a new particle system that includes shape-matched rigid bodies. +*/ +struct PxParticleRigidDesc +{ + PxParticleRigidDesc() : rigidOffsets(NULL), rigidCoefficients(NULL), rigidTranslations(NULL), rigidRotations(NULL), + rigidLocalPositions(NULL), rigidLocalNormals(NULL), maxRigids(0), numActiveRigids(0) { } + + PxU32* rigidOffsets; + PxReal* rigidCoefficients; + PxVec4* rigidTranslations; + PxQuat* rigidRotations; + PxVec4* rigidLocalPositions; + PxVec4* rigidLocalNormals; + PxU32 maxRigids; + PxU32 numActiveRigids; +}; + +////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// + +/** +\brief Helper class to manage PxParticleClothDesc buffers used for communicating particle based cloths to PxParticleClothBuffer. +*/ +class PxParticleClothBufferHelper +{ +public: + virtual void release() = 0; + + virtual PxU32 getMaxCloths() const = 0; //!< \return The maximum number of cloths this PxParticleClothBufferHelper can hold. + virtual PxU32 getNumCloths() const = 0; //!< \return The current number of cloths in this PxParticleClothBufferHelper. + virtual PxU32 getMaxSprings() const = 0; //!< \return The maximum number of springs this PxParticleClothBufferHelper can hold. + virtual PxU32 getNumSprings() const = 0; //!< \return The current number of springs in this PxParticleClothBufferHelper. + virtual PxU32 getMaxTriangles() const = 0; //!< \return The maximum number of triangles this PxParticleClothBufferHelper can hold. + virtual PxU32 getNumTriangles() const = 0; //!< \return The current number of triangles in this PxParticleClothBufferHelper. + virtual PxU32 getMaxParticles() const = 0; //!< \return The maximum number of particles this PxParticleClothBufferHelper can hold. + virtual PxU32 getNumParticles() const = 0; //!< \return The current number of particles in this PxParticleClothBufferHelper. + + /** + \brief Adds a PxParticleCloth to this PxParticleClothBufferHelper instance. + + \param[in] particleCloth The PxParticleCloth to be added. + \param[in] triangles A pointer to the triangles + \param[in] numTriangles The number of triangles + \param[in] springs A pointer to the springs + \param[in] numSprings The number of springs + \param[in] restPositions A pointer to the particle rest positions + \param[in] numParticles The number of particles in this cloth + + @see PxParticleCloth PxParticleSpring + */ + virtual void addCloth(const PxParticleCloth& particleCloth, + const PxU32* triangles, const PxU32 numTriangles, + const PxParticleSpring* springs, const PxU32 numSprings, const PxVec4* restPositions, const PxU32 numParticles) = 0; + + /** + \brief Adds a cloth to this PxParticleClothBufferHelper instance. + + Adds a cloth to this PxParticleClothBufferHelper instance. With this method the relevant parameters for inflatable simulation + (restVolume, pressure) can be set directly. + + \param[in] blendScale This should be 1.f / (numPartitions + 1) if the springs are partitioned by the user. Otherwise this will be set during spring partitioning. + \param[in] restVolume The rest volume of the inflatable + \param[in] pressure The pressure of the inflatable. The target inflatable volume is defined as restVolume * pressure. Setting this to > 0.0 will enable inflatable simulation. + \param[in] triangles A pointer to the triangles + \param[in] numTriangles The number of triangles + \param[in] springs A pointer to the springs + \param[in] numSprings The number of springs + \param[in] restPositions A pointer to the particle rest positions + \param[in] numParticles The number of particles in this cloth + + @see PxParticleSpring + */ + virtual void addCloth(const PxReal blendScale, const PxReal restVolume, const PxReal pressure, + const PxU32* triangles, const PxU32 numTriangles, + const PxParticleSpring* springs, const PxU32 numSprings, + const PxVec4* restPositions, const PxU32 numParticles) = 0; + + /** + \brief Returns a PxParticleClothDesc for this PxParticleClothBufferHelper instance to be used for spring partitioning. + + \return the PxParticleClothDesc. + + @see PxCreateAndPopulateParticleClothBuffer, PxParticleClothPreProcessor::partitionSprings + */ + virtual PxParticleClothDesc& getParticleClothDesc() = 0; + +protected: + virtual ~PxParticleClothBufferHelper() {} +}; + + +/** +\brief Helper struct that holds information about a specific mesh in a PxParticleVolumeBufferHelper. +*/ +struct PxParticleVolumeMesh +{ + PxU32 startIndex; //!< The index of the first triangle of this mesh in the triangle array of the PxParticleVolumeBufferHelper instance. + PxU32 count; //!< The number of triangles of this mesh. +}; + +/** +\brief Helper class to manage communicating PxParticleVolumes data to PxParticleBuffer. +*/ +class PxParticleVolumeBufferHelper +{ +public: + virtual void release() = 0; + + virtual PxU32 getMaxVolumes() const = 0; //!< \return The maximum number of PxParticleVolume this PxParticleVolumeBufferHelper instance can hold. + virtual PxU32 getNumVolumes() const = 0; //!< \return The current number of PxParticleVolume in this PxParticleVolumeBufferHelper instance. + virtual PxU32 getMaxTriangles() const = 0; //!< \return The maximum number of triangles this PxParticleVolumeBufferHelper instance can hold. + virtual PxU32 getNumTriangles() const = 0; //!< \return The current number of triangles in this PxParticleVolumeBufferHelper instance. + + virtual PxParticleVolume* getParticleVolumes() = 0; //!< \return A pointer to the PxParticleVolume s of this PxParticleVolumeBufferHelper instance. + virtual PxParticleVolumeMesh* getParticleVolumeMeshes() = 0; //!< \return A pointer to the PxParticleVolumeMesh structs describing the PxParticleVolumes of this PxParticleVolumeBufferHelper instance. + virtual PxU32* getTriangles() = 0; //!< \return A pointer to the triangle indices in this PxParticleVolumeBufferHelper instance. + + /** + \brief Adds a PxParticleVolume with a PxParticleVolumeMesh + + \param[in] volume The PxParticleVolume to be added. + \param[in] volumeMesh A PxParticleVolumeMesh that describes the volumes to be added. startIndex is the index into the triangle list of the PxParticleVolumeBufferHelper instance. + \param[in] triangles A pointer to the triangle indices of the PxParticleVolume to be added. + \param[in] numTriangles The number of triangles of the PxParticleVolume to be added. + */ + virtual void addVolume(const PxParticleVolume& volume, const PxParticleVolumeMesh& volumeMesh, const PxU32* triangles, const PxU32 numTriangles) = 0; + + /** + \brief Adds a volume + + \param[in] particleOffset The index of the first particle of the cloth that maps to this volume in the PxParticleClothBufferHelper instance. + \param[in] numParticles The number of particles of the cloth that maps to this volume in the PxParticleClothBufferHelper instance. + \param[in] triangles A pointer to the triangle indices of this volume. + \param[in] numTriangles The number of triangles in this volume. + */ + virtual void addVolume(const PxU32 particleOffset, const PxU32 numParticles, const PxU32* triangles, const PxU32 numTriangles) = 0; + +protected: + virtual ~PxParticleVolumeBufferHelper() {} +}; + + +/** +\brief Helper class to manage PxParticleRigidDesc buffers used for communicating particle based rigids to PxPaticleSystem. +*/ +class PxParticleRigidBufferHelper +{ +public: + virtual void release() = 0; + + virtual PxU32 getMaxRigids() const = 0; //!< \return The maximum number of rigids this PxParticleRigidBufferHelper instance can hold. + virtual PxU32 getNumRigids() const = 0; //!< \return The current number of rigids in this PxParticleRigidBufferHelper instance. + virtual PxU32 getMaxParticles() const = 0; //!< \return The maximum number of particles this PxParticleRigidBufferHelper instance can hold. + virtual PxU32 getNumParticles() const = 0; //!< \return The current number of particles in this PxParticleRigidBufferHelper instance. + + /** + \brief Adds a rigid. + + \param[in] translation The world-space location of the rigid. + \param[in] rotation The world-space rotation of the rigid. + \param[in] coefficient The stiffness of the rigid. + \param[in] localPositions The particle positions in local space. + \param[in] localNormals The surface normal for all the particles in local space. Each PxVec4 has the normal in the first 3 components and the SDF in the last component. + \param[in] numParticles The number of particles in this rigid. + */ + virtual void addRigid(const PxVec3& translation, const PxQuat& rotation, const PxReal coefficient, + const PxVec4* localPositions, const PxVec4* localNormals, PxU32 numParticles) = 0; + + /** + \brief Get the PxParticleRigidDesc for this buffer. + + \returns A PxParticleRigidDesc. + */ + virtual PxParticleRigidDesc& getParticleRigidDesc() = 0; + +protected: + virtual ~PxParticleRigidBufferHelper() {} +}; + +/////////////////////////////////////////////////////////////////////////////// + +/** +\brief Holds user-defined attachment data to attach particles to other bodies +*/ +class PxParticleAttachmentBuffer : public PxUserAllocated +{ + PxArray mAttachments; + PxArray mFilters; + PxHashMap mReferencedBodies; + PxArray mNewReferencedBodies; + PxArray mDestroyedRefrencedBodies; + + PxParticleBuffer& mParticleBuffer; + + PxParticleRigidAttachment* mDeviceAttachments; + PxParticleRigidFilterPair* mDeviceFilters; + PxU32 mNumDeviceAttachments; + PxU32 mNumDeviceFilters; + + PxCudaContextManager* mCudaContextManager; + + PxParticleSystem& mParticleSystem; + + bool mDirty; + + PX_NOCOPY(PxParticleAttachmentBuffer) + +public: + + PxParticleAttachmentBuffer(PxParticleBuffer& particleBuffer, PxParticleSystem& particleSystem); + + ~PxParticleAttachmentBuffer(); + + // adds attachment to attachment buffer - localPose is in actor space for attachments to all types of rigids. + void addRigidAttachment(PxRigidActor* rigidBody, const PxU32 particleID, const PxVec3& localPose, PxConeLimitedConstraint* coneLimit = NULL); + bool removeRigidAttachment(PxRigidActor* rigidBody, const PxU32 particleID); + void addRigidFilter(PxRigidActor* rigidBody, const PxU32 particleID); + bool removeRigidFilter(PxRigidActor* rigidBody, const PxU32 particleID); + + void copyToDevice(CUstream stream = 0); +}; + +/** +\brief Creates a PxParticleRigidBufferHelper. + +\param[in] maxRigids The maximum number of rigids this PxParticleRigidsBuffers instance should hold. +\param[in] maxParticles The maximum number of particles this PxParticleRigidBufferHelper instance should hold. +\param[in] cudaContextManager A pointer to a PxCudaContextManager. + +\return A pointer to the new PxParticleRigidBufferHelper. +*/ +PxParticleRigidBufferHelper* PxCreateParticleRigidBufferHelper(PxU32 maxRigids, PxU32 maxParticles, PxCudaContextManager* cudaContextManager); + +/** +\brief Creates a PxParticleClothBufferHelper helper. + +\param[in] maxCloths The maximum number of cloths this PxParticleClothBufferHelper should hold. +\param[in] maxTriangles The maximum number of triangles this PxParticleClothBufferHelper should hold. +\param[in] maxSprings The maximum number of springs this PxParticleClothBufferHelper should hold. +\param[in] maxParticles The maximum number of particles this PxParticleClothBufferHelper should hold. +\param[in] cudaContextManager A pointer to a PxCudaContextManager. + +\return A pointer to the PxParticleClothBufferHelper that was created. +*/ +PxParticleClothBufferHelper* PxCreateParticleClothBufferHelper(const PxU32 maxCloths, const PxU32 maxTriangles, const PxU32 maxSprings, const PxU32 maxParticles, PxCudaContextManager* cudaContextManager); + +/** +\brief Creates a PxParticleVolumeBufferHelper. + +\param[in] maxVolumes The maximum number of PxParticleVolume s this PxParticleVolumeBufferHelper instance should hold. +\param[in] maxTriangles The maximum number of triangles this PxParticleVolumeBufferHelper instance should hold. +\param[in] cudaContextManager A pointer to a PxCudaContextManager. + +\return A pointer to the new PxParticleVolumeBufferHelper. +*/ +PxParticleVolumeBufferHelper* PxCreateParticleVolumeBufferHelper(PxU32 maxVolumes, PxU32 maxTriangles, PxCudaContextManager* cudaContextManager); + +/** +\brief Creates a particle attachment buffer + +\param[in] particleBuffer The particle buffer that contains particles that should get attached to something +\param[in] particleSystem The particle system that is used to simulate the userBuffer +\return An attachment buffer ready to use +*/ +PxParticleAttachmentBuffer* PxCreateParticleAttachmentBuffer(PxParticleBuffer& particleBuffer, PxParticleSystem& particleSystem); + +/** +\brief Creates and populates a particle buffer + +\param[in] desc The particle buffer descriptor +\param[in] cudaContextManager A cuda context manager +\return A fully populated particle buffer ready to use +*/ +PxParticleBuffer* PxCreateAndPopulateParticleBuffer(const ExtGpu::PxParticleBufferDesc& desc, PxCudaContextManager* cudaContextManager); + +/** +\brief Creates and populates a particle buffer that includes support for diffuse particles + +\param[in] desc The particle buffer descriptor +\param[in] cudaContextManager A cuda context manager +\return A fully populated particle buffer ready to use +*/ +PxParticleAndDiffuseBuffer* PxCreateAndPopulateParticleAndDiffuseBuffer(const ExtGpu::PxParticleAndDiffuseBufferDesc& desc, PxCudaContextManager* cudaContextManager); + +/** +\brief Creates and populates a particle cloth buffer + +\param[in] desc The particle buffer descriptor +\param[in] clothDesc The cloth descriptor +\param[out] output A cloth output object to further configure the behavior of the cloth +\param[in] cudaContextManager A cuda context manager +\return A fully populated particle cloth buffer ready to use +*/ +PxParticleClothBuffer* PxCreateAndPopulateParticleClothBuffer(const ExtGpu::PxParticleBufferDesc& desc, const PxParticleClothDesc& clothDesc, + PxPartitionedParticleCloth& output, PxCudaContextManager* cudaContextManager); + +/** +\brief Creates and populates a particle rigid buffer. Particle rigids are particles that try to keep their relative positions. They are a bit commpressible similar to softbodies. + +\param[in] desc The particle buffer descriptor +\param[in] rigidDesc The rigid descriptor +\param[in] cudaContextManager A cuda context manager +\return A fully populated particle rigid buffer ready to use +*/ +PxParticleRigidBuffer* PxCreateAndPopulateParticleRigidBuffer(const ExtGpu::PxParticleBufferDesc& desc, const ExtGpu::PxParticleRigidDesc& rigidDesc, + PxCudaContextManager* cudaContextManager); + +} // namespace ExtGpu + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** @} */ +#endif + diff --git a/Source/ThirdParty/PhysX/extensions/PxPrismaticJoint.h b/Source/ThirdParty/PhysX/extensions/PxPrismaticJoint.h index e59207a0c..d34c190c3 100644 --- a/Source/ThirdParty/PhysX/extensions/PxPrismaticJoint.h +++ b/Source/ThirdParty/PhysX/extensions/PxPrismaticJoint.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PX_PRISMATICJOINT_H -#define PX_PRISMATICJOINT_H +#ifndef PX_PRISMATIC_JOINT_H +#define PX_PRISMATIC_JOINT_H /** \addtogroup extensions @{ */ @@ -163,8 +162,10 @@ public: \param[in] tolerance the linear tolerance threshold @see getProjectionLinearTolerance() + + @deprecated */ - virtual void setProjectionLinearTolerance(PxReal tolerance) = 0; + PX_DEPRECATED virtual void setProjectionLinearTolerance(PxReal tolerance) = 0; /** \brief Get the linear tolerance threshold for projection. @@ -172,8 +173,10 @@ public: \return the linear tolerance threshold in radians @see setProjectionLinearTolerance() + + @deprecated */ - virtual PxReal getProjectionLinearTolerance() const = 0; + PX_DEPRECATED virtual PxReal getProjectionLinearTolerance() const = 0; /** \brief Set the angular tolerance threshold for projection. Projection is enabled if PxConstraintFlag::ePROJECTION @@ -192,15 +195,19 @@ public: \param[in] tolerance the linear tolerance threshold @see getProjectionLinearTolerance() PxJoint::setConstraintFlags() + + @deprecated */ - virtual void setProjectionAngularTolerance(PxReal tolerance) = 0; + PX_DEPRECATED virtual void setProjectionAngularTolerance(PxReal tolerance) = 0; /** \brief Get the angular tolerance threshold for projection. @see getProjectionAngularTolerance() + + @deprecated */ - virtual PxReal getProjectionAngularTolerance() const = 0; + PX_DEPRECATED virtual PxReal getProjectionAngularTolerance() const = 0; /** \brief Returns string name of PxPrismaticJoint, used for serialization diff --git a/Source/ThirdParty/PhysX/extensions/PxRackAndPinionJoint.h b/Source/ThirdParty/PhysX/extensions/PxRackAndPinionJoint.h new file mode 100644 index 000000000..953ff04df --- /dev/null +++ b/Source/ThirdParty/PhysX/extensions/PxRackAndPinionJoint.h @@ -0,0 +1,136 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_RACK_AND_PINION_JOINT_H +#define PX_RACK_AND_PINION_JOINT_H +/** \addtogroup extensions + @{ +*/ + +#include "extensions/PxJoint.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + class PxRackAndPinionJoint; + + /** + \brief Create a rack & pinion Joint. + + \param[in] physics The physics SDK + \param[in] actor0 An actor to which the joint is attached. NULL may be used to attach the joint to a specific point in the world frame + \param[in] localFrame0 The position and orientation of the joint relative to actor0 + \param[in] actor1 An actor to which the joint is attached. NULL may be used to attach the joint to a specific point in the world frame + \param[in] localFrame1 The position and orientation of the joint relative to actor1 + + @see PxRackAndPinionJoint + */ + PxRackAndPinionJoint* PxRackAndPinionJointCreate(PxPhysics& physics, PxRigidActor* actor0, const PxTransform& localFrame0, PxRigidActor* actor1, const PxTransform& localFrame1); + + /** + \brief A joint that connects an existing revolute joint to an existing prismatic joint, + and constrains their relative angular/linear velocity and position with respect to each other. + + @see PxRackAndPinionJointCreate PxJoint + */ + class PxRackAndPinionJoint : public PxJoint + { + public: + + /** + \brief Set the hinge & prismatic joints connected by the rack & pinion joint. + + The passed hinge joint can be either PxRevoluteJoint, PxD6Joint or PxArticulationJointReducedCoordinate. It cannot be null. + The passed prismatic joint can be either PxPrismaticJoint or PxD6Joint. It cannot be null. + + Note that these joints are only used to compute the positional error correction term, + used to adjust potential drift between jointed actors. The rack & pinion joint can run without + calling this function, but in that case some visible overlap may develop over time between + the teeth of the rack & pinion meshes. + + \note Calling this function resets the internal positional error correction term. + + \param[in] hinge The hinge joint (pinion) + \param[in] prismatic The prismatic joint (rack) + \return true if success + */ + virtual bool setJoints(const PxBase* hinge, const PxBase* prismatic) = 0; + + /** + \brief Set the desired ratio directly. + + \note You may need to use a negative gear ratio if the joint frames of involved actors are not oriented in the same direction. + + \note Calling this function resets the internal positional error correction term. + + \param[in] ratio Desired ratio between the hinge and the prismatic. + */ + virtual void setRatio(float ratio) = 0; + + /** + \brief Get the ratio. + + \return Current ratio + */ + virtual float getRatio() const = 0; + + /** + \brief Set the desired ratio indirectly. + + This is a simple helper function that computes the ratio from passed data: + + ratio = (PI*2*nbRackTeeth)/(rackLength*nbPinionTeeth) + + \note Calling this function resets the internal positional error correction term. + + \param[in] nbRackTeeth Number of teeth on the rack (cannot be zero) + \param[in] nbPinionTeeth Number of teeth on the pinion (cannot be zero) + \param[in] rackLength Length of the rack + \return true if success + */ + virtual bool setData(PxU32 nbRackTeeth, PxU32 nbPinionTeeth, float rackLength) = 0; + + virtual const char* getConcreteTypeName() const { return "PxRackAndPinionJoint"; } + + protected: + + PX_INLINE PxRackAndPinionJoint(PxType concreteType, PxBaseFlags baseFlags) : PxJoint(concreteType, baseFlags) {} + + PX_INLINE PxRackAndPinionJoint(PxBaseFlags baseFlags) : PxJoint(baseFlags) {} + + virtual bool isKindOf(const char* name) const { return !::strcmp("PxRackAndPinionJoint", name) || PxJoint::isKindOf(name); } + }; + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/extensions/PxRaycastCCD.h b/Source/ThirdParty/PhysX/extensions/PxRaycastCCD.h index 927178190..4e92e190e 100644 --- a/Source/ThirdParty/PhysX/extensions/PxRaycastCCD.h +++ b/Source/ThirdParty/PhysX/extensions/PxRaycastCCD.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,7 +22,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. @@ -81,6 +80,16 @@ namespace physx */ bool registerRaycastCCDObject(PxRigidDynamic* actor, PxShape* shape); + /** + \brief Unregister dynamic object for raycast CCD. + + \param[in] actor object's actor + \param[in] shape object's shape + + \return True if success + */ + bool unregisterRaycastCCDObject(PxRigidDynamic* actor, PxShape* shape); + /** \brief Perform raycast CCD. Call this after your simulate/fetchResults calls. diff --git a/Source/ThirdParty/PhysX/extensions/PxRemeshingExt.h b/Source/ThirdParty/PhysX/extensions/PxRemeshingExt.h new file mode 100644 index 000000000..556a859c7 --- /dev/null +++ b/Source/ThirdParty/PhysX/extensions/PxRemeshingExt.h @@ -0,0 +1,73 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_REMESHING_EXT_H +#define PX_REMESHING_EXT_H +/** \addtogroup extensions + @{ +*/ + +#include "foundation/PxVec3.h" +#include "foundation/PxArray.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + /** + \brief Provides methods to adjust the tessellation of meshes + */ + class PxRemeshingExt + { + public: + /** + \brief Processes a triangle mesh and makes sure that no triangle edge is longer than the maximal edge length specified + + To shorten edges that are too long, additional points get inserted at their center leading to a subdivision of the input mesh. + This process is executed repeatedly until the maximum edge length criterion is satisfied + + \param[in,out] triangles The triangles of the mesh where a maximum edge length should be enforced. They will be modified in place during the process. + \param[in,out] points The vertices of the mesh where a maximum edge length should be enforced. They will be modified in place during the process. + \param[in] maxEdgeLength The maximum edge length allowed after processing the input + \param[in] maxIterations The maximum number of subdivision iterations + \param[out] triangleMap An optional map that provides the index of the original triangle for every triangle after the subdivision + \param[in] triangleCountThreshold Optional limit to the number of triangles. Not guaranteed to match exactly, the algorithm will just stop as soon as possible after reaching the limit. + + \return True if any remeshing was applied + */ + static bool limitMaxEdgeLength(PxArray& triangles, PxArray& points, PxReal maxEdgeLength, + PxU32 maxIterations = 100, PxArray* triangleMap = NULL, PxU32 triangleCountThreshold = 0xFFFFFFFF); + }; + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/extensions/PxRepXSerializer.h b/Source/ThirdParty/PhysX/extensions/PxRepXSerializer.h index f75320b62..92f8211d0 100644 --- a/Source/ThirdParty/PhysX/extensions/PxRepXSerializer.h +++ b/Source/ThirdParty/PhysX/extensions/PxRepXSerializer.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,9 +22,10 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + #ifndef PX_REPX_SERIALIZER_H #define PX_REPX_SERIALIZER_H /** \addtogroup Serializers @@ -128,21 +128,22 @@ PX_INLINE physx::PxRepXObject PxCreateRepXObject(const physx::PxBase* inType, co template PX_INLINE physx::PxRepXObject PxCreateRepXObject(const TDataType* inType) { - return PxCreateRepXObject(inType, static_cast(reinterpret_cast(inType))); + return PxCreateRepXObject(inType, static_cast(size_t(inType))); } /** \brief Preprocessor macro for RepX serializer creation. */ #define PX_NEW_REPX_SERIALIZER(T) \ - *PX_PLACEMENT_NEW(PxGetFoundation().getAllocatorCallback().allocate(sizeof(T), "PxRepXSerializer", __FILE__, __LINE__ ), T)(PxGetFoundation().getAllocatorCallback()) + *PX_PLACEMENT_NEW(PxGetAllocatorCallback()->allocate(sizeof(T), "PxRepXSerializer", __FILE__, __LINE__ ), T)(*PxGetAllocatorCallback()) /** \brief Preprocessor Macro to simplify RepX serializer delete. */ #define PX_DELETE_REPX_SERIALIZER(x) \ - { PxRepXSerializer* s = x; if (s) { PxGetFoundation().getAllocatorCallback().deallocate(s); } } + { PxRepXSerializer* s = x; if (s) { PxGetAllocatorCallback()->deallocate(s); } } /** @} */ -#endif // PX_REPX_SERIALIZER_H +#endif + diff --git a/Source/ThirdParty/PhysX/extensions/PxRepXSimpleType.h b/Source/ThirdParty/PhysX/extensions/PxRepXSimpleType.h index a49ad2339..0eee59929 100644 --- a/Source/ThirdParty/PhysX/extensions/PxRepXSimpleType.h +++ b/Source/ThirdParty/PhysX/extensions/PxRepXSimpleType.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,10 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - - #ifndef PX_REPX_SIMPLE_TYPE_H #define PX_REPX_SIMPLE_TYPE_H diff --git a/Source/ThirdParty/PhysX/extensions/PxRevoluteJoint.h b/Source/ThirdParty/PhysX/extensions/PxRevoluteJoint.h index 8d82c8cb0..55bed4fc5 100644 --- a/Source/ThirdParty/PhysX/extensions/PxRevoluteJoint.h +++ b/Source/ThirdParty/PhysX/extensions/PxRevoluteJoint.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PX_REVOLUTEJOINT_H -#define PX_REVOLUTEJOINT_H +#ifndef PX_REVOLUTE_JOINT_H +#define PX_REVOLUTE_JOINT_H /** \addtogroup extensions @{ */ @@ -139,14 +138,14 @@ public: If the joint is spinning faster than this velocity, the motor will actually try to brake (see PxRevoluteJointFlag::eDRIVE_FREESPIN.) - If you set this to infinity then the motor will keep speeding up, unless there is some sort - of resistance on the attached bodies. The sign of this variable determines the rotation direction, - with positive values going the same way as positive joint angles. + The sign of this variable determines the rotation direction, with positive values going + the same way as positive joint angles. Setting a very large target velocity may cause + undesirable results. \param[in] velocity the drive target velocity - \param[in] autowake Whether to wake the joint rigids up if it is asleep. + \param[in] autowake Whether to wake up the joint rigids if they are asleep. - Range: [0, PX_MAX_F32)
+ Range: (-PX_MAX_F32, PX_MAX_F32)
Default: 0.0 @see PxRevoluteFlags::eDRIVE_FREESPIN @@ -165,8 +164,6 @@ public: /** \brief sets the maximum torque the drive can exert. - Setting this to a very large value if velTarget is also very large may cause unexpected results. - The value set here may be used either as an impulse limit or a force limit, depending on the flag PxConstraintFlag::eDRIVE_LIMITS_ARE_FORCES Range: [0, PX_MAX_F32)
@@ -256,8 +253,10 @@ public: \param[in] tolerance the linear tolerance threshold @see getProjectionLinearTolerance() PxJoint::setConstraintFlags() PxConstraintFlag::ePROJECTION + + @deprecated */ - virtual void setProjectionLinearTolerance(PxReal tolerance) = 0; + PX_DEPRECATED virtual void setProjectionLinearTolerance(PxReal tolerance) = 0; /** \brief Get the linear tolerance threshold for projection. @@ -265,8 +264,10 @@ public: \return the linear tolerance threshold @see setProjectionLinearTolerance() + + @deprecated */ - virtual PxReal getProjectionLinearTolerance() const = 0; + PX_DEPRECATED virtual PxReal getProjectionLinearTolerance() const = 0; /** \brief Set the angular tolerance threshold for projection. Projection is enabled if @@ -285,8 +286,10 @@ public: \param[in] tolerance the angular tolerance threshold in radians @see getProjectionAngularTolerance() PxJoint::setConstraintFlag() PxConstraintFlag::ePROJECTION + + @deprecated */ - virtual void setProjectionAngularTolerance(PxReal tolerance) = 0; + PX_DEPRECATED virtual void setProjectionAngularTolerance(PxReal tolerance) = 0; /** \brief gets the angular tolerance threshold for projection. @@ -294,8 +297,10 @@ public: \return the angular tolerance threshold in radians @see setProjectionAngularTolerance() + + @deprecated */ - virtual PxReal getProjectionAngularTolerance() const = 0; + PX_DEPRECATED virtual PxReal getProjectionAngularTolerance() const = 0; /** \brief Returns string name of PxRevoluteJoint, used for serialization diff --git a/Source/ThirdParty/PhysX/extensions/PxRigidActorExt.h b/Source/ThirdParty/PhysX/extensions/PxRigidActorExt.h index c7a3b7bf2..cb331cd4b 100644 --- a/Source/ThirdParty/PhysX/extensions/PxRigidActorExt.h +++ b/Source/ThirdParty/PhysX/extensions/PxRigidActorExt.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_EXTENSIONS_RIGIDACTOR_H -#define PX_PHYSICS_EXTENSIONS_RIGIDACTOR_H +#ifndef PX_RIGID_ACTOR_EXT_H +#define PX_RIGID_ACTOR_EXT_H /** \addtogroup extensions @{ */ @@ -43,6 +41,9 @@ namespace physx { #endif +class PxBVH; +class PxCooking; + /** \brief utility functions for use with PxRigidActor and subclasses @@ -82,7 +83,6 @@ public: @see PxShape PxShape::release(), PxPhysics::createShape(), PxRigidActor::attachShape() */ - static PxShape* createExclusiveShape(PxRigidActor& actor, const PxGeometry& geometry, PxMaterial*const* materials, PxU16 materialCount, PxShapeFlags shapeFlags = PxShapeFlag::eVISUALIZATION | PxShapeFlag::eSCENE_QUERY_SHAPE | PxShapeFlag::eSIMULATION_SHAPE) { @@ -125,7 +125,6 @@ public: @see PxShape PxShape::release(), PxPhysics::createShape(), PxRigidActor::attachShape() */ - static PX_FORCE_INLINE PxShape* createExclusiveShape(PxRigidActor& actor, const PxGeometry& geometry, const PxMaterial& material, PxShapeFlags shapeFlags = PxShapeFlag::eVISUALIZATION | PxShapeFlag::eSCENE_QUERY_SHAPE | PxShapeFlag::eSIMULATION_SHAPE) { @@ -133,7 +132,6 @@ public: return createExclusiveShape(actor, geometry, &materialPtr, 1, shapeFlags); } - /** \brief Gets a list of bounds based on shapes in rigid actor. This list can be used to cook/create bounding volume hierarchy though PxCooking API. @@ -141,10 +139,24 @@ public: \param[in] actor The actor from which the bounds list is retrieved. \param[out] numBounds Number of bounds in returned list. - @see PxShape PxBVHStructure PxCooking::createBVHStructure PxCooking::cookBVHStructure + @see PxShape PxBVH PxCooking::createBVH PxCooking::cookBVH */ - static PxBounds3* getRigidActorShapeLocalBoundsList(const PxRigidActor& actor, PxU32& numBounds); + static PxBounds3* getRigidActorShapeLocalBoundsList(const PxRigidActor& actor, PxU32& numBounds); + /** + \brief Convenience function to create a PxBVH object from a PxRigidActor. + + The computed PxBVH can then be used in PxScene::addActor() or PxAggregate::addActor(). + After adding the actor & BVH to the scene/aggregate, release the PxBVH object by calling PxBVH::release(). + + \param[in] physics The physics object. The function will retrieve the insertion callback from it. + \param[in] actor The actor to compute a PxBVH for. + + \return The PxBVH for this actor. + + @see PxBVH PxScene::addActor PxAggregate::addActor + */ + static PxBVH* createBVHFromActor(PxPhysics& physics, const PxRigidActor& actor); }; #if !PX_DOXYGEN diff --git a/Source/ThirdParty/PhysX/extensions/PxRigidBodyExt.h b/Source/ThirdParty/PhysX/extensions/PxRigidBodyExt.h index 71228b3ab..298801600 100644 --- a/Source/ThirdParty/PhysX/extensions/PxRigidBodyExt.h +++ b/Source/ThirdParty/PhysX/extensions/PxRigidBodyExt.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_EXTENSIONS_RIGIDBODY_H -#define PX_PHYSICS_EXTENSIONS_RIGIDBODY_H +#ifndef PX_RIGID_BODY_EXT_H +#define PX_RIGID_BODY_EXT_H /** \addtogroup extensions @{ */ @@ -93,7 +91,6 @@ public: */ static bool updateMassAndInertia(PxRigidBody& body, const PxReal* shapeDensities, PxU32 shapeDensityCount, const PxVec3* massLocalPose = NULL, bool includeNonSimShapes = false); - /** \brief Computation of mass properties for a rigid body actor @@ -109,7 +106,6 @@ public: */ static bool updateMassAndInertia(PxRigidBody& body, PxReal density, const PxVec3* massLocalPose = NULL, bool includeNonSimShapes = false); - /** \brief Computation of mass properties for a rigid body actor @@ -133,7 +129,6 @@ public: */ static bool setMassAndUpdateInertia(PxRigidBody& body, const PxReal* shapeMasses, PxU32 shapeMassCount, const PxVec3* massLocalPose = NULL, bool includeNonSimShapes = false); - /** \brief Computation of mass properties for a rigid body actor @@ -154,7 +149,6 @@ public: */ static bool setMassAndUpdateInertia(PxRigidBody& body, PxReal mass, const PxVec3* massLocalPose = NULL, bool includeNonSimShapes = false); - /** \brief Compute the mass, inertia tensor and center of mass from a list of shapes. @@ -166,7 +160,6 @@ public: */ static PxMassProperties computeMassPropertiesFromShapes(const PxShape* const* shapes, PxU32 shapeCount); - /** \brief Applies a force (or impulse) defined in the global coordinate frame, acting at a particular point in global coordinates, to the actor. @@ -315,6 +308,58 @@ public: */ static PxVec3 getVelocityAtOffset(const PxRigidBody& body, const PxVec3& pos); + /** + \brief Compute the change to linear and angular velocity that would occur if an impulsive force and torque were to be applied to a specified rigid body. + + The rigid body is left unaffected unless a subsequent independent call is executed that actually applies the computed changes to velocity and angular velocity. + + \note if this call is used to determine the velocity delta for an articulation link, only the mass properties of the link are taken into account. + + @see PxRigidBody::getLinearVelocity, PxRigidBody::setLinearVelocity, PxRigidBody::getAngularVelocity, PxRigidBody::setAngularVelocity + + \param[in] body The body under consideration. + \param[in] impulsiveForce The impulsive force that would be applied to the specified rigid body. + \param[in] impulsiveTorque The impulsive torque that would be applied to the specified rigid body. + \param[out] deltaLinearVelocity The change in linear velocity that would arise if impulsiveForce was to be applied to the specified rigid body. + \param[out] deltaAngularVelocity The change in angular velocity that would arise if impulsiveTorque was to be applied to the specified rigid body. + */ + static void computeVelocityDeltaFromImpulse(const PxRigidBody& body, const PxVec3& impulsiveForce, const PxVec3& impulsiveTorque, PxVec3& deltaLinearVelocity, PxVec3& deltaAngularVelocity); + + /** + \brief Computes the linear and angular velocity change vectors for a given impulse at a world space position taking a mass and inertia scale into account + + This function is useful for extracting the respective linear and angular velocity changes from a contact or joint when the mass/inertia ratios have been adjusted. + + \note if this call is used to determine the velocity delta for an articulation link, only the mass properties of the link are taken into account. + + \param[in] body The rigid body + \param[in] globalPose The body's world space transform + \param[in] point The point in world space where the impulse is applied + \param[in] impulse The impulse vector in world space + \param[in] invMassScale The inverse mass scale + \param[in] invInertiaScale The inverse inertia scale + \param[out] deltaLinearVelocity The linear velocity change + \param[out] deltaAngularVelocity The angular velocity change + */ + static void computeVelocityDeltaFromImpulse(const PxRigidBody& body, const PxTransform& globalPose, const PxVec3& point, const PxVec3& impulse, const PxReal invMassScale, + const PxReal invInertiaScale, PxVec3& deltaLinearVelocity, PxVec3& deltaAngularVelocity); + + /** + \brief Computes the linear and angular impulse vectors for a given impulse at a world space position taking a mass and inertia scale into account + + This function is useful for extracting the respective linear and angular impulses from a contact or joint when the mass/inertia ratios have been adjusted. + + \param[in] body The rigid body + \param[in] globalPose The body's world space transform + \param[in] point The point in world space where the impulse is applied + \param[in] impulse The impulse vector in world space + \param[in] invMassScale The inverse mass scale + \param[in] invInertiaScale The inverse inertia scale + \param[out] linearImpulse The linear impulse + \param[out] angularImpulse The angular impulse + */ + static void computeLinearAngularImpulse(const PxRigidBody& body, const PxTransform& globalPose, const PxVec3& point, const PxVec3& impulse, const PxReal invMassScale, + const PxReal invInertiaScale, PxVec3& linearImpulse, PxVec3& angularImpulse); /** \brief Performs a linear sweep through space with the body's geometry objects. @@ -342,7 +387,7 @@ public: \return True if a blocking hit was found. - @see PxScene PxQueryFlags PxFilterData PxBatchQueryPreFilterShader PxBatchQueryPostFilterShader PxSweepHit + @see PxScene PxQueryFlags PxFilterData PxSweepHit */ static bool linearSweepSingle( PxRigidBody& body, PxScene& scene, const PxVec3& unitDir, const PxReal distance, @@ -383,7 +428,7 @@ public: \return the number of touching hits. If overflow is set to true, the results are incomplete. In case of overflow there are also no guarantees that all touching hits returned are closer than the blocking hit. - @see PxScene PxQueryFlags PxFilterData PxBatchQueryPreFilterShader PxBatchQueryPostFilterShader PxSweepHit + @see PxScene PxQueryFlags PxFilterData PxSweepHit */ static PxU32 linearSweepMultiple( PxRigidBody& body, PxScene& scene, const PxVec3& unitDir, const PxReal distance, @@ -393,63 +438,6 @@ public: const PxQueryFilterData& filterData = PxQueryFilterData(), PxQueryFilterCallback* filterCall = NULL, const PxQueryCache* cache = NULL, const PxReal inflation = 0.0f); - - - /** - \brief Compute the change to linear and angular velocity that would occur if an impulsive force and torque were to be applied to a specified rigid body. - - The rigid body is left unaffected unless a subsequent independent call is executed that actually applies the computed changes to velocity and angular velocity. - - \note if this call is used to determine the velocity delta for an articulation link, only the mass properties of the link are taken into account. - - @see PxRigidBody::getLinearVelocity, PxRigidBody::setLinearVelocity, PxRigidBody::getAngularVelocity, PxRigidBody::setAngularVelocity - - \param[in] body The body under consideration. - \param[in] impulsiveForce The impulsive force that would be applied to the specified rigid body. - \param[in] impulsiveTorque The impulsive torque that would be applied to the specified rigid body. - \param[out] deltaLinearVelocity The change in linear velocity that would arise if impulsiveForce was to be applied to the specified rigid body. - \param[out] deltaAngularVelocity The change in angular velocity that would arise if impulsiveTorque was to be applied to the specified rigid body. - */ - static void computeVelocityDeltaFromImpulse(const PxRigidBody& body, const PxVec3& impulsiveForce, const PxVec3& impulsiveTorque, PxVec3& deltaLinearVelocity, PxVec3& deltaAngularVelocity); - - /** - \brief Computes the linear and angular velocity change vectors for a given impulse at a world space position taking a mass and inertia scale into account - - This function is useful for extracting the respective linear and angular velocity changes from a contact or joint when the mass/inertia ratios have been adjusted. - - \note if this call is used to determine the velocity delta for an articulation link, only the mass properties of the link are taken into account. - - \param[in] body The rigid body - \param[in] globalPose The body's world space transform - \param[in] point The point in world space where the impulse is applied - \param[in] impulse The impulse vector in world space - \param[in] invMassScale The inverse mass scale - \param[in] invInertiaScale The inverse inertia scale - \param[out] deltaLinearVelocity The linear velocity change - \param[out] deltaAngularVelocity The angular velocity change - */ - - static void computeVelocityDeltaFromImpulse(const PxRigidBody& body, const PxTransform& globalPose, const PxVec3& point, const PxVec3& impulse, const PxReal invMassScale, - const PxReal invInertiaScale, PxVec3& deltaLinearVelocity, PxVec3& deltaAngularVelocity); - - /** - \brief Computes the linear and angular impulse vectors for a given impulse at a world space position taking a mass and inertia scale into account - - This function is useful for extracting the respective linear and angular impulses from a contact or joint when the mass/inertia ratios have been adjusted. - - \param[in] body The rigid body - \param[in] globalPose The body's world space transform - \param[in] point The point in world space where the impulse is applied - \param[in] impulse The impulse vector in world space - \param[in] invMassScale The inverse mass scale - \param[in] invInertiaScale The inverse inertia scale - \param[out] linearImpulse The linear impulse - \param[out] angularImpulse The angular impulse - */ - static void computeLinearAngularImpulse(const PxRigidBody& body, const PxTransform& globalPose, const PxVec3& point, const PxVec3& impulse, const PxReal invMassScale, - const PxReal invInertiaScale, PxVec3& linearImpulse, PxVec3& angularImpulse); - - }; #if !PX_DOXYGEN diff --git a/Source/ThirdParty/PhysX/extensions/PxSamplingExt.h b/Source/ThirdParty/PhysX/extensions/PxSamplingExt.h new file mode 100644 index 000000000..088c4f20f --- /dev/null +++ b/Source/ThirdParty/PhysX/extensions/PxSamplingExt.h @@ -0,0 +1,185 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_SAMPLING_EXT_H +#define PX_SAMPLING_EXT_H +/** \addtogroup extensions + @{ +*/ + +#include "foundation/PxArray.h" +#include "geometry/PxGeometry.h" +#include "foundation/PxUserAllocated.h" +#include "geometry/PxSimpleTriangleMesh.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +/** +\brief utility functions to sample vertices on or inside a triangle mesh or other geometries +*/ +class PxSamplingExt +{ +public: + /** Computes samples on a triangle mesh's surface that are not closer to each other than a given distance. Optionally the mesh's interior can be filled with samples as well. + + \param[in] mesh The triangle mesh + \param[in] r The closest distance two surface samples are allowed to have + \param[out] result Equally distributed samples on and if specified inside the triangle mesh + \param[in] rVolume The average distance of samples inside the mesh. If set to zero, samples will only be placed on the mesh's surface + \param[out] triangleIds Optional output containing the index of the triangle for all samples on the mesh's surface. The array will contain less entries than output vertices if volume samples are active since volume samples are not on the surface. + \param[out] barycentricCoordinates Optional output containing the barycentric coordinates for all samples on the mesh's surface. The array will contain less entries than output vertices if volume samples are active since volume samples are not on the surface. + \param[in] axisAlignedBox A box that limits the space where samples can get created + \param[in] boxOrientation The orientation of the box that limits the space where samples can get created + \param[in] maxNumSamples If larger than zero, the sampler will stop when the sample count reaches maxNumSamples + \param[in] numSampleAttemptsAroundPoint Number of repetitions the underlying algorithm performs to find a new valid sample that matches all criteria like minimal distance to existing samples etc. + \return Returns true if the sampling was successful and false if there was a problem. Usually an internal overflow is the problem for very big meshes or very small sampling radii. + */ + static bool poissonSample(const PxSimpleTriangleMesh& mesh, PxReal r, PxArray& result, PxReal rVolume = 0.0f, PxArray* triangleIds = NULL, PxArray* barycentricCoordinates = NULL, + const PxBounds3* axisAlignedBox = NULL, const PxQuat* boxOrientation = NULL, PxU32 maxNumSamples = 0, PxU32 numSampleAttemptsAroundPoint = 30); + + /** Computes samples on a geometry's surface that are not closer to each other than a given distance. + + \param[in] geometry The geometry that defines the surface on which the samples get created + \param[in] transform The geometry's global pose + \param[in] worldBounds The geometry's bounding box + \param[in] r The closest distance two surface samples are allowed to have + \param[out] result Equally distributed samples on and if specified inside the triangle mesh + \param[in] rVolume The average distance of samples inside the mesh. If set to zero, samples will only be placed on the mesh's surface + \param[in] axisAlignedBox A box that limits the space where samples can get created + \param[in] boxOrientation The orientation of the box that limits the space where samples can get created + \param[in] maxNumSamples If larger than zero, the sampler will stop when the sample count reaches maxNumSamples + \param[in] numSampleAttemptsAroundPoint Number of repetitions the underlying algorithm performs to find a new valid sample that matches all criteria like minimal distance to existing samples etc. + \return Returns true if the sampling was successful and false if there was a problem. Usually an internal overflow is the problem for very big meshes or very small sampling radii. + */ + static bool poissonSample(const PxGeometry& geometry, const PxTransform& transform, const PxBounds3& worldBounds, PxReal r, PxArray& result, PxReal rVolume = 0.0f, + const PxBounds3* axisAlignedBox = NULL, const PxQuat* boxOrientation = NULL, PxU32 maxNumSamples = 0, PxU32 numSampleAttemptsAroundPoint = 30); +}; + +/** +\brief Sampler to generate Poisson Samples locally on a triangle mesh or a shape. For every local addition of new samples, an individual sampling density can be used. +*/ +class PxPoissonSampler : public PxUserAllocated +{ +public: + /** Sets the sampling radius + \param[in] samplingRadius The closest distance two surface samples are allowed to have. Changing the sampling radius is a bit an expensive operation. + \return Returns true if the sampling was successful and false if there was a problem. Usually an internal overflow is the problem for very big meshes or very small sampling radii. + */ + virtual bool setSamplingRadius(PxReal samplingRadius) = 0; + + /** Adds samples + \param[in] samples The samples to add. Adding samples is a bit an expensive operation. + */ + virtual void addSamples(const PxArray& samples) = 0; + + /** Adds samples + \param[in] samples The samples to remove. Removing samples is a bit an expensive operation. + \return Returns the number of removed samples. If some samples were not found, then the number of actually removed samples will be smaller than the number of samples requested to remove + */ + virtual PxU32 removeSamples(const PxArray& samples) = 0; + + /** Adds new Poisson Samples inside the sphere specified + \param[in] sphereCenter The sphere's center. Used to define the region where new samples get added. + \param[in] sphereRadius The sphere's radius. Used to define the region where new samples get added. + \param[in] createVolumeSamples If set to true, samples will also get generated inside of the mesh, not just on its surface. + */ + virtual void addSamplesInSphere(const PxVec3& sphereCenter, PxReal sphereRadius, bool createVolumeSamples = false) = 0; + + /** Adds new Poisson Samples inside the box specified + \param[in] axisAlignedBox The axis aligned bounding box. Used to define the region where new samples get added. + \param[in] boxOrientation The orientation making an oriented bounding box out of the axis aligned one. Used to define the region where new samples get added. + \param[in] createVolumeSamples If set to true, samples will also get generated inside of the mesh, not just on its surface. + */ + virtual void addSamplesInBox(const PxBounds3& axisAlignedBox, const PxQuat& boxOrientation, bool createVolumeSamples = false) = 0; + + /** Gets the Poisson Samples + \return Returns the generated Poisson Samples + */ + virtual const PxArray& getSamples() const = 0; + + virtual ~PxPoissonSampler() { } +}; + + +/** Creates a shape sampler +\param[in] geometry The shape that defines the surface on which the samples get created +\param[in] transform The shape's global pose +\param[in] worldBounds The shapes bounding box +\param[in] initialSamplingRadius The closest distance two surface samples are allowed to have +\param[in] numSampleAttemptsAroundPoint Number of repetitions the underlying algorithm performs to find a new valid sample that matches all criteria like minimal distance to existing samples etc. +\return Returns the sampler +*/ +PxPoissonSampler* PxCreateShapeSampler(const PxGeometry& geometry, const PxTransform& transform, const PxBounds3& worldBounds, PxReal initialSamplingRadius, PxI32 numSampleAttemptsAroundPoint = 30); + + +/** +\brief Sampler to generate Poisson Samples on a triangle mesh. +*/ +class PxTriangleMeshPoissonSampler : public virtual PxPoissonSampler +{ +public: + /** Gets the Poisson Samples' triangle indices + \return Returns the generated Poisson Samples' triangle indices + */ + virtual const PxArray& getSampleTriangleIds() const = 0; + + /** Gets the Poisson Samples' barycentric coordinates + \return Returns the generated Poisson Samples' barycentric coordinates + */ + virtual const PxArray& getSampleBarycentrics() const = 0; + + /** Checks whether a point is inside the triangle mesh + \return Returns true if the point is inside the triangle mesh + */ + virtual bool isPointInTriangleMesh(const PxVec3& p) = 0; + + virtual ~PxTriangleMeshPoissonSampler() { } +}; + + +/** Creates a triangle mesh sampler +\param[in] triangles The triangle indices of the mesh +\param[in] numTriangles The total number of triangles +\param[in] vertices The vertices of the mesh +\param[in] numVertices The total number of vertices +\param[in] initialSamplingRadius The closest distance two surface samples are allowed to have +\param[in] numSampleAttemptsAroundPoint Number of repetitions the underlying algorithm performs to find a new valid sample that matches all criteria like minimal distance to existing samples etc. +\return Returns the sampler +*/ +PxTriangleMeshPoissonSampler* PxCreateTriangleMeshSampler(const PxU32* triangles, PxU32 numTriangles, const PxVec3* vertices, PxU32 numVertices, PxReal initialSamplingRadius, PxI32 numSampleAttemptsAroundPoint = 30); + + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/extensions/PxSceneQueryExt.h b/Source/ThirdParty/PhysX/extensions/PxSceneQueryExt.h index 6f08fe803..f089abf21 100644 --- a/Source/ThirdParty/PhysX/extensions/PxSceneQueryExt.h +++ b/Source/ThirdParty/PhysX/extensions/PxSceneQueryExt.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_EXTENSIONS_SCENE_QUERY_H -#define PX_PHYSICS_EXTENSIONS_SCENE_QUERY_H +#ifndef PX_SCENE_QUERY_EXT_H +#define PX_SCENE_QUERY_EXT_H /** \addtogroup extensions @{ */ @@ -301,6 +299,208 @@ public: PxSceneQueryFilterCallback* filterCall = NULL); }; +struct PxBatchQueryStatus +{ + enum Enum + { + /** + \brief This is the initial state before a query starts. + */ + ePENDING = 0, + + /** + \brief The query is finished; results have been written into the result and hit buffers. + */ + eSUCCESS, + + /** + \brief The query results were incomplete due to touch hit buffer overflow. Blocking hit is still correct. + */ + eOVERFLOW + }; + + static PX_FORCE_INLINE Enum getStatus(const PxRaycastBuffer& r) + { + return (0xffffffff == r.nbTouches) ? ePENDING : (0xffffffff == r.maxNbTouches ? eOVERFLOW : eSUCCESS); + } + static PX_FORCE_INLINE Enum getStatus(const PxSweepBuffer& r) + { + return (0xffffffff == r.nbTouches) ? ePENDING : (0xffffffff == r.maxNbTouches ? eOVERFLOW : eSUCCESS); + } + static PX_FORCE_INLINE Enum getStatus(const PxOverlapBuffer& r) + { + return (0xffffffff == r.nbTouches) ? ePENDING : (0xffffffff == r.maxNbTouches ? eOVERFLOW : eSUCCESS); + } +}; + +class PxBatchQueryExt +{ +public: + + virtual void release() = 0; + + /** + \brief Performs a raycast against objects in the scene. + + \note Touching hits are not ordered. + \note Shooting a ray from within an object leads to different results depending on the shape type. Please check the details in article SceneQuery. User can ignore such objects by using one of the provided filter mechanisms. + + \param[in] origin Origin of the ray. + \param[in] unitDir Normalized direction of the ray. + \param[in] distance Length of the ray. Needs to be larger than 0. + \param[in] maxNbTouches Maximum number of hits to record in the touch buffer for this query. Default=0 reports a single blocking hit. If maxTouchHits is set to 0 all hits are treated as blocking by default. + \param[in] hitFlags Specifies which properties per hit should be computed and returned in hit array and blocking hit. + \param[in] filterData Filtering data passed to the filter shader. See #PxQueryFilterData #PxQueryFilterCallback + \param[in] cache Cached hit shape (optional). Query is tested against cached shape first. If no hit is found the ray gets queried against the scene. + Note: Filtering is not executed for a cached shape if supplied; instead, if a hit is found, it is assumed to be a blocking hit. + Note: Using past touching hits as cache will produce incorrect behavior since the cached hit will always be treated as blocking. + + \note This query call writes to a list associated with the query object and is NOT thread safe (for performance reasons there is no lock + and overlapping writes from different threads may result in undefined behavior). + + \return Returns a PxRaycastBuffer pointer that will store the result of the query after execute() is completed. + This will point either to an element of the buffer allocated on construction or to a user buffer passed to the constructor. + @see PxCreateBatchQueryExt + + @see PxQueryFilterData PxQueryFilterCallback PxRaycastHit PxScene::raycast + */ + virtual PxRaycastBuffer* raycast( + const PxVec3& origin, const PxVec3& unitDir, const PxReal distance, + const PxU16 maxNbTouches = 0, + PxHitFlags hitFlags = PxHitFlags(PxHitFlag::eDEFAULT), + const PxQueryFilterData& filterData = PxQueryFilterData(), + const PxQueryCache* cache = NULL) = 0; + + /** + \brief Performs a sweep test against objects in the scene. + + \note Touching hits are not ordered. + \note If a shape from the scene is already overlapping with the query shape in its starting position, + the hit is returned unless eASSUME_NO_INITIAL_OVERLAP was specified. + + \param[in] geometry Geometry of object to sweep (supported types are: box, sphere, capsule, convex). + \param[in] pose Pose of the sweep object. + \param[in] unitDir Normalized direction of the sweep. + \param[in] distance Sweep distance. Needs to be larger than 0. Will be clamped to PX_MAX_SWEEP_DISTANCE. + \param[in] maxNbTouches Maximum number of hits to record in the touch buffer for this query. Default=0 reports a single blocking hit. If maxTouchHits is set to 0 all hits are treated as blocking by default. + \param[in] hitFlags Specifies which properties per hit should be computed and returned in hit array and blocking hit. + \param[in] filterData Filtering data and simple logic. See #PxQueryFilterData #PxQueryFilterCallback + \param[in] cache Cached hit shape (optional). Query is tested against cached shape first. If no hit is found the ray gets queried against the scene. + Note: Filtering is not executed for a cached shape if supplied; instead, if a hit is found, it is assumed to be a blocking hit. + Note: Using past touching hits as cache will produce incorrect behavior since the cached hit will always be treated as blocking. + \param[in] inflation This parameter creates a skin around the swept geometry which increases its extents for sweeping. The sweep will register a hit as soon as the skin touches a shape, and will return the corresponding distance and normal. + Note: ePRECISE_SWEEP doesn't support inflation. Therefore the sweep will be performed with zero inflation. + + \note This query call writes to a list associated with the query object and is NOT thread safe (for performance reasons there is no lock + and overlapping writes from different threads may result in undefined behavior). + + \return Returns a PxSweepBuffer pointer that will store the result of the query after execute() is completed. + This will point either to an element of the buffer allocated on construction or to a user buffer passed to the constructor. + @see PxCreateBatchQueryExt + + @see PxHitFlags PxQueryFilterData PxBatchQueryPreFilterShader PxBatchQueryPostFilterShader PxSweepHit + */ + virtual PxSweepBuffer* sweep( + const PxGeometry& geometry, const PxTransform& pose, const PxVec3& unitDir, const PxReal distance, + const PxU16 maxNbTouches = 0, + PxHitFlags hitFlags = PxHitFlags(PxHitFlag::eDEFAULT), + const PxQueryFilterData& filterData = PxQueryFilterData(), + const PxQueryCache* cache = NULL, + const PxReal inflation = 0.0f) = 0; + + + /** + \brief Performs an overlap test of a given geometry against objects in the scene. + + \note Filtering: returning eBLOCK from user filter for overlap queries will cause a warning (see #PxQueryHitType). + + \param[in] geometry Geometry of object to check for overlap (supported types are: box, sphere, capsule, convex). + \param[in] pose Pose of the object. + \param[in] maxNbTouches Maximum number of hits to record in the touch buffer for this query. Default=0 reports a single blocking hit. If maxTouchHits is set to 0 all hits are treated as blocking by default. + \param[in] filterData Filtering data and simple logic. See #PxQueryFilterData #PxQueryFilterCallback + \param[in] cache Cached hit shape (optional). Query is tested against cached shape first. If no hit is found the ray gets queried against the scene. + Note: Filtering is not executed for a cached shape if supplied; instead, if a hit is found, it is assumed to be a blocking hit. + Note: Using past touching hits as cache will produce incorrect behavior since the cached hit will always be treated as blocking. + + \note eBLOCK should not be returned from user filters for overlap(). Doing so will result in undefined behavior, and a warning will be issued. + \note If the PxQueryFlag::eNO_BLOCK flag is set, the eBLOCK will instead be automatically converted to an eTOUCH and the warning suppressed. + \note This query call writes to a list associated with the query object and is NOT thread safe (for performance reasons there is no lock + and overlapping writes from different threads may result in undefined behavior). + + \return Returns a PxOverlapBuffer pointer that will store the result of the query after execute() is completed. + This will point either to an element of the buffer allocated on construction or to a user buffer passed to the constructor. + @see PxCreateBatchQueryExt + + @see PxQueryFilterData PxQueryFilterCallback + */ + virtual PxOverlapBuffer* overlap( + const PxGeometry& geometry, const PxTransform& pose, + PxU16 maxNbTouches = 0, + const PxQueryFilterData& filterData = PxQueryFilterData(), + const PxQueryCache* cache = NULL) = 0; + + virtual void execute() = 0; + +protected: + + virtual ~PxBatchQueryExt() {} +}; + +/** +\brief Create a PxBatchQueryExt without the need for pre-allocated result or touch buffers. + +\param[in] scene Queries will be performed against objects in the specified PxScene +\param[in] queryFilterCallback Filtering for all queries is performed using queryFilterCallback. A null pointer results in all shapes being considered. + +\param[in] maxNbRaycasts A result buffer will be allocated that is large enough to accommodate maxNbRaycasts calls to PxBatchQueryExt::raycast() +\param[in] maxNbRaycastTouches A touch buffer will be allocated that is large enough to accommodate maxNbRaycastTouches touches for all raycasts in the batch. + +\param[in] maxNbSweeps A result buffer will be allocated that is large enough to accommodate maxNbSweeps calls to PxBatchQueryExt::sweep() +\param[in] maxNbSweepTouches A touch buffer will be allocated that is large enough to accommodate maxNbSweepTouches touches for all sweeps in the batch. + +\param[in] maxNbOverlaps A result buffer will be allocated that is large enough to accommodate maxNbOverlaps calls to PxBatchQueryExt::overlap() +\param[in] maxNbOverlapTouches A touch buffer will be allocated that is large enough to accommodate maxNbOverlapTouches touches for all overlaps in the batch. + +\return Returns a PxBatchQueryExt instance. A NULL pointer will be returned if the subsequent allocations fail or if any of the arguments are illegal. +In the event that a NULL pointer is returned a corresponding error will be issued to the error stream. +*/ +PxBatchQueryExt* PxCreateBatchQueryExt( + const PxScene& scene, PxQueryFilterCallback* queryFilterCallback, + const PxU32 maxNbRaycasts, const PxU32 maxNbRaycastTouches, + const PxU32 maxNbSweeps, const PxU32 maxNbSweepTouches, + const PxU32 maxNbOverlaps, const PxU32 maxNbOverlapTouches); + + +/** +\brief Create a PxBatchQueryExt with user-supplied result and touch buffers. + +\param[in] scene Queries will be performed against objects in the specified PxScene +\param[in] queryFilterCallback Filtering for all queries is performed using queryFilterCallback. A null pointer results in all shapes being considered. + +\param[in] raycastBuffers This is the array that will be used to store the results of each raycast in a batch. +\param[in] maxNbRaycasts This is the length of the raycastBuffers array. +\param[in] raycastTouches This is the array that will be used to store the touches generated by all raycasts in a batch. +\param[in] maxNbRaycastTouches This is the length of the raycastTouches array. + +\param[in] sweepBuffers This is the array that will be used to store the results of each sweep in a batch. +\param[in] maxNbSweeps This is the length of the sweepBuffers array. +\param[in] sweepTouches This is the array that will be used to store the touches generated by all sweeps in a batch. +\param[in] maxNbSweepTouches This is the length of the sweepTouches array. + +\param[in] overlapBuffers This is the array that will be used to store the results of each overlap in a batch. +\param[in] maxNbOverlaps This is the length of the overlapBuffers array. +\param[in] overlapTouches This is the array that will be used to store the touches generated by all overlaps in a batch. +\param[in] maxNbOverlapTouches This is the length of the overlapTouches array. + +\return Returns a PxBatchQueryExt instance. A NULL pointer will be returned if the subsequent allocations fail or if any of the arguments are illegal. +In the event that a NULL pointer is returned a corresponding error will be issued to the error stream. +*/ +PxBatchQueryExt* PxCreateBatchQueryExt( + const PxScene& scene, PxQueryFilterCallback* queryFilterCallback, + PxRaycastBuffer* raycastBuffers, const PxU32 maxNbRaycasts, PxRaycastHit* raycastTouches, const PxU32 maxNbRaycastTouches, + PxSweepBuffer* sweepBuffers, const PxU32 maxNbSweeps, PxSweepHit* sweepTouches, const PxU32 maxNbSweepTouches, + PxOverlapBuffer* overlapBuffers, const PxU32 maxNbOverlaps, PxOverlapHit* overlapTouches, const PxU32 maxNbOverlapTouches); + #if !PX_DOXYGEN } // namespace physx #endif diff --git a/Source/ThirdParty/PhysX/extensions/PxSceneQuerySystemExt.h b/Source/ThirdParty/PhysX/extensions/PxSceneQuerySystemExt.h new file mode 100644 index 000000000..909fd726f --- /dev/null +++ b/Source/ThirdParty/PhysX/extensions/PxSceneQuerySystemExt.h @@ -0,0 +1,67 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_SCENE_QUERY_SYSTEM_EXT_H +#define PX_SCENE_QUERY_SYSTEM_EXT_H +/** \addtogroup extensions + @{ +*/ + +#include "PxSceneQuerySystem.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + /** + \brief Creates an external scene query system. + + An external SQ system is the part of a PxScene that deals with scene queries (SQ). This is usually taken care of + by an internal implementation inside PxScene, but it is also possible to re-route all SQ calls to an external + implementation, potentially opening the door to some customizations in behavior and features for advanced users. + + The following external SQ system is an example of how an implementation would look like. It re-uses much of the + same code as the internal version, but it could be re-implemented in a completely different way to match users' + specific needs. + + \param[in] desc Scene query descriptor + \param[in] contextID Context ID parameter, sent to the profiler + + \return An external SQ system instance + + @see PxSceneQuerySystem PxSceneQueryDesc + */ + PxSceneQuerySystem* PxCreateExternalSceneQuerySystem(const PxSceneQueryDesc& desc, PxU64 contextID); + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/extensions/PxSerialization.h b/Source/ThirdParty/PhysX/extensions/PxSerialization.h index 54e5cdd08..fca17512a 100644 --- a/Source/ThirdParty/PhysX/extensions/PxSerialization.h +++ b/Source/ThirdParty/PhysX/extensions/PxSerialization.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,11 +22,10 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - #ifndef PX_SERIALIZATION_H #define PX_SERIALIZATION_H /** \addtogroup extensions @@ -46,7 +44,7 @@ PX_BINARY_SERIAL_VERSION is used to version the PhysX binary data and meta data. The global unique identifier of the PhysX SDK needs to match the one in the data and meta data, otherwise they are considered incompatible. A 32 character wide GUID can be generated with https://www.guidgenerator.com/ for example. */ -#define PX_BINARY_SERIAL_VERSION "F193874828914B3A8AC4EFE75AED0247" +#define PX_BINARY_SERIAL_VERSION "0E16D844227B469DB23DA9C42CB4E624" #if !PX_DOXYGEN @@ -235,6 +233,8 @@ public: /** \brief Serializes a collection to a binary stream. + \deprecated Deterministic binary serialization is deprecated. PxSerialization::serializeCollectionToBinary might become deterministic in the future. + Convenience function that serializes a collection to a stream while rebasing memory addresses and handles to achieve a deterministic output, independent of the PhysX runtime environment the objects have been created in. @@ -245,11 +245,13 @@ public: @see PxSerialization::serializeCollectionToBinary, PxSerialization::dumpBinaryMetaData, PxBinaryConverter */ - static bool serializeCollectionToBinaryDeterministic(PxOutputStream& outputStream, PxCollection& collection, PxSerializationRegistry& sr, const PxCollection* externalRefs = NULL, bool exportNames = false); + PX_DEPRECATED static bool serializeCollectionToBinaryDeterministic(PxOutputStream& outputStream, PxCollection& collection, PxSerializationRegistry& sr, const PxCollection* externalRefs = NULL, bool exportNames = false); /** \brief Dumps the binary meta-data to a stream. + \deprecated Binary conversion and binary meta data are deprecated. + A meta-data file contains information about the SDK's internal classes and about custom user types ready for serialization. Such a file is needed to convert binary-serialized data from one platform to another (re-targeting). The converter needs meta-data files for the source and target platforms to perform conversions. @@ -261,14 +263,16 @@ public: @see PxOutputStream, PxSerializationRegistry */ - static void dumpBinaryMetaData(PxOutputStream& outputStream, PxSerializationRegistry& sr); + PX_DEPRECATED static void dumpBinaryMetaData(PxOutputStream& outputStream, PxSerializationRegistry& sr); /** \brief Creates binary converter for re-targeting binary-serialized data. + \deprecated Binary conversion and binary meta data are deprecated. + \return Binary converter instance. */ - static PxBinaryConverter* createBinaryConverter(); + PX_DEPRECATED static PxBinaryConverter* createBinaryConverter(); /** \brief Creates an application managed registry for serialization. diff --git a/Source/ThirdParty/PhysX/extensions/PxShapeExt.h b/Source/ThirdParty/PhysX/extensions/PxShapeExt.h index ce4440a8a..e0c059d4e 100644 --- a/Source/ThirdParty/PhysX/extensions/PxShapeExt.h +++ b/Source/ThirdParty/PhysX/extensions/PxShapeExt.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_EXTENSIONS_SHAPE_H -#define PX_PHYSICS_EXTENSIONS_SHAPE_H +#ifndef PX_SHAPE_EXT_H +#define PX_SHAPE_EXT_H /** \addtogroup extensions @{ */ @@ -39,6 +37,7 @@ #include "PxShape.h" #include "PxRigidActor.h" #include "geometry/PxGeometryQuery.h" +#include "PxQueryReport.h" #if !PX_DOXYGEN namespace physx @@ -87,7 +86,7 @@ public: PxU32 maxHits, PxRaycastHit* rayHits) { return PxGeometryQuery::raycast( - rayOrigin, rayDir, shape.getGeometry().any(), getGlobalPose(shape, actor), maxDist, hitFlags, maxHits, rayHits); + rayOrigin, rayDir, shape.getGeometry(), getGlobalPose(shape, actor), maxDist, hitFlags, maxHits, rayHits); } /** @@ -104,7 +103,7 @@ public: static PX_INLINE bool overlap(const PxShape& shape, const PxRigidActor& actor, const PxGeometry& otherGeom, const PxTransform& otherGeomPose) { - return PxGeometryQuery::overlap(shape.getGeometry().any(), getGlobalPose(shape, actor), otherGeom, otherGeomPose); + return PxGeometryQuery::overlap(shape.getGeometry(), getGlobalPose(shape, actor), otherGeom, otherGeomPose); } /** @@ -128,7 +127,7 @@ public: const PxVec3& unitDir, const PxReal distance, const PxGeometry& otherGeom, const PxTransform& otherGeomPose, PxSweepHit& sweepHit, PxHitFlags hitFlags) { - return PxGeometryQuery::sweep(unitDir, distance, otherGeom, otherGeomPose, shape.getGeometry().any(), getGlobalPose(shape, actor), sweepHit, hitFlags); + return PxGeometryQuery::sweep(unitDir, distance, otherGeom, otherGeomPose, shape.getGeometry(), getGlobalPose(shape, actor), sweepHit, hitFlags); } @@ -145,7 +144,7 @@ public: */ static PX_INLINE PxBounds3 getWorldBounds(const PxShape& shape, const PxRigidActor& actor, float inflation=1.01f) { - return PxGeometryQuery::getWorldBounds(shape.getGeometry().any(), getGlobalPose(shape, actor), inflation); + return PxGeometryQuery::getWorldBounds(shape.getGeometry(), getGlobalPose(shape, actor), inflation); } }; diff --git a/Source/ThirdParty/PhysX/extensions/PxSimpleFactory.h b/Source/ThirdParty/PhysX/extensions/PxSimpleFactory.h index d6e423dc3..ac21af09f 100644 --- a/Source/ThirdParty/PhysX/extensions/PxSimpleFactory.h +++ b/Source/ThirdParty/PhysX/extensions/PxSimpleFactory.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_EXTENSIONS_SIMPLE_FACTORY_H -#define PX_PHYSICS_EXTENSIONS_SIMPLE_FACTORY_H +#ifndef PX_SIMPLE_FACTORY_H +#define PX_SIMPLE_FACTORY_H /** \addtogroup extensions @{ */ @@ -51,7 +49,6 @@ namespace physx class PxGeometry; class PxShape; - /** \brief simple method to create a PxRigidDynamic actor with a single PxShape. \param[in] sdk the PxPhysics object @@ -66,7 +63,6 @@ namespace physx @see PxRigidDynamic PxShapeFlag */ - PxRigidDynamic* PxCreateDynamic(PxPhysics& sdk, const PxTransform& transform, const PxGeometry& geometry, @@ -74,7 +70,6 @@ PxRigidDynamic* PxCreateDynamic(PxPhysics& sdk, PxReal density, const PxTransform& shapeOffset = PxTransform(PxIdentity)); - /** \brief simple method to create a PxRigidDynamic actor with a single PxShape. \param[in] sdk the PxPhysics object @@ -87,13 +82,11 @@ PxRigidDynamic* PxCreateDynamic(PxPhysics& sdk, @see PxRigidDynamic PxShapeFlag */ - PxRigidDynamic* PxCreateDynamic(PxPhysics& sdk, const PxTransform& transform, PxShape& shape, PxReal density); - /** \brief simple method to create a kinematic PxRigidDynamic actor with a single PxShape. \param[in] sdk the PxPhysics object @@ -113,7 +106,6 @@ PxRigidDynamic* PxCreateDynamic(PxPhysics& sdk, @see PxRigidDynamic PxShapeFlag */ - PxRigidDynamic* PxCreateKinematic(PxPhysics& sdk, const PxTransform& transform, const PxGeometry& geometry, @@ -121,7 +113,6 @@ PxRigidDynamic* PxCreateKinematic(PxPhysics& sdk, PxReal density, const PxTransform& shapeOffset = PxTransform(PxIdentity)); - /** \brief simple method to create a kinematic PxRigidDynamic actor with a single PxShape. \param[in] sdk the PxPhysics object @@ -139,13 +130,11 @@ PxRigidDynamic* PxCreateKinematic(PxPhysics& sdk, @see PxRigidDynamic PxShapeFlag */ - PxRigidDynamic* PxCreateKinematic(PxPhysics& sdk, const PxTransform& transform, PxShape& shape, PxReal density); - /** \brief simple method to create a PxRigidStatic actor with a single PxShape. \param[in] sdk the PxPhysics object @@ -158,14 +147,12 @@ PxRigidDynamic* PxCreateKinematic(PxPhysics& sdk, @see PxRigidStatic */ - PxRigidStatic* PxCreateStatic(PxPhysics& sdk, const PxTransform& transform, const PxGeometry& geometry, PxMaterial& material, const PxTransform& shapeOffset = PxTransform(PxIdentity)); - /** \brief simple method to create a PxRigidStatic actor with a single PxShape. \param[in] sdk the PxPhysics object @@ -176,28 +163,10 @@ PxRigidStatic* PxCreateStatic(PxPhysics& sdk, @see PxRigidStatic */ - PxRigidStatic* PxCreateStatic(PxPhysics& sdk, const PxTransform& transform, PxShape& shape); - -/** \brief simple method to create a PxRigidStatic actor with a single PxShape. - - \param[in] sdk the PxPhysics object - \param[in] transform the global pose of the new object - \param[in] shape the new object's shape - - \return a new static actor, or NULL if it could not be constructed - - @see PxRigidStatic -*/ - -PxRigidStatic* PxCreateStatic(PxPhysics& sdk, - const PxTransform& transform, - PxShape& shape); - - /** \brief create a shape by copying attributes from another shape @@ -210,6 +179,8 @@ The function clones a PxShape. The following properties are copied: - rest offset - simulation filter data - query filter data +- torsional patch radius +- minimum torsional patch radius The following are not copied and retain their default values: - name @@ -220,15 +191,11 @@ The following are not copied and retain their default values: \param[in] isExclusive whether the new shape should be an exclusive or shared shape. \return the newly-created rigid static - */ - PxShape* PxCloneShape(PxPhysics& physicsSDK, const PxShape& shape, bool isExclusive); - - /** \brief create a static body by copying attributes from another rigid actor @@ -236,6 +203,7 @@ The function clones a PxRigidDynamic or PxRigidStatic as a PxRigidStatic. A unif - shapes - actor flags - owner client and client behavior bits +- dominance group The following are not copied and retain their default values: - name @@ -250,23 +218,21 @@ The following are not copied and retain their default values: \param[in] transform the transform of the new static. \return the newly-created rigid static - */ - PxRigidStatic* PxCloneStatic(PxPhysics& physicsSDK, const PxTransform& transform, const PxRigidActor& actor); - /** \brief create a dynamic body by copying attributes from an existing body The following properties are copied: - shapes -- actor flags and rigidDynamic flags +- actor flags, rigidDynamic flags and rigidDynamic lock flags - mass, moment of inertia, and center of mass frame - linear and angular velocity - linear and angular damping +- maximum linear velocity - maximum angular velocity - position and velocity solver iterations - maximum depenetration velocity @@ -275,6 +241,7 @@ The following properties are copied: - dominance group - owner client and client behavior bits - name pointer +- kinematic target The following are not copied and retain their default values: - name @@ -290,14 +257,11 @@ The following are not copied and retain their default values: \param[in] transform the transform of the new dynamic \return the newly-created rigid static - */ - PxRigidDynamic* PxCloneDynamic(PxPhysics& physicsSDK, const PxTransform& transform, const PxRigidDynamic& body); - /** \brief create a plane actor. The plane equation is n.x + d = 0 \param[in] sdk the PxPhysics object @@ -308,12 +272,10 @@ PxRigidDynamic* PxCloneDynamic(PxPhysics& physicsSDK, @see PxRigidStatic */ - PxRigidStatic* PxCreatePlane(PxPhysics& sdk, const PxPlane& plane, PxMaterial& material); - /** \brief scale a rigid actor by a uniform scale @@ -325,10 +287,8 @@ center of mass is linearly scaled, the mass is multiplied by the cube of the sca \param[in] scale the scale by which to multiply the actor. Must be >0. \param[in] scaleMassProps whether to scale the mass properties */ - void PxScaleRigidActor(PxRigidActor& actor, PxReal scale, bool scaleMassProps = true); - #if !PX_DOXYGEN } // namespace physx #endif diff --git a/Source/ThirdParty/PhysX/extensions/PxSmoothNormals.h b/Source/ThirdParty/PhysX/extensions/PxSmoothNormals.h index 21d0d47f3..7b5285015 100644 --- a/Source/ThirdParty/PhysX/extensions/PxSmoothNormals.h +++ b/Source/ThirdParty/PhysX/extensions/PxSmoothNormals.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_EXTENSIONS_SMOOTH_NORMALS_H -#define PX_PHYSICS_EXTENSIONS_SMOOTH_NORMALS_H +#ifndef PX_SMOOTH_NORMALS_H +#define PX_SMOOTH_NORMALS_H /** \addtogroup extensions @{ */ diff --git a/Source/ThirdParty/PhysX/extensions/PxSoftBodyExt.h b/Source/ThirdParty/PhysX/extensions/PxSoftBodyExt.h new file mode 100644 index 000000000..ffc1c3093 --- /dev/null +++ b/Source/ThirdParty/PhysX/extensions/PxSoftBodyExt.h @@ -0,0 +1,197 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_SOFT_BODY_EXT_H +#define PX_SOFT_BODY_EXT_H +/** \addtogroup extensions + @{ +*/ + +#include "foundation/PxTransform.h" +#include "PxSoftBody.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +struct PxCookingParams; +class PxSimpleTriangleMesh; +class PxInsertionCallback; +class PxSoftBodyMesh; + +/** +\brief utility functions for use with PxSoftBody and subclasses +*/ +class PxSoftBodyExt +{ +public: + /** + \brief Computes the SoftBody's vertex masses from the provided density and the volume of the tetrahedra + + The buffers affected by this operation can be obtained from the SoftBody using the methods getSimPositionInvMassCPU() and getSimVelocityInvMassCPU() + + The inverse mass is stored in the 4th component (the first three components are x, y, z coordinates) of the simulation mesh's position and velocity buffer. + Performance optimizations are the reason why the mass inverse is stored in two locations. + + \param[in] softBody The soft body which will get its mass updated + \param[in] density The density to used to calculate the mass from the body's volume + \param[in] maxInvMassRatio Maximum allowed ratio defined as max(vertexMasses) / min(vertexMasses) where vertexMasses is a list of float values with a mass for every vertex in the simulation mesh + + @see PxSoftBody PxSoftBody::getSimPositionInvMassCPU() PxSoftBody::getSimVelocityInvMassCPU() + */ + static void updateMass(PxSoftBody& softBody, const PxReal density, const PxReal maxInvMassRatio); + + /** + \brief Computes the SoftBody's vertex masses such that the sum of all masses is equal to the provided mass + + The buffers affected by this operation can be obtained from the SoftBody using the methods getSimPositionInvMassCPU() and getSimVelocityInvMassCPU() + + The inverse mass is stored in the 4th component (the first three components are x, y, z coordinates) of the simulation mesh's position and velocity buffer. + Performance optimizations are the reason why the mass inverse is stored in two locations. + + \param[in] softBody The soft body which will get its mass updated + \param[in] mass The SoftBody's mass + \param[in] maxInvMassRatio Maximum allowed ratio defined as max(vertexMasses) / min(vertexMasses) where vertexMasses is a list of float values with a mass for every vertex in the simulation mesh + + @see PxSoftBody PxSoftBody::getSimPositionInvMassCPU() PxSoftBody::getSimVelocityInvMassCPU() + */ + static void setMass(PxSoftBody& softBody, const PxReal mass, const PxReal maxInvMassRatio); + + /** + \brief Transforms a SoftBody + + The buffers affected by this operation can be obtained from the SoftBody using the methods getSimPositionInvMassCPU() and getSimVelocityInvMassCPU() + + Applies a transformation to the simulation mesh's positions an velocities. Velocities only get rotated and scaled (translation is not applicable to direction vectors). + It does not modify the body's mass. + If the method is called multiple times, the transformation will compound with the ones previously applied. + + \param[in] softBody The soft body which is transformed + \param[in] transform The transform to apply + \param[in] scale A scaling factor + + @see PxSoftBody PxSoftBody::getSimPositionInvMassCPU() PxSoftBody::getSimVelocityInvMassCPU() + */ + static void transform(PxSoftBody& softBody, const PxTransform& transform, const PxReal scale); + + /** + \brief Updates the collision mesh's vertex positions to match the simulation mesh's transformation and scale. + + The buffer affected by this operation can be obtained from the SoftBody using the method getPositionInvMassCPU() + + \param[in] softBody The soft body which will get its collision mesh vertices updated + + @see PxSoftBody PxSoftBody::getPositionInvMassCPU() + */ + static void updateEmbeddedCollisionMesh(PxSoftBody& softBody); + + /** + \brief Uploads prepared SoftBody data to the GPU. It ensures that the embedded collision mesh matches the simulation mesh's transformation and scale. + + \param[in] softBody The soft body which will perform the data upload + \param[in] flags Specifies which buffers the data transfer should include + \param[in] flush If set to true, the upload will get processed immediately, otherwise it will take place before the data is needed for calculations on the GPU + + @see PxSoftBody + */ + static void commit(PxSoftBody& softBody, PxSoftBodyDataFlags flags, bool flush = false); + + /** + \brief Creates a full SoftBody mesh matching the shape given as input. Uses a voxel mesh for FEM simulation and a surface-matching mesh for collision detection. + + \param[in] params Cooking params instance required for mesh processing + \param[in] surfaceMesh Input triangle mesh that represents the surface of the SoftBody + \param[in] numVoxelsAlongLongestAABBAxis The number of voxels along the longest bounding box axis + \param[in] insertionCallback The insertion interface from PxPhysics + \param[in] validate If set to true the input triangle mesh will get analyzed to find possible deficiencies + \return SoftBody mesh if cooking was successful, NULL otherwise + @see PxSoftBodyMesh + */ + static PxSoftBodyMesh* createSoftBodyMesh(const PxCookingParams& params, const PxSimpleTriangleMesh& surfaceMesh, PxU32 numVoxelsAlongLongestAABBAxis, PxInsertionCallback& insertionCallback, const bool validate = true); + + /** + \brief Creates a full SoftBody mesh matching the shape given as input. Uses the same surface-matching mesh for collision detection and FEM simulation. + + \param[in] params Cooking params instance required for mesh processing + \param[in] surfaceMesh Input triangle mesh that represents the surface of the SoftBody + \param[in] insertionCallback The insertion interface from PxPhysics + \param[in] maxWeightRatioInTet Upper limit for the ratio of node weights that are adjacent to the same tetrahedron. The closer to one (while remaining larger than one), the more stable the simulation. + \param[in] validate If set to true the input triangle mesh will get analyzed to find possible deficiencies + \return SoftBody mesh if cooking was successful, NULL otherwise + @see PxSoftBodyMesh + */ + static PxSoftBodyMesh* createSoftBodyMeshNoVoxels(const PxCookingParams& params, const PxSimpleTriangleMesh& surfaceMesh, PxInsertionCallback& insertionCallback, PxReal maxWeightRatioInTet = 1.5f, const bool validate = true); + + + /** + \brief Creates a SoftBody instance from a SoftBody mesh + + \param[in] softBodyMesh The SoftBody mesh + \param[in] transform The transform that defines initial position and orientation of the SoftBody + \param[in] material The material + \param[in] cudaContextManager A cuda context manager + \param[in] density The density used to compute the mass properties + \param[in] solverIterationCount The number of iterations the solver should apply during simulation + \param[in] femParams Additional parameters to specify e. g. damping + \param[in] scale The scaling of the SoftBody + \return SoftBody instance + @see PxSoftBodyMesh, PxSoftBody + */ + static PxSoftBody* createSoftBodyFromMesh(PxSoftBodyMesh* softBodyMesh, const PxTransform& transform, + const PxFEMSoftBodyMaterial& material, PxCudaContextManager& cudaContextManager, PxReal density = 100.0f, PxU32 solverIterationCount = 30, + const PxFEMParameters& femParams = PxFEMParameters(), PxReal scale = 1.0f); + + + /** + \brief Creates a SoftBody instance with a box shape + + \param[in] transform The transform that defines initial position and orientation of the SoftBody + \param[in] boxDimensions The dimensions (side lengths) of the box shape + \param[in] material The material + \param[in] cudaContextManager A cuda context manager + \param[in] maxEdgeLength The maximal length of a triangle edge. Subdivision will get applied until the edge length criteria is matched. -1 means no subdivision is applied. + \param[in] density The density used to compute the mass properties + \param[in] solverIterationCount The number of iterations the solver should apply during simulation + \param[in] femParams Additional parameters to specify e. g. damping + \param[in] numVoxelsAlongLongestAABBAxis The number of voxels to use for the simulation mesh along the longest bounding box dimension + \param[in] scale The scaling of the SoftBody + \return SoftBody instance + @see PxSoftBodyMesh, PxSoftBody + */ + static PxSoftBody* createSoftBodyBox(const PxTransform& transform, const PxVec3& boxDimensions, const PxFEMSoftBodyMaterial& material, + PxCudaContextManager& cudaContextManager, PxReal maxEdgeLength = -1.0f, PxReal density = 100.0f, PxU32 solverIterationCount = 30, + const PxFEMParameters& femParams = PxFEMParameters(), PxU32 numVoxelsAlongLongestAABBAxis = 10, PxReal scale = 1.0f); +}; + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/extensions/PxSphericalJoint.h b/Source/ThirdParty/PhysX/extensions/PxSphericalJoint.h index 188ebfc41..bee05853f 100644 --- a/Source/ThirdParty/PhysX/extensions/PxSphericalJoint.h +++ b/Source/ThirdParty/PhysX/extensions/PxSphericalJoint.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PX_SPHERICALJOINT_H -#define PX_SPHERICALJOINT_H +#ifndef PX_SPHERICAL_JOINT_H +#define PX_SPHERICAL_JOINT_H /** \addtogroup extensions @{ */ @@ -168,8 +167,10 @@ public: \param[in] tolerance the linear tolerance threshold @see getProjectionLinearTolerance() PxJoint::setConstraintFlags() PxConstraintFlag::ePROJECTION + + @deprecated */ - virtual void setProjectionLinearTolerance(PxReal tolerance) = 0; + PX_DEPRECATED virtual void setProjectionLinearTolerance(PxReal tolerance) = 0; /** \brief Get the linear tolerance threshold for projection. @@ -177,8 +178,10 @@ public: \return the linear tolerance threshold @see setProjectionLinearTolerance() + + @deprecated */ - virtual PxReal getProjectionLinearTolerance() const = 0; + PX_DEPRECATED virtual PxReal getProjectionLinearTolerance() const = 0; /** \brief Returns string name of PxSphericalJoint, used for serialization diff --git a/Source/ThirdParty/PhysX/extensions/PxStringTableExt.h b/Source/ThirdParty/PhysX/extensions/PxStringTableExt.h index a40f1d33b..b4fdb1cf8 100644 --- a/Source/ThirdParty/PhysX/extensions/PxStringTableExt.h +++ b/Source/ThirdParty/PhysX/extensions/PxStringTableExt.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,11 +22,10 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - #ifndef PX_STRING_TABLE_EXT_H #define PX_STRING_TABLE_EXT_H #include "foundation/Px.h" diff --git a/Source/ThirdParty/PhysX/extensions/PxTetMakerExt.h b/Source/ThirdParty/PhysX/extensions/PxTetMakerExt.h new file mode 100644 index 000000000..e5d8dd51b --- /dev/null +++ b/Source/ThirdParty/PhysX/extensions/PxTetMakerExt.h @@ -0,0 +1,188 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_TETMAKER_EXT_H +#define PX_TETMAKER_EXT_H +/** \addtogroup extensions + @{ +*/ + +#include "foundation/PxSimpleTypes.h" +#include "foundation/PxVec3.h" +#include "common/PxCoreUtilityTypes.h" +#include "foundation/PxArray.h" +#include "PxTriangleMeshAnalysisResult.h" +#include "PxTetrahedronMeshAnalysisResult.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +class PxTriangleMesh; +class PxTetrahedronMeshDesc; +class PxSoftBodySimulationDataDesc; +struct PxTetMakerData; +class PxSimpleTriangleMesh; + +/** +\brief Provides functionality to create a tetrahedral mesh from a triangle mesh. +*/ +class PxTetMaker +{ +public: + + /** + \brief Create conforming tetrahedron mesh using TetMaker + + \param[in] triangleMesh The description of the triangle mesh including vertices and indices + \param[out] outVertices The vertices to store the conforming tetrahedral mesh + \param[out] outTetIndices The indices to store the conforming tetrahedral mesh + \param[in] validate If set to true the input triangle mesh will get analyzed to find possible deficiencies + \param[in] volumeThreshold Tetrahedra with a volume smaller than the specified threshold will be removed from the mesh + \return True if success + */ + static bool createConformingTetrahedronMesh(const PxSimpleTriangleMesh& triangleMesh, physx::PxArray& outVertices, physx::PxArray& outTetIndices, + const bool validate = true, PxReal volumeThreshold = 0.0f); + + /** + \brief Create voxel-based tetrahedron mesh using TetMaker + + \param[in] tetMesh The description of the tetrahedral mesh including vertices and indices + \param[in] numVoxelsAlongLongestBoundingBoxAxis The number of voxels along the longest bounding box axis + \param[out] outVertices The vertices to store the voxel-based tetrahedral mesh + \param[out] outTetIndices The indices to store the voxel-based tetrahedral mesh + \param[out] inputPointToOutputTetIndex Buffer with the size of nbTetVerts that contains the tetrahedron index containing the input point with the same index + \param[in] anchorNodeIndices Some input vertices may not be referenced by any tetrahedron. They can be mapped to another input vertex that is used by a tetrahedron to support embedding of additional points. + \return True if success + */ + static bool createVoxelTetrahedronMesh(const PxTetrahedronMeshDesc& tetMesh, const PxU32 numVoxelsAlongLongestBoundingBoxAxis, + physx::PxArray& outVertices, physx::PxArray& outTetIndices, PxI32* inputPointToOutputTetIndex = NULL, const PxU32* anchorNodeIndices = NULL); + + /** + \brief Create voxel-based tetrahedron mesh using TetMaker + + \param[in] tetMesh The description of the tetrahedral mesh including vertices and indices + \param[in] voxelEdgeLength The edge length of a voxel.Can be adjusted slightly such that a multiple of it matches the input points' bounding box size + \param[out] outVertices The vertices to store the voxel-based tetrahedral mesh + \param[out] outTetIndices The indices to store the voxel-based tetrahedral mesh + \param[out] inputPointToOutputTetIndex Buffer with the size of nbTetVerts that contains the tetrahedron index containing the input point with the same index + \param[in] anchorNodeIndices Some input vertices may not be referenced by any tetrahedron. They can be mapped to another input vertex that is used by a tetrahedron to support embedding of additional points. + \return True if success + */ + static bool createVoxelTetrahedronMeshFromEdgeLength(const PxTetrahedronMeshDesc& tetMesh, const PxReal voxelEdgeLength, + physx::PxArray& outVertices, physx::PxArray& outTetIndices, PxI32* inputPointToOutputTetIndex = NULL, const PxU32* anchorNodeIndices = NULL); + + /** + \brief Analyzes the triangle mesh to get a report about deficiencies. Some deficiencies can be handled by the tetmesher, others cannot. + + \param[in] triangleMesh The description of the triangle mesh including vertices and indices + \param[in] minVolumeThreshold Minimum volume the mesh must have such that no volume warning is generated + \param[in] minTriangleAngleRadians Minimum angle allowed for triangles such that no angle warning is generated + \return Flags that describe the triangle mesh's deficiencies + */ + static PxTriangleMeshAnalysisResults validateTriangleMesh(const PxSimpleTriangleMesh& triangleMesh, const PxReal minVolumeThreshold = 1e-6f, const PxReal minTriangleAngleRadians = 10.0f*3.1415926535898f / 180.0f); + + /** + \brief Analyzes the tetrahedron mesh to get a report about deficiencies. Some deficiencies can be handled by the softbody cooker, others cannot. + + \param[in] points The mesh's points + \param[in] tetrahedra The mesh's tetrahedra (index buffer) + \param[in] minTetVolumeThreshold Minimum volume every tetrahedron in the mesh must have such that no volume warning is generated + \return Flags that describe the tetrahedron mesh's deficiencies + */ + static PxTetrahedronMeshAnalysisResults validateTetrahedronMesh(const PxBoundedData& points, const PxBoundedData& tetrahedra, const PxReal minTetVolumeThreshold = 1e-8f); + + /** + \brief Simplifies (decimates) a triangle mesh using quadric simplification. + + \param[in] inputVertices The vertices of the input triangle mesh + \param[in] inputIndices The indices of the input triangle mesh of the form (id0, id1, id2), (id0, id1, id2), .. + \param[in] targetTriangleCount Desired number of triangles in the output mesh + \param[in] maximalEdgeLength Edges below this length will not be collapsed. A value of zero means there is no limit. + \param[out] outputVertices The vertices of the output (decimated) triangle mesh + \param[out] outputIndices The indices of the output (decimated) triangle mesh of the form (id0, id1, id2), (id0, id1, id2), .. + \param[out] vertexMap Optional parameter which returns the mapping from input to output vertices. Note that multiple input vertices are typically collapsed into the same output vertex. + \param[in] edgeLengthCostWeight Factor to scale influence of edge length when prioritizing edge collapses. Has no effect if set to zero. + \param[in] flatnessDetectionThreshold Threshold used to detect edges in flat regions and to improve the placement of the collapsed point. If set to a large value it will have no effect. + */ + static void simplifyTriangleMesh(const PxArray& inputVertices, const PxArray&inputIndices, int targetTriangleCount, PxF32 maximalEdgeLength, + PxArray& outputVertices, PxArray& outputIndices, + PxArray *vertexMap = NULL, PxReal edgeLengthCostWeight = 0.1f, PxReal flatnessDetectionThreshold = 0.01f); + + /** + \brief Creates a new mesh from a given mesh. The input mesh is first voxelized. The new surface is created from the voxel surface and subsequent projection to the original mesh. + + \param[in] inputVertices The vertices of the input triangle mesh + \param[in] inputIndices The indices of the input triangle mesh of the form (id0, id1, id2), (id0, id1, id2), .. + \param[in] gridResolution Size of the voxel grid (number of voxels along the longest dimension) + \param[out] outputVertices The vertices of the output (decimated) triangle mesh + \param[out] outputIndices The indices of the output (decimated) triangle mesh of the form (id0, id1, id2), (id0, id1, id2), .. + \param[out] vertexMap Optional parameter which returns a mapping from input to output vertices. Since the meshes are independent, the mapping returns an output vertex that is topologically close to the input vertex. + */ + static void remeshTriangleMesh(const PxArray& inputVertices, const PxArray&inputIndices, int gridResolution, + PxArray& outputVertices, PxArray& outputIndices, + PxArray *vertexMap = NULL); + + /** + \brief Creates a tetrahedral mesh using an octree. + + \param[in] inputVertices The vertices of the input triangle mesh + \param[in] inputIndices The indices of the input triangle mesh of the form (id0, id1, id2), (id0, id1, id2), .. + \param[in] useTreeNodes Using the nodes of the octree as tetrahedral vertices + \param[out] outputVertices The vertices of the output tetrahedral mesh + \param[out] outputIndices The indices of the output tetrahedral mesh of the form (id0, id1, id2, id3), (id0, id1, id2, id3), .. + \param[in] volumeThreshold Tetrahedra with a volume smaller than the specified threshold will be removed from the mesh + */ + static void createTreeBasedTetrahedralMesh(const PxArray& inputVertices, const PxArray&inputIndices, + bool useTreeNodes, PxArray& outputVertices, PxArray& outputIndices, PxReal volumeThreshold = 0.0f); + + /** + \brief Creates a tetrahedral mesh by relaxing a voxel mesh around the input mesh + + \param[in] inputVertices The vertices of the input triangle mesh + \param[in] inputIndices The indices of the input triangle mesh of the form (id0, id1, id2), (id0, id1, id2), .. + \param[out] outputVertices The vertices of the output tetrahedral mesh + \param[out] outputIndices The indices of the output tetrahedral mesh of the form (id0, id1, id2, id3), (id0, id1, id2, id3), .. + \param[in] resolution The grid spacing is computed as the diagonal of the bounding box of the input mesh divided by the resolution. + \param[in] numRelaxationIterations Number of iterations to pull the tetrahedral mesh towards the input mesh + \param[in] relMinTetVolume Constrains the volumes of the tetrahedra to stay abobe relMinTetvolume times the tetrahedron's rest volume. + */ + static void createRelaxedVoxelTetrahedralMesh(const PxArray& inputVertices, const PxArray&inputIndices, + PxArray& outputVertices, PxArray& outputIndices, + PxI32 resolution, PxI32 numRelaxationIterations = 5, PxF32 relMinTetVolume = 0.05f); + +}; + +#if !PX_DOXYGEN +} +#endif + +/** @} */ +#endif + diff --git a/Source/ThirdParty/PhysX/extensions/PxTetrahedronMeshAnalysisResult.h b/Source/ThirdParty/PhysX/extensions/PxTetrahedronMeshAnalysisResult.h new file mode 100644 index 000000000..be88af9e7 --- /dev/null +++ b/Source/ThirdParty/PhysX/extensions/PxTetrahedronMeshAnalysisResult.h @@ -0,0 +1,61 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. + +#ifndef PX_TETRAHEDRON_MESH_ANALYSIS_RESULT_H +#define PX_TETRAHEDRON_MESH_ANALYSIS_RESULT_H + + +#include "PxPhysXConfig.h" +#include "foundation/PxFlags.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + /** + \brief These flags indicate what kind of deficiencies a tetrahedron mesh has and describe if the mesh is considered ok, problematic or invalid for softbody cooking + */ + class PxTetrahedronMeshAnalysisResult + { + public: + enum Enum + { + eVALID = 0, + eDEGENERATE_TETRAHEDRON = (1 << 0), //!< At least one tetrahedron has zero or negative volume. This can happen when the input triangle mesh contains triangles that are very elongated, e. g. one edge is a lot shorther than the other two. + + eMESH_IS_PROBLEMATIC = (1 << 1), //!< flag is set if the mesh is categorized as problematic + eMESH_IS_INVALID = (1 << 2) //!< flag is set if the mesh is categorized as invalid + }; + }; + typedef PxFlags PxTetrahedronMeshAnalysisResults; + PX_FLAGS_OPERATORS(PxTetrahedronMeshAnalysisResult::Enum, PxU32) + +#if !PX_DOXYGEN +} +#endif + +#endif diff --git a/Source/ThirdParty/PhysX/extensions/PxTetrahedronMeshExt.h b/Source/ThirdParty/PhysX/extensions/PxTetrahedronMeshExt.h new file mode 100644 index 000000000..ca24c4415 --- /dev/null +++ b/Source/ThirdParty/PhysX/extensions/PxTetrahedronMeshExt.h @@ -0,0 +1,100 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_TETRAHEDRON_MESH_EXT_H +#define PX_TETRAHEDRON_MESH_EXT_H +/** \addtogroup extensions + @{ +*/ + +#include "foundation/PxVec3.h" +#include "foundation/PxArray.h" + + +#if !PX_DOXYGEN +namespace physx +{ +#endif + class PxTetrahedronMesh; + + /** + \brief utility functions for use with PxTetrahedronMesh and subclasses + */ + class PxTetrahedronMeshExt + { + public: + /** Returns the index of the tetrahedron that contains a point + + \param[in] mesh The tetmesh + \param[in] point The point to find the enclosing tetrahedron for + \param[in] bary The barycentric coordinates of the point inside the enclosing tetrahedron + \param[in] tolerance Tolerance value used classify points as inside if they lie exactly a tetrahedron's surface + \return The index of the tetrahedon containing the point, -1 if not tetrahedron contains the opoint + */ + static PxI32 findTetrahedronContainingPoint(const PxTetrahedronMesh* mesh, const PxVec3& point, PxVec4& bary, PxReal tolerance = 1e-6f); + + /** Returns the index of the tetrahedron closest to a point + + \param[in] mesh The tetmesh + \param[in] point The point to find the closest tetrahedron for + \param[in] bary The barycentric coordinates of the point in the tetrahedron + \return The index of the tetrahedon closest to the point + */ + static PxI32 findTetrahedronClosestToPoint(const PxTetrahedronMesh* mesh, const PxVec3& point, PxVec4& bary); + + /** Extracts the surface triangles of a tetmesh + + The extracted triangle's vertex indices point to the vertex buffer of the tetmesh. + + \param[in] tetrahedra The tetrahedra indices + \param[in] numTetrahedra The number of tetrahedra + \param[in] sixteenBitIndices If set to true, the tetrahedra indices are read as 16bit integers, otherwise 32bit integers are used + \param[in] surfaceTriangles The resulting surface triangles + \param[in] surfaceTriangleToTet Optional array to get the index of a tetrahedron that is adjacent to the surface triangle with the corresponding index + \param[in] flipTriangleOrientation Reverses the orientation of the ouput triangles + */ + static void extractTetMeshSurface(const void* tetrahedra, PxU32 numTetrahedra, bool sixteenBitIndices, PxArray& surfaceTriangles, PxArray* surfaceTriangleToTet = NULL, bool flipTriangleOrientation = false); + + /** Extracts the surface triangles of a tetmesh + + The extracted triangle's vertex indices point to the vertex buffer of the tetmesh. + + \param[in] mesh The mesh from which the surface shall be computed + \param[in] surfaceTriangles The resulting surface triangles + \param[in] surfaceTriangleToTet Optional array to get the index of a tetrahedron that is adjacent to the surface triangle with the corresponding index + \param[in] flipTriangleOrientation Reverses the orientation of the ouput triangles + */ + static void extractTetMeshSurface(const PxTetrahedronMesh* mesh, PxArray& surfaceTriangles, PxArray* surfaceTriangleToTet = NULL, bool flipTriangleOrientation = false); + }; + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/extensions/PxTriangleMeshAnalysisResult.h b/Source/ThirdParty/PhysX/extensions/PxTriangleMeshAnalysisResult.h new file mode 100644 index 000000000..e84bcf95c --- /dev/null +++ b/Source/ThirdParty/PhysX/extensions/PxTriangleMeshAnalysisResult.h @@ -0,0 +1,69 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. + +#ifndef PX_TRIANGLE_MESH_ANALYSIS_RESULT_H +#define PX_TRIANGLE_MESH_ANALYSIS_RESULT_H + + +#include "PxPhysXConfig.h" +#include "foundation/PxFlags.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + /** + \brief These flags indicate what kind of deficiencies a triangle mesh has and describe if the mesh is considered ok, problematic or invalid for tetmeshing + */ + class PxTriangleMeshAnalysisResult + { + public: + enum Enum + { + eVALID = 0, + eZERO_VOLUME = (1 << 0), //!< invalid: Flat mesh without meaningful amount of volume - cannot be meshed since a tetmesh is volumetric + eOPEN_BOUNDARIES = (1 << 1), //!< problematic: Open boundary means that the mesh is not watertight and that there are holes. The mesher can fill holes but the surface might have an unexpected shape where the hole was. + eSELF_INTERSECTIONS = (1 << 2), //!< problematic: The surface of the resulting mesh won't match exactly at locations of self-intersections. The tetmesh might be connected at self-intersections even if the input triangle mesh is not + eINCONSISTENT_TRIANGLE_ORIENTATION = (1 << 3), //!< invalid: It is not possible to distinguish what is inside and outside of the mesh. If there are no self-intersections and not edges shared by more than two triangles, a call to makeTriOrientationConsistent can fix this. Without fixing it, the output from the tetmesher will be incorrect + eCONTAINS_ACUTE_ANGLED_TRIANGLES = (1 << 4), //!< problematic: An ideal mesh for a softbody has triangles with similar angles and evenly distributed vertices. Acute angles can be handled but might lead to a poor quality tetmesh. + eEDGE_SHARED_BY_MORE_THAN_TWO_TRIANGLES = (1 << 5), //!< problematic: Border case of a self-intersecting mesh. The tetmesh might not match the surace exactly near such edges. + eCONTAINS_DUPLICATE_POINTS = (1 << 6), //!< ok: Duplicate points can be handled by the mesher without problems. The resulting tetmesh will only make use of first unique point that is found, duplicate points will get mapped to that unique point in the tetmesh. Therefore the tetmesh can contain points that are not accessed by a tet. + eCONTAINS_INVALID_POINTS = (1 << 7), //!< invalid: Points contain NAN, infinity or similar values that will lead to an invalid mesh + eREQUIRES_32BIT_INDEX_BUFFER = (1 << 8), //!< invalid: Mesh contains more indices than a 16bit index buffer can address + + eMESH_IS_PROBLEMATIC = (1 << 9), //!< flag is set if the mesh is categorized as problematic + eMESH_IS_INVALID = (1 << 10) //!< flag is set if the mesh is categorized as invalid + }; + }; + typedef PxFlags PxTriangleMeshAnalysisResults; + PX_FLAGS_OPERATORS(PxTriangleMeshAnalysisResult::Enum, PxU32) + +#if !PX_DOXYGEN +} +#endif + +#endif diff --git a/Source/ThirdParty/PhysX/extensions/PxTriangleMeshExt.h b/Source/ThirdParty/PhysX/extensions/PxTriangleMeshExt.h index 8bee28db9..c5de6966d 100644 --- a/Source/ThirdParty/PhysX/extensions/PxTriangleMeshExt.h +++ b/Source/ThirdParty/PhysX/extensions/PxTriangleMeshExt.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,19 +22,19 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_EXTENSIONS_TRIANGLE_MESH_H -#define PX_PHYSICS_EXTENSIONS_TRIANGLE_MESH_H +#ifndef PX_TRIANGLE_MESH_EXT_H +#define PX_TRIANGLE_MESH_EXT_H /** \addtogroup extensions @{ */ #include "PxPhysXConfig.h" #include "common/PxPhysXCommonConfig.h" +#include "foundation/PxArray.h" #if !PX_DOXYGEN namespace physx @@ -43,6 +42,7 @@ namespace physx #endif class PxGeometry; +class PxTriangleMesh; class PxTriangleMeshGeometry; class PxHeightFieldGeometry; @@ -180,6 +180,15 @@ class PxHeightFieldGeometry; PxU32 maxIter, PxU32* usedIter = NULL); + /** + \brief Extracts an isosurface from the SDF of a mesh if it the SDF is available. + + \param[in] triangleMesh The triangle mesh + \param[out] isosurfaceVertices The vertices of the extracted isosurface + \param[out] isosurfaceTriangleIndices The triangles of the extracted isosurface + */ + bool PxExtractIsosurfaceFromSDF(const PxTriangleMesh& triangleMesh, PxArray& isosurfaceVertices, PxArray& isosurfaceTriangleIndices); + #if !PX_DOXYGEN } // namespace physx #endif diff --git a/Source/ThirdParty/PhysX/filebuf/PxFileBuf.h b/Source/ThirdParty/PhysX/filebuf/PxFileBuf.h index 9431fc36c..79ab02661 100644 --- a/Source/ThirdParty/PhysX/filebuf/PxFileBuf.h +++ b/Source/ThirdParty/PhysX/filebuf/PxFileBuf.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,7 +22,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. @@ -205,7 +204,7 @@ public: void release(void) { - delete this; + PX_DELETE_THIS; } static PX_INLINE bool isBigEndian() diff --git a/Source/ThirdParty/PhysX/foundation/PsAllocator.h b/Source/ThirdParty/PhysX/foundation/PsAllocator.h deleted file mode 100644 index 91c5ea9dc..000000000 --- a/Source/ThirdParty/PhysX/foundation/PsAllocator.h +++ /dev/null @@ -1,367 +0,0 @@ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of NVIDIA CORPORATION nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. -// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. -// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PSFOUNDATION_PSALLOCATOR_H -#define PSFOUNDATION_PSALLOCATOR_H - -#include "foundation/PxAllocatorCallback.h" -#include "foundation/PxAssert.h" -#include "PxFoundation.h" -#include "Ps.h" - -#if(PX_WINDOWS_FAMILY || PX_XBOXONE) - #include - #include -#endif -#if(PX_APPLE_FAMILY) - #include -#endif - -#include - -// Allocation macros going through user allocator -#if PX_CHECKED - #define PX_ALLOC(n, name) physx::shdfnd::NamedAllocator(name).allocate(n, __FILE__, __LINE__) -#else - #define PX_ALLOC(n, name) physx::shdfnd::NonTrackingAllocator().allocate(n, __FILE__, __LINE__) -#endif -#define PX_ALLOC_TEMP(n, name) PX_ALLOC(n, name) -#define PX_FREE(x) physx::shdfnd::NonTrackingAllocator().deallocate(x) -#define PX_FREE_AND_RESET(x) \ - { \ - PX_FREE(x); \ - x = 0; \ - } - -// The following macros support plain-old-types and classes derived from UserAllocated. -#define PX_NEW(T) new (physx::shdfnd::ReflectionAllocator(), __FILE__, __LINE__) T -#define PX_NEW_TEMP(T) PX_NEW(T) -#define PX_DELETE(x) delete x -#define PX_DELETE_AND_RESET(x) \ - { \ - PX_DELETE(x); \ - x = 0; \ - } -#define PX_DELETE_POD(x) \ - { \ - PX_FREE(x); \ - x = 0; \ - } -#define PX_DELETE_ARRAY(x) \ - { \ - PX_DELETE([] x); \ - x = 0; \ - } - -// aligned allocation -#define PX_ALIGNED16_ALLOC(n) physx::shdfnd::AlignedAllocator<16>().allocate(n, __FILE__, __LINE__) -#define PX_ALIGNED16_FREE(x) physx::shdfnd::AlignedAllocator<16>().deallocate(x) - -//! placement new macro to make it easy to spot bad use of 'new' -#define PX_PLACEMENT_NEW(p, T) new (p) T - -#if PX_DEBUG || PX_CHECKED - #define PX_USE_NAMED_ALLOCATOR 1 -#else - #define PX_USE_NAMED_ALLOCATOR 0 -#endif - -// Don't use inline for alloca !!! -#if PX_WINDOWS_FAMILY - #include - #define PxAlloca(x) _alloca(x) -#elif PX_LINUX || PX_ANDROID - #include - #define PxAlloca(x) alloca(x) -#elif PX_APPLE_FAMILY - #include - #define PxAlloca(x) alloca(x) -#elif PX_PS4 - #include - #define PxAlloca(x) alloca(x) -#elif PX_XBOXONE - #include - #define PxAlloca(x) alloca(x) -#elif PX_SWITCH - #include - #define PxAlloca(x) alloca(x) -#endif - -#define PxAllocaAligned(x, alignment) ((size_t(PxAlloca(x + alignment)) + (alignment - 1)) & ~size_t(alignment - 1)) - -namespace physx -{ -namespace shdfnd -{ - -PX_FOUNDATION_API PxAllocatorCallback& getAllocator(); - -/** -Allocator used to access the global PxAllocatorCallback instance without providing additional information. -*/ - -class PX_FOUNDATION_API Allocator -{ - public: - Allocator(const char* = 0) - { - } - void* allocate(size_t size, const char* file, int line); - void deallocate(void* ptr); -}; - -/* - * Bootstrap allocator using malloc/free. - * Don't use unless your objects get allocated before foundation is initialized. - */ -class RawAllocator -{ - public: - RawAllocator(const char* = 0) - { - } - void* allocate(size_t size, const char*, int) - { - // malloc returns valid pointer for size==0, no need to check - return ::malloc(size); - } - void deallocate(void* ptr) - { - // free(0) is guaranteed to have no side effect, no need to check - ::free(ptr); - } -}; - -/* - * Allocator that simply calls straight back to the application without tracking. - * This is used by the heap (Foundation::mNamedAllocMap) that tracks allocations - * because it needs to be able to grow as a result of an allocation. - * Making the hash table re-entrant to deal with this may not make sense. - */ -class NonTrackingAllocator -{ - public: - PX_FORCE_INLINE NonTrackingAllocator(const char* = 0) - { - } - PX_FORCE_INLINE void* allocate(size_t size, const char* file, int line) - { - return !size ? 0 : getAllocator().allocate(size, "NonTrackedAlloc", file, line); - } - PX_FORCE_INLINE void deallocate(void* ptr) - { - if(ptr) - getAllocator().deallocate(ptr); - } -}; - -/* -\brief Virtual allocator callback used to provide run-time defined allocators to foundation types like Array or Bitmap. - This is used by VirtualAllocator -*/ -class VirtualAllocatorCallback -{ - public: - VirtualAllocatorCallback() - { - } - virtual ~VirtualAllocatorCallback() - { - } - virtual void* allocate(const size_t size, const char* file, const int line) = 0; - virtual void deallocate(void* ptr) = 0; -}; - -/* -\brief Virtual allocator to be used by foundation types to provide run-time defined allocators. -Due to the fact that Array extends its allocator, rather than contains a reference/pointer to it, the VirtualAllocator -must -be a concrete type containing a pointer to a virtual callback. The callback may not be available at instantiation time, -therefore -methods are provided to set the callback later. -*/ -class VirtualAllocator -{ - public: - VirtualAllocator(VirtualAllocatorCallback* callback = NULL) : mCallback(callback) - { - } - - void* allocate(const size_t size, const char* file, const int line) - { - PX_ASSERT(mCallback); - if(size) - return mCallback->allocate(size, file, line); - return NULL; - } - void deallocate(void* ptr) - { - PX_ASSERT(mCallback); - if(ptr) - mCallback->deallocate(ptr); - } - - void setCallback(VirtualAllocatorCallback* callback) - { - mCallback = callback; - } - VirtualAllocatorCallback* getCallback() - { - return mCallback; - } - - private: - VirtualAllocatorCallback* mCallback; - VirtualAllocator& operator=(const VirtualAllocator&); -}; - -#if PX_USE_NAMED_ALLOCATOR // can be slow, so only use in debug/checked -class PX_FOUNDATION_API NamedAllocator -{ - public: - NamedAllocator(const PxEMPTY); - NamedAllocator(const char* name = 0); // todo: should not have default argument! - NamedAllocator(const NamedAllocator&); - ~NamedAllocator(); - NamedAllocator& operator=(const NamedAllocator&); - void* allocate(size_t size, const char* filename, int line); - void deallocate(void* ptr); -}; -#else -class NamedAllocator; -#endif // PX_DEBUG - -/** -Allocator used to access the global PxAllocatorCallback instance using a static name derived from T. -*/ - -template -class ReflectionAllocator -{ - static const char* getName() - { - if(!PxGetFoundation().getReportAllocationNames()) - return ""; -#if PX_GCC_FAMILY - return __PRETTY_FUNCTION__; -#else - // name() calls malloc(), raw_name() wouldn't - return typeid(T).name(); -#endif - } - - public: - ReflectionAllocator(const PxEMPTY) - { - } - ReflectionAllocator(const char* = 0) - { - } - inline ReflectionAllocator(const ReflectionAllocator&) - { - } - void* allocate(size_t size, const char* filename, int line) - { - return size ? getAllocator().allocate(size, getName(), filename, line) : 0; - } - void deallocate(void* ptr) - { - if(ptr) - getAllocator().deallocate(ptr); - } -}; - -template -struct AllocatorTraits -{ -#if PX_USE_NAMED_ALLOCATOR - typedef NamedAllocator Type; -#else - typedef ReflectionAllocator Type; -#endif -}; - -// if you get a build error here, you are trying to PX_NEW a class -// that is neither plain-old-type nor derived from UserAllocated -template -union EnableIfPod -{ - int i; - T t; - typedef X Type; -}; - -} // namespace shdfnd -} // namespace physx - -// Global placement new for ReflectionAllocator templated by -// plain-old-type. Allows using PX_NEW for pointers and built-in-types. -// -// ATTENTION: You need to use PX_DELETE_POD or PX_FREE to deallocate -// memory, not PX_DELETE. PX_DELETE_POD redirects to PX_FREE. -// -// Rationale: PX_DELETE uses global operator delete(void*), which we dont' want to overload. -// Any other definition of PX_DELETE couldn't support array syntax 'PX_DELETE([]a);'. -// PX_DELETE_POD was preferred over PX_DELETE_ARRAY because it is used -// less often and applies to both single instances and arrays. -template -PX_INLINE void* operator new(size_t size, physx::shdfnd::ReflectionAllocator alloc, const char* fileName, - typename physx::shdfnd::EnableIfPod::Type line) -{ - return alloc.allocate(size, fileName, line); -} - -template -PX_INLINE void* operator new [](size_t size, physx::shdfnd::ReflectionAllocator alloc, const char* fileName, - typename physx::shdfnd::EnableIfPod::Type line) -{ return alloc.allocate(size, fileName, line); } - -// If construction after placement new throws, this placement delete is being called. -template -PX_INLINE void operator delete(void* ptr, physx::shdfnd::ReflectionAllocator alloc, const char* fileName, - typename physx::shdfnd::EnableIfPod::Type line) -{ - PX_UNUSED(fileName); - PX_UNUSED(line); - - alloc.deallocate(ptr); -} - -// If construction after placement new throws, this placement delete is being called. -template -PX_INLINE void operator delete [](void* ptr, physx::shdfnd::ReflectionAllocator alloc, const char* fileName, - typename physx::shdfnd::EnableIfPod::Type line) -{ - PX_UNUSED(fileName); - PX_UNUSED(line); - - alloc.deallocate(ptr); -} - -#endif // #ifndef PSFOUNDATION_PSALLOCATOR_H diff --git a/Source/ThirdParty/PhysX/foundation/Px.h b/Source/ThirdParty/PhysX/foundation/Px.h index e4e53415d..1d3dd4e74 100644 --- a/Source/ThirdParty/PhysX/foundation/Px.h +++ b/Source/ThirdParty/PhysX/foundation/Px.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PXFOUNDATION_PX_H -#define PXFOUNDATION_PX_H +#ifndef PX_H +#define PX_H /** \addtogroup foundation @{ @@ -56,14 +55,31 @@ class PxInputStream; class PxInputData; class PxOutputStream; -class PxVec2; -class PxVec3; -class PxVec4; -class PxMat33; -class PxMat44; +template class PxVec2T; +typedef PxVec2T PxVec2; + +template class PxVec3T; +typedef PxVec3T PxVec3; + +template class PxVec4T; +typedef PxVec4T PxVec4; + +template class PxQuatT; +typedef PxQuatT PxQuat; + +template class PxMat33T; +typedef PxMat33T PxMat33; + +template class PxMat34T; +typedef PxMat34T PxMat34; + +template class PxMat44T; +typedef PxMat44T PxMat44; + +template class PxTransformT; +typedef PxTransformT PxTransform; + class PxPlane; -class PxQuat; -class PxTransform; class PxBounds3; /** enum for empty constructor tag*/ @@ -89,4 +105,5 @@ enum PxIDENTITY #endif /** @} */ -#endif // #ifndef PXFOUNDATION_PX_H +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxAlignedMalloc.h b/Source/ThirdParty/PhysX/foundation/PxAlignedMalloc.h new file mode 100644 index 000000000..6e71f5988 --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxAlignedMalloc.h @@ -0,0 +1,89 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_ALIGNED_MALLOC_H +#define PX_ALIGNED_MALLOC_H + +#include "PxUserAllocated.h" + +/*! +Allocate aligned memory. +Alignment must be a power of 2! +-- should be templated by a base allocator +*/ + +#if !PX_DOXYGEN +namespace physx +{ +#endif + /** + Allocator, which is used to access the global PxAllocatorCallback instance + (used for dynamic data types template instantiation), which can align memory + */ + + // SCS: AlignedMalloc with 3 params not found, seems not used on PC either + // disabled for now to avoid GCC error + + template + class PxAlignedAllocator : public BaseAllocator + { + public: + PxAlignedAllocator(const BaseAllocator& base = BaseAllocator()) : BaseAllocator(base) + { + } + + void* allocate(size_t size, const char* file, int line) + { + size_t pad = N - 1 + sizeof(size_t); // store offset for delete. + uint8_t* base = reinterpret_cast(BaseAllocator::allocate(size + pad, file, line)); + if (!base) + return NULL; + + uint8_t* ptr = reinterpret_cast(size_t(base + pad) & ~(size_t(N) - 1)); // aligned pointer, ensuring N + // is a size_t + // wide mask + reinterpret_cast(ptr)[-1] = size_t(ptr - base); // store offset + + return ptr; + } + void deallocate(void* ptr) + { + if (ptr == NULL) + return; + + uint8_t* base = reinterpret_cast(ptr) - reinterpret_cast(ptr)[-1]; + BaseAllocator::deallocate(base); + } + }; + +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxAlloca.h b/Source/ThirdParty/PhysX/foundation/PxAlloca.h new file mode 100644 index 000000000..64c41515d --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxAlloca.h @@ -0,0 +1,93 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_ALLOCA_H +#define PX_ALLOCA_H + +#include "foundation/PxTempAllocator.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif +template +class PxScopedPointer : private Alloc +{ + public: + ~PxScopedPointer() + { + if(mOwned) + Alloc::deallocate(mPointer); + } + + operator T*() const + { + return mPointer; + } + + T* mPointer; + bool mOwned; +}; + +#if !PX_DOXYGEN +} // namespace physx +#endif + + // Don't use inline for alloca !!! +#if PX_WINDOWS_FAMILY +#include +#define PxAlloca(x) _alloca(x) +#elif PX_LINUX || PX_ANDROID +#include +#define PxAlloca(x) alloca(x) +#elif PX_APPLE_FAMILY +#include +#define PxAlloca(x) alloca(x) +#elif PX_PS4 || PX_PS5 +#include +#define PxAlloca(x) alloca(x) +#elif PX_SWITCH +#include +#define PxAlloca(x) alloca(x) +#endif + +#define PxAllocaAligned(x, alignment) ((size_t(PxAlloca(x + alignment)) + (alignment - 1)) & ~size_t(alignment - 1)) + +/*! Stack allocation for \c count instances of \c type. Falling back to temp allocator if using more than 1kB. */ +#define PX_ALLOCA(var, type, count) \ + physx::PxScopedPointer var; \ + { \ + uint32_t size = sizeof(type) * (count); \ + var.mOwned = size > 1024; \ + if(var.mOwned) \ + var.mPointer = reinterpret_cast(physx::PxTempAllocator().allocate(size, __FILE__, __LINE__)); \ + else \ + var.mPointer = reinterpret_cast(PxAlloca(size)); \ + } +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxAllocator.h b/Source/ThirdParty/PhysX/foundation/PxAllocator.h new file mode 100644 index 000000000..5fb41997d --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxAllocator.h @@ -0,0 +1,230 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_ALLOCATOR_H +#define PX_ALLOCATOR_H + +#include "foundation/PxAllocatorCallback.h" +#include "foundation/PxAssert.h" +#include "foundation/PxFoundation.h" +#include "foundation/Px.h" + +#if PX_VC +#pragma warning(push) +#pragma warning(disable : 4577) +#endif + +#if PX_WINDOWS_FAMILY + #include +#if(_MSC_VER >= 1923) + #include +#else + #include +#endif +#endif +#if(PX_APPLE_FAMILY) + #include +#endif + +#include + +#if PX_VC +#pragma warning(pop) +#endif + + +// PT: the rules are simple: +// - PX_ALLOC/PX_ALLOCATE/PX_FREE is similar to malloc/free. Use that for POD/anything that doesn't need ctor/dtor. +// - PX_NEW/PX_DELETE is similar to new/delete. Use that for anything that needs a ctor/dtor. +// - Everything goes through the user allocator. +// - Inherit from PxUserAllocated to PX_NEW something. Do it even on small classes, it's free. +// - You cannot PX_NEW a POD. Use PX_ALLOC. + +#define PX_ALLOC(n, name) physx::PxAllocator().allocate(n, __FILE__, __LINE__) + +// PT: use this one to reduce the amount of visible reinterpret_cast +#define PX_ALLOCATE(type, count, name) reinterpret_cast(PX_ALLOC(count*sizeof(type), name)) + +#define PX_FREE(x) \ + if(x) \ + { \ + physx::PxAllocator().deallocate(x); \ + x = NULL; \ + } + +#define PX_FREE_THIS physx::PxAllocator().deallocate(this) + +#define PX_NEW(T) new (physx::PxReflectionAllocator(), __FILE__, __LINE__) T +#define PX_PLACEMENT_NEW(p, T) new (p) T +#define PX_DELETE_THIS delete this +#define PX_DELETE(x) if(x) { delete x; x = NULL; } +#define PX_DELETE_ARRAY(x) if(x) { delete []x; x = NULL; } +#define PX_RELEASE(x) if(x) { x->release(); x = NULL; } + +#if !PX_DOXYGEN +namespace physx +{ +#endif + /** + Allocator used to access the global PxAllocatorCallback instance without providing additional information. + */ + class PxAllocator + { + public: + PX_FORCE_INLINE PxAllocator(const char* = NULL){} + + PX_FORCE_INLINE void* allocate(size_t size, const char* file, int line) + { + return size ? PxGetBroadcastAllocator()->allocate(size, "", file, line) : NULL; + } + + PX_FORCE_INLINE void deallocate(void* ptr) + { + if(ptr) + PxGetBroadcastAllocator()->deallocate(ptr); + } + }; + + /* + * Bootstrap allocator using malloc/free. + * Don't use unless your objects get allocated before foundation is initialized. + */ + class PxRawAllocator + { + public: + PxRawAllocator(const char* = 0) {} + + PX_FORCE_INLINE void* allocate(size_t size, const char*, int) + { + // malloc returns valid pointer for size==0, no need to check + return ::malloc(size); + } + + PX_FORCE_INLINE void deallocate(void* ptr) + { + // free(0) is guaranteed to have no side effect, no need to check + ::free(ptr); + } + }; + + /* + \brief Virtual allocator callback used to provide run-time defined allocators to foundation types like Array or Bitmap. + This is used by VirtualAllocator + */ + class PxVirtualAllocatorCallback + { + public: + PxVirtualAllocatorCallback() {} + virtual ~PxVirtualAllocatorCallback() {} + + virtual void* allocate(const size_t size, const int group, const char* file, const int line) = 0; + virtual void deallocate(void* ptr) = 0; + }; + + /* + \brief Virtual allocator to be used by foundation types to provide run-time defined allocators. + Due to the fact that Array extends its allocator, rather than contains a reference/pointer to it, the VirtualAllocator + must + be a concrete type containing a pointer to a virtual callback. The callback may not be available at instantiation time, + therefore + methods are provided to set the callback later. + */ + class PxVirtualAllocator + { + public: + PxVirtualAllocator(PxVirtualAllocatorCallback* callback = NULL, const int group = 0) : mCallback(callback), mGroup(group) {} + + PX_FORCE_INLINE void* allocate(const size_t size, const char* file, const int line) + { + PX_ASSERT(mCallback); + if (size) + return mCallback->allocate(size, mGroup, file, line); + return NULL; + } + + PX_FORCE_INLINE void deallocate(void* ptr) + { + PX_ASSERT(mCallback); + if (ptr) + mCallback->deallocate(ptr); + } + + private: + PxVirtualAllocatorCallback* mCallback; + const int mGroup; + PxVirtualAllocator& operator=(const PxVirtualAllocator&); + }; + + /** + Allocator used to access the global PxAllocatorCallback instance using a static name derived from T. + */ + template + class PxReflectionAllocator + { + static const char* getName() + { + if (!PxGetFoundation().getReportAllocationNames()) + return ""; +#if PX_GCC_FAMILY + return __PRETTY_FUNCTION__; +#else + // name() calls malloc(), raw_name() wouldn't + return typeid(T).name(); +#endif + } + + public: + PxReflectionAllocator(const PxEMPTY) {} + PxReflectionAllocator(const char* = 0) {} + + inline PxReflectionAllocator(const PxReflectionAllocator&) {} + + PX_FORCE_INLINE void* allocate(size_t size, const char* filename, int line) + { + return size ? PxGetBroadcastAllocator()->allocate(size, getName(), filename, line) : NULL; + } + + PX_FORCE_INLINE void deallocate(void* ptr) + { + if (ptr) + PxGetBroadcastAllocator()->deallocate(ptr); + } + }; + + template + struct PxAllocatorTraits + { + typedef PxReflectionAllocator Type; + }; + +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxAllocatorCallback.h b/Source/ThirdParty/PhysX/foundation/PxAllocatorCallback.h index 4e9487d80..c82ceb0d3 100644 --- a/Source/ThirdParty/PhysX/foundation/PxAllocatorCallback.h +++ b/Source/ThirdParty/PhysX/foundation/PxAllocatorCallback.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,17 +22,18 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PXFOUNDATION_PXALLOCATORCALLBACK_H -#define PXFOUNDATION_PXALLOCATORCALLBACK_H +#ifndef PX_ALLOCATOR_CALLBACK_H +#define PX_ALLOCATOR_CALLBACK_H /** \addtogroup foundation @{ */ +#include "foundation/PxFoundationConfig.h" #include "foundation/Px.h" #if !PX_DOXYGEN namespace physx @@ -52,9 +52,7 @@ or the physics processing thread(s). class PxAllocatorCallback { public: - /** - \brief destructor - */ + virtual ~PxAllocatorCallback() { } @@ -92,4 +90,5 @@ class PxAllocatorCallback #endif /** @} */ -#endif // #ifndef PXFOUNDATION_PXALLOCATORCALLBACK_H +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxSharedAssert.h b/Source/ThirdParty/PhysX/foundation/PxAoS.h similarity index 78% rename from Source/ThirdParty/PhysX/foundation/PxSharedAssert.h rename to Source/ThirdParty/PhysX/foundation/PxAoS.h index 1cb05cb2e..bb5e74807 100644 --- a/Source/ThirdParty/PhysX/foundation/PxSharedAssert.h +++ b/Source/ThirdParty/PhysX/foundation/PxAoS.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,24 +22,21 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PXFOUNDATION_PXASSERT_H -#define PXFOUNDATION_PXASSERT_H - -/** \addtogroup foundation -@{ */ +#ifndef PX_AOS_H +#define PX_AOS_H #include "foundation/Px.h" -#if !PX_ENABLE_ASSERTS - #define PX_SHARED_ASSERT(exp) ((void)0) +#if PX_WINDOWS && !PX_NEON +#include "windows/PxWindowsAoS.h" +#elif(PX_UNIX_FAMILY || PX_PS4 || PX_PS5 || PX_SWITCH) +#include "unix/PxUnixAoS.h" #else - #include - #define PX_SHARED_ASSERT(exp) assert(exp); -#endif // !PX_ENABLE_ASSERTS +#error "Platform not supported!" +#endif -/** @} */ -#endif // #ifndef PXFOUNDATION_PXASSERT_H +#endif diff --git a/Source/ThirdParty/PhysX/foundation/PxArray.h b/Source/ThirdParty/PhysX/foundation/PxArray.h new file mode 100644 index 000000000..5b636f891 --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxArray.h @@ -0,0 +1,721 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_ARRAY_H +#define PX_ARRAY_H + +#include "foundation/PxAssert.h" +#include "foundation/PxMathIntrinsics.h" +#include "foundation/PxAllocator.h" +#include "foundation/PxBasicTemplates.h" +#include "foundation/PxMemory.h" + +namespace physx +{ + +/*! +An array is a sequential container. + +Implementation note +* entries between 0 and size are valid objects +* we use inheritance to build this because the array is included inline in a lot + of objects and we want the allocator to take no space if it's not stateful, which + aggregation doesn't allow. Also, we want the metadata at the front for the inline + case where the allocator contains some inline storage space +*/ +template ::Type> +class PxArray : protected Alloc +{ + public: + typedef T* Iterator; + typedef const T* ConstIterator; + + explicit PxArray(const PxEMPTY v) : Alloc(v) + { + if(mData) + mCapacity |= PX_SIGN_BITMASK; + } + + /*! + Default array constructor. Initialize an empty array + */ + PX_INLINE explicit PxArray(const Alloc& alloc = Alloc()) : Alloc(alloc), mData(0), mSize(0), mCapacity(0) + { + } + + /*! + Initialize array with given capacity + */ + PX_INLINE explicit PxArray(uint32_t size, const T& a = T(), const Alloc& alloc = Alloc()) + : Alloc(alloc), mData(0), mSize(0), mCapacity(0) + { + resize(size, a); + } + + /*! + Copy-constructor. Copy all entries from other array + */ + template + PX_INLINE explicit PxArray(const PxArray& other, const Alloc& alloc = Alloc()) + : Alloc(alloc) + { + copy(other); + } + + // This is necessary else the basic default copy constructor is used in the case of both arrays being of the same + // template instance + // The C++ standard clearly states that a template constructor is never a copy constructor [2]. In other words, + // the presence of a template constructor does not suppress the implicit declaration of the copy constructor. + // Also never make a copy constructor explicit, or copy-initialization* will no longer work. This is because + // 'binding an rvalue to a const reference requires an accessible copy constructor' (http://gcc.gnu.org/bugs/) + // *http://stackoverflow.com/questions/1051379/is-there-a-difference-in-c-between-copy-initialization-and-assignment-initializ + PX_INLINE PxArray(const PxArray& other, const Alloc& alloc = Alloc()) : Alloc(alloc) + { + copy(other); + } + + /*! + Initialize array with given length + */ + PX_INLINE explicit PxArray(const T* first, const T* last, const Alloc& alloc = Alloc()) + : Alloc(alloc), mSize(last < first ? 0 : uint32_t(last - first)), mCapacity(mSize) + { + mData = allocate(mSize); + copy(mData, mData + mSize, first); + } + + /*! + Destructor + */ + PX_INLINE ~PxArray() + { + destroy(mData, mData + mSize); + + if(capacity() && !isInUserMemory()) + deallocate(mData); + } + + /*! + Assignment operator. Copy content (deep-copy) + */ + template + PX_INLINE PxArray& operator=(const PxArray& rhs) + { + if(&rhs == this) + return *this; + + clear(); + reserve(rhs.mSize); + copy(mData, mData + rhs.mSize, rhs.mData); + + mSize = rhs.mSize; + return *this; + } + + PX_INLINE PxArray& operator=(const PxArray& t) // Needs to be declared, see comment at copy-constructor + { + return operator=(t); + } + + /*! + Array indexing operator. + \param i + The index of the element that will be returned. + \return + The element i in the array. + */ + PX_FORCE_INLINE const T& operator[](uint32_t i) const + { + PX_ASSERT(i < mSize); + return mData[i]; + } + + /*! + Array indexing operator. + \param i + The index of the element that will be returned. + \return + The element i in the array. + */ + PX_FORCE_INLINE T& operator[](uint32_t i) + { + PX_ASSERT(i < mSize); + return mData[i]; + } + + /*! + Returns a pointer to the initial element of the array. + \return + a pointer to the initial element of the array. + */ + PX_FORCE_INLINE ConstIterator begin() const + { + return mData; + } + + PX_FORCE_INLINE Iterator begin() + { + return mData; + } + + /*! + Returns an iterator beyond the last element of the array. Do not dereference. + \return + a pointer to the element beyond the last element of the array. + */ + + PX_FORCE_INLINE ConstIterator end() const + { + return mData + mSize; + } + + PX_FORCE_INLINE Iterator end() + { + return mData + mSize; + } + + /*! + Returns a reference to the first element of the array. Undefined if the array is empty. + \return a reference to the first element of the array + */ + + PX_FORCE_INLINE const T& front() const + { + PX_ASSERT(mSize); + return mData[0]; + } + + PX_FORCE_INLINE T& front() + { + PX_ASSERT(mSize); + return mData[0]; + } + + /*! + Returns a reference to the last element of the array. Undefined if the array is empty + \return a reference to the last element of the array + */ + + PX_FORCE_INLINE const T& back() const + { + PX_ASSERT(mSize); + return mData[mSize - 1]; + } + + PX_FORCE_INLINE T& back() + { + PX_ASSERT(mSize); + return mData[mSize - 1]; + } + + /*! + Returns the number of entries in the array. This can, and probably will, + differ from the array capacity. + \return + The number of of entries in the array. + */ + PX_FORCE_INLINE uint32_t size() const + { + return mSize; + } + + /*! + Clears the array. + */ + PX_INLINE void clear() + { + destroy(mData, mData + mSize); + mSize = 0; + } + + /*! + Returns whether the array is empty (i.e. whether its size is 0). + \return + true if the array is empty + */ + PX_FORCE_INLINE bool empty() const + { + return mSize == 0; + } + + /*! + Finds the first occurrence of an element in the array. + \param a + The element to find. + */ + + PX_INLINE Iterator find(const T& a) + { + uint32_t index; + for(index = 0; index < mSize && mData[index] != a; index++) + ; + return mData + index; + } + + PX_INLINE ConstIterator find(const T& a) const + { + uint32_t index; + for(index = 0; index < mSize && mData[index] != a; index++) + ; + return mData + index; + } + + ///////////////////////////////////////////////////////////////////////// + /*! + Adds one element to the end of the array. Operation is O(1). + \param a + The element that will be added to this array. + */ + ///////////////////////////////////////////////////////////////////////// + + PX_FORCE_INLINE T& pushBack(const T& a) + { + if(capacity() <= mSize) + return growAndPushBack(a); + + PX_PLACEMENT_NEW(reinterpret_cast(mData + mSize), T)(a); + + return mData[mSize++]; + } + + ///////////////////////////////////////////////////////////////////////// + /*! + Returns the element at the end of the array. Only legal if the array is non-empty. + */ + ///////////////////////////////////////////////////////////////////////// + PX_INLINE T popBack() + { + PX_ASSERT(mSize); + T t = mData[mSize - 1]; + + mData[--mSize].~T(); + + return t; + } + + ///////////////////////////////////////////////////////////////////////// + /*! + Construct one element at the end of the array. Operation is O(1). + */ + ///////////////////////////////////////////////////////////////////////// + PX_INLINE T& insert() + { + if(capacity() <= mSize) + grow(capacityIncrement()); + + T* ptr = mData + mSize++; + PX_PLACEMENT_NEW(ptr, T); // not 'T()' because PODs should not get default-initialized. + return *ptr; + } + + ///////////////////////////////////////////////////////////////////////// + /*! + Subtracts the element on position i from the array and replace it with + the last element. + Operation is O(1) + \param i + The position of the element that will be subtracted from this array. + */ + ///////////////////////////////////////////////////////////////////////// + PX_INLINE void replaceWithLast(uint32_t i) + { + PX_ASSERT(i < mSize); + mData[i] = mData[--mSize]; + + mData[mSize].~T(); + } + + PX_INLINE void replaceWithLast(Iterator i) + { + replaceWithLast(static_cast(i - mData)); + } + + ///////////////////////////////////////////////////////////////////////// + /*! + Replaces the first occurrence of the element a with the last element + Operation is O(n) + \param a + The position of the element that will be subtracted from this array. + \return true if the element has been removed. + */ + ///////////////////////////////////////////////////////////////////////// + + PX_INLINE bool findAndReplaceWithLast(const T& a) + { + uint32_t index = 0; + while(index < mSize && mData[index] != a) + ++index; + if(index == mSize) + return false; + replaceWithLast(index); + return true; + } + + ///////////////////////////////////////////////////////////////////////// + /*! + Subtracts the element on position i from the array. Shift the entire + array one step. + Operation is O(n) + \param i + The position of the element that will be subtracted from this array. + */ + ///////////////////////////////////////////////////////////////////////// + PX_INLINE void remove(uint32_t i) + { + PX_ASSERT(i < mSize); + + T* it = mData + i; + it->~T(); + while (++i < mSize) + { + PX_PLACEMENT_NEW(it, T(mData[i])); + ++it; + it->~T(); + } + --mSize; + } + + ///////////////////////////////////////////////////////////////////////// + /*! + Removes a range from the array. Shifts the array so order is maintained. + Operation is O(n) + \param begin + The starting position of the element that will be subtracted from this array. + \param count + The number of elments that will be subtracted from this array. + */ + ///////////////////////////////////////////////////////////////////////// + PX_INLINE void removeRange(uint32_t begin, uint32_t count) + { + PX_ASSERT(begin < mSize); + PX_ASSERT((begin + count) <= mSize); + + for(uint32_t i = 0; i < count; i++) + mData[begin + i].~T(); // call the destructor on the ones being removed first. + + T* dest = &mData[begin]; // location we are copying the tail end objects to + T* src = &mData[begin + count]; // start of tail objects + uint32_t move_count = mSize - (begin + count); // compute remainder that needs to be copied down + + for(uint32_t i = 0; i < move_count; i++) + { + PX_PLACEMENT_NEW(dest, T(*src)); // copy the old one to the new location + src->~T(); // call the destructor on the old location + dest++; + src++; + } + mSize -= count; + } + + ////////////////////////////////////////////////////////////////////////// + /*! + Resize array + */ + ////////////////////////////////////////////////////////////////////////// + PX_NOINLINE void resize(const uint32_t size, const T& a = T()); + + PX_NOINLINE void resizeUninitialized(const uint32_t size); + + ////////////////////////////////////////////////////////////////////////// + /*! + Resize array such that only as much memory is allocated to hold the + existing elements + */ + ////////////////////////////////////////////////////////////////////////// + PX_INLINE void shrink() + { + recreate(mSize); + } + + ////////////////////////////////////////////////////////////////////////// + /*! + Deletes all array elements and frees memory. + */ + ////////////////////////////////////////////////////////////////////////// + PX_INLINE void reset() + { + resize(0); + shrink(); + } + + ////////////////////////////////////////////////////////////////////////// + /*! + Resets or clears the array depending on occupancy. + */ + ////////////////////////////////////////////////////////////////////////// + PX_INLINE void resetOrClear() + { + const PxU32 c = capacity(); + const PxU32 s = size(); + if(s>=c/2) + clear(); + else + reset(); + } + + ////////////////////////////////////////////////////////////////////////// + /*! + Ensure that the array has at least size capacity. + */ + ////////////////////////////////////////////////////////////////////////// + PX_INLINE void reserve(const uint32_t capacity) + { + if(capacity > this->capacity()) + grow(capacity); + } + + ////////////////////////////////////////////////////////////////////////// + /*! + Query the capacity(allocated mem) for the array. + */ + ////////////////////////////////////////////////////////////////////////// + PX_FORCE_INLINE uint32_t capacity() const + { + return mCapacity & ~PX_SIGN_BITMASK; + } + + ////////////////////////////////////////////////////////////////////////// + /*! + Unsafe function to force the size of the array + */ + ////////////////////////////////////////////////////////////////////////// + PX_FORCE_INLINE void forceSize_Unsafe(uint32_t size) + { + PX_ASSERT(size <= mCapacity); + mSize = size; + } + + ////////////////////////////////////////////////////////////////////////// + /*! + Swap contents of an array without allocating temporary storage + */ + ////////////////////////////////////////////////////////////////////////// + PX_INLINE void swap(PxArray& other) + { + PxSwap(mData, other.mData); + PxSwap(mSize, other.mSize); + PxSwap(mCapacity, other.mCapacity); + } + + ////////////////////////////////////////////////////////////////////////// + /*! + Assign a range of values to this vector (resizes to length of range) + */ + ////////////////////////////////////////////////////////////////////////// + PX_INLINE void assign(const T* first, const T* last) + { + resizeUninitialized(uint32_t(last - first)); + copy(begin(), end(), first); + } + + // We need one bit to mark arrays that have been deserialized from a user-provided memory block. + // For alignment & memory saving purpose we store that bit in the rarely used capacity member. + PX_FORCE_INLINE uint32_t isInUserMemory() const + { + return mCapacity & PX_SIGN_BITMASK; + } + + /// return reference to allocator + PX_INLINE Alloc& getAllocator() + { + return *this; + } + + protected: + // constructor for where we don't own the memory + PxArray(T* memory, uint32_t size, uint32_t capacity, const Alloc& alloc = Alloc()) + : Alloc(alloc), mData(memory), mSize(size), mCapacity(capacity | PX_SIGN_BITMASK) + { + } + + template + PX_NOINLINE void copy(const PxArray& other); + + PX_INLINE T* allocate(uint32_t size) + { + if(size > 0) + { + T* p = reinterpret_cast(Alloc::allocate(sizeof(T) * size, __FILE__, __LINE__)); + PxMarkSerializedMemory(p, sizeof(T) * size); + return p; + } + return 0; + } + + PX_INLINE void deallocate(void* mem) + { + Alloc::deallocate(mem); + } + + static PX_INLINE void create(T* first, T* last, const T& a) + { + for(; first < last; ++first) + ::PX_PLACEMENT_NEW(first, T(a)); + } + + static PX_INLINE void copy(T* first, T* last, const T* src) + { + if(last <= first) + return; + + for(; first < last; ++first, ++src) + ::PX_PLACEMENT_NEW(first, T(*src)); + } + + static PX_INLINE void destroy(T* first, T* last) + { + for(; first < last; ++first) + first->~T(); + } + + /*! + Called when pushBack() needs to grow the array. + \param a The element that will be added to this array. + */ + PX_NOINLINE T& growAndPushBack(const T& a); + + /*! + Resizes the available memory for the array. + + \param capacity + The number of entries that the set should be able to hold. + */ + PX_INLINE void grow(uint32_t capacity) + { + PX_ASSERT(this->capacity() < capacity); + recreate(capacity); + } + + /*! + Creates a new memory block, copies all entries to the new block and destroys old entries. + + \param capacity + The number of entries that the set should be able to hold. + */ + PX_NOINLINE void recreate(uint32_t capacity); + + // The idea here is to prevent accidental bugs with pushBack or insert. Unfortunately + // it interacts badly with InlineArrays with smaller inline allocations. + // TODO(dsequeira): policy template arg, this is exactly what they're for. + PX_INLINE uint32_t capacityIncrement() const + { + const uint32_t capacity = this->capacity(); + return capacity == 0 ? 1 : capacity * 2; + } + + T* mData; + uint32_t mSize; + uint32_t mCapacity; +}; + +template +PX_NOINLINE void PxArray::resize(const uint32_t size, const T& a) +{ + reserve(size); + create(mData + mSize, mData + size, a); + destroy(mData + size, mData + mSize); + mSize = size; +} + +template +template +PX_NOINLINE void PxArray::copy(const PxArray& other) +{ + if(!other.empty()) + { + mData = allocate(mSize = mCapacity = other.size()); + copy(mData, mData + mSize, other.begin()); + } + else + { + mData = NULL; + mSize = 0; + mCapacity = 0; + } + + // mData = allocate(other.mSize); + // mSize = other.mSize; + // mCapacity = other.mSize; + // copy(mData, mData + mSize, other.mData); +} + +template +PX_NOINLINE void PxArray::resizeUninitialized(const uint32_t size) +{ + reserve(size); + mSize = size; +} + +template +PX_NOINLINE T& PxArray::growAndPushBack(const T& a) +{ + uint32_t capacity = capacityIncrement(); + + T* newData = allocate(capacity); + PX_ASSERT((!capacity) || (newData && (newData != mData))); + copy(newData, newData + mSize, mData); + + // inserting element before destroying old array + // avoids referencing destroyed object when duplicating array element. + PX_PLACEMENT_NEW(reinterpret_cast(newData + mSize), T)(a); + + destroy(mData, mData + mSize); + if(!isInUserMemory()) + deallocate(mData); + + mData = newData; + mCapacity = capacity; + + return mData[mSize++]; +} + +template +PX_NOINLINE void PxArray::recreate(uint32_t capacity) +{ + T* newData = allocate(capacity); + PX_ASSERT((!capacity) || (newData && (newData != mData))); + + copy(newData, newData + mSize, mData); + destroy(mData, mData + mSize); + if(!isInUserMemory()) + deallocate(mData); + + mData = newData; + mCapacity = capacity; +} + +template +PX_INLINE void swap(PxArray& x, PxArray& y) +{ + x.swap(y); +} + +} // namespace physx + +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxAssert.h b/Source/ThirdParty/PhysX/foundation/PxAssert.h index 88309d53f..f1d4d2688 100644 --- a/Source/ThirdParty/PhysX/foundation/PxAssert.h +++ b/Source/ThirdParty/PhysX/foundation/PxAssert.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PX_FOUNDATION_PX_ASSERT_H -#define PX_FOUNDATION_PX_ASSERT_H +#ifndef PX_ASSERT_H +#define PX_ASSERT_H #include "foundation/PxFoundationConfig.h" #include "foundation/Px.h" @@ -42,7 +41,10 @@ namespace physx { #endif -/* Base class to handle assert failures */ +/** + * @brief Base class to handle assert failures + * @deprecated + */ class PX_DEPRECATED PxAssertHandler { public: @@ -52,9 +54,17 @@ class PX_DEPRECATED PxAssertHandler virtual void operator()(const char* exp, const char* file, int line, bool& ignore) = 0; }; +/** + * @deprecated + */ PX_FOUNDATION_API PX_DEPRECATED PxAssertHandler& PxGetAssertHandler(); + +/** + * @deprecated + */ PX_FOUNDATION_API PX_DEPRECATED void PxSetAssertHandler(PxAssertHandler& handler); + #if !PX_ENABLE_ASSERTS #define PX_ASSERT(exp) ((void)0) #define PX_ALWAYS_ASSERT_MESSAGE(exp) ((void)0) @@ -95,4 +105,5 @@ PX_FOUNDATION_API PX_DEPRECATED void PxSetAssertHandler(PxAssertHandler& handler /** @} */ -#endif // PX_FOUNDATION_PX_ASSERT_H +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxAtomic.h b/Source/ThirdParty/PhysX/foundation/PxAtomic.h new file mode 100644 index 000000000..5cf4a16fa --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxAtomic.h @@ -0,0 +1,65 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_ATOMIC_H +#define PX_ATOMIC_H + +#include "foundation/PxFoundationConfig.h" +#include "foundation/PxSimpleTypes.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif +/* set *dest equal to val. Return the old value of *dest */ +PX_FOUNDATION_API PxI32 PxAtomicExchange(volatile PxI32* dest, PxI32 val); + +/* if *dest == comp, replace with exch. Return original value of *dest */ +PX_FOUNDATION_API PxI32 PxAtomicCompareExchange(volatile PxI32* dest, PxI32 exch, PxI32 comp); + +/* if *dest == comp, replace with exch. Return original value of *dest */ +PX_FOUNDATION_API void* PxAtomicCompareExchangePointer(volatile void** dest, void* exch, void* comp); + +/* increment the specified location. Return the incremented value */ +PX_FOUNDATION_API PxI32 PxAtomicIncrement(volatile PxI32* val); + +/* decrement the specified location. Return the decremented value */ +PX_FOUNDATION_API PxI32 PxAtomicDecrement(volatile PxI32* val); + +/* add delta to *val. Return the new value */ +PX_FOUNDATION_API PxI32 PxAtomicAdd(volatile PxI32* val, PxI32 delta); + +/* compute the maximum of dest and val. Return the new value */ +PX_FOUNDATION_API PxI32 PxAtomicMax(volatile PxI32* val, PxI32 val2); + +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxBasicTemplates.h b/Source/ThirdParty/PhysX/foundation/PxBasicTemplates.h new file mode 100644 index 000000000..7243e5d8a --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxBasicTemplates.h @@ -0,0 +1,147 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_BASIC_TEMPLATES_H +#define PX_BASIC_TEMPLATES_H + +#include "foundation/PxPreprocessor.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + template + struct PxEqual + { + bool operator()(const A& a, const A& b) const + { + return a == b; + } + }; + + template + struct PxLess + { + bool operator()(const A& a, const A& b) const + { + return a < b; + } + }; + + template + struct PxGreater + { + bool operator()(const A& a, const A& b) const + { + return a > b; + } + }; + + template + class PxPair + { + public: + F first; + S second; + PX_CUDA_CALLABLE PxPair() : first(F()), second(S()) + { + } + PX_CUDA_CALLABLE PxPair(const F& f, const S& s) : first(f), second(s) + { + } + PX_CUDA_CALLABLE PxPair(const PxPair& p) : first(p.first), second(p.second) + { + } + // CN - fix for /.../PxBasicTemplates.h(61) : warning C4512: 'physx::PxPair' : assignment operator could + // not be generated + PX_CUDA_CALLABLE PxPair& operator=(const PxPair& p) + { + first = p.first; + second = p.second; + return *this; + } + PX_CUDA_CALLABLE bool operator==(const PxPair& p) const + { + return first == p.first && second == p.second; + } + PX_CUDA_CALLABLE bool operator<(const PxPair& p) const + { + if (first < p.first) + return true; + else + return !(p.first < first) && (second < p.second); + } + }; + + template + struct PxLogTwo + { + static const unsigned int value = PxLogTwo<(A >> 1)>::value + 1; + }; + template <> + struct PxLogTwo<1> + { + static const unsigned int value = 0; + }; + + template + struct PxUnConst + { + typedef T Type; + }; + template + struct PxUnConst + { + typedef T Type; + }; + + template + T PxPointerOffset(void* p, ptrdiff_t offset) + { + return reinterpret_cast(reinterpret_cast(p) + offset); + } + template + T PxPointerOffset(const void* p, ptrdiff_t offset) + { + return reinterpret_cast(reinterpret_cast(p) + offset); + } + + template + PX_CUDA_CALLABLE PX_INLINE void PxSwap(T& x, T& y) + { + const T tmp = x; + x = y; + y = tmp; + } + +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxBitAndData.h b/Source/ThirdParty/PhysX/foundation/PxBitAndData.h index e5692997c..38f937b4e 100644 --- a/Source/ThirdParty/PhysX/foundation/PxBitAndData.h +++ b/Source/ThirdParty/PhysX/foundation/PxBitAndData.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PXFOUNDATION_PXBITANDDATA_H -#define PXFOUNDATION_PXBITANDDATA_H +#ifndef PX_BIT_AND_DATA_H +#define PX_BIT_AND_DATA_H #include "foundation/Px.h" @@ -75,13 +74,14 @@ class PxBitAndDataT protected: storageType mData; }; -typedef PxBitAndDataT PxBitAndByte; -typedef PxBitAndDataT PxBitAndWord; -typedef PxBitAndDataT PxBitAndDword; +typedef PxBitAndDataT PxBitAndByte; +typedef PxBitAndDataT PxBitAndWord; +typedef PxBitAndDataT PxBitAndDword; #if !PX_DOXYGEN } // namespace physx #endif /** @} */ -#endif // PXFOUNDATION_PXBITANDDATA_H +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxBitMap.h b/Source/ThirdParty/PhysX/foundation/PxBitMap.h new file mode 100644 index 000000000..cb7ce9d17 --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxBitMap.h @@ -0,0 +1,480 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_BITMAP_H +#define PX_BITMAP_H + +#include "foundation/PxAssert.h" +#include "foundation/PxMath.h" +#include "foundation/PxMemory.h" +#include "foundation/PxAllocator.h" +#include "foundation/PxUserAllocated.h" +#include "foundation/PxIntrinsics.h" +#include "foundation/PxBitUtils.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + /*! + Hold a bitmap with operations to set,reset or test given bit. + + We inhibit copy to prevent unintentional copies. If a copy is desired copy() should be used or + alternatively a copy constructor implemented. + */ + template + class PxBitMapBase : public PxUserAllocated + { + //= ATTENTION! ===================================================================================== + // Changing the data layout of this class breaks the binary serialization format. See comments for + // PX_BINARY_SERIAL_VERSION. If a modification is required, please adjust the getBinaryMetaData + // function. If the modification is made on a custom branch, please change PX_BINARY_SERIAL_VERSION + // accordingly. + //================================================================================================== + + PX_NOCOPY(PxBitMapBase) + + public: + + // PX_SERIALIZATION + /* todo: explicit */ PxBitMapBase(const PxEMPTY) + { + if (mMap) + mWordCount |= PX_SIGN_BITMASK; + } + //~PX_SERIALIZATION + + PX_INLINE PxBitMapBase(const PxAllocator& allocator) : mMap(0), mWordCount(0), mAllocator(allocator) {} + + PX_INLINE PxBitMapBase() : mMap(0), mWordCount(0) {} + + PX_INLINE ~PxBitMapBase() + { + release(); + } + + PX_INLINE void release() + { + if (mMap && !isInUserMemory()) + mAllocator.deallocate(mMap); + mMap = NULL; + } + + PX_INLINE PxAllocator& getAllocator() { return mAllocator; } + + PX_INLINE void growAndSet(PxU32 index) + { + extend(index + 1); + mMap[index >> 5] |= 1 << (index & 31); + } + + PX_INLINE void growAndReset(PxU32 index) + { + extend(index + 1); + mMap[index >> 5] &= ~(1 << (index & 31)); + } + + PX_INLINE PxIntBool boundedTest(PxU32 index) const + { + return PxIntBool(index >> 5 >= getWordCount() ? PxIntFalse : (mMap[index >> 5] & (1 << (index & 31)))); + } + + PX_INLINE void boundedReset(PxU32 index) + { + if((index >> 5) < getWordCount()) + mMap[index >> 5] &= ~(1 << (index & 31)); + } + + // Special optimized versions, when you _know_ your index is in range + PX_INLINE void set(PxU32 index) + { + PX_ASSERT(index> 5] |= 1 << (index & 31); + } + + PX_INLINE void reset(PxU32 index) + { + PX_ASSERT(index> 5] &= ~(1 << (index & 31)); + } + + PX_INLINE PxIntBool test(PxU32 index) const + { + PX_ASSERT(index> 5] & (1 << (index & 31))); + } + + // nibble == 4 bits + PX_INLINE PxU32 getNibbleFast(PxU32 nibIndex) const + { + const PxU32 bitIndex = nibIndex << 2; + PX_ASSERT(bitIndex < getWordCount() * 32); + return (mMap[bitIndex >> 5] >> (bitIndex & 31)) & 0xf; + } + + PX_INLINE void andNibbleFast(PxU32 nibIndex, PxU32 mask) + { + //TODO: there has to be a faster way... + const PxU32 bitIndex = nibIndex << 2; + const PxU32 shift = (bitIndex & 31); + const PxU32 nibMask = (0xfu << shift); + + PX_ASSERT(bitIndex < getWordCount() * 32); + + mMap[bitIndex >> 5] &= ((mask << shift) | ~nibMask); + } + + PX_INLINE void orNibbleFast(PxU32 nibIndex, PxU32 mask) + { + PX_ASSERT(!(mask & ~0xfu)); //check extra bits are not set + + const PxU32 bitIndex = nibIndex << 2; + const PxU32 shift = bitIndex & 31; + + PX_ASSERT(bitIndex < getWordCount() * 32); + + mMap[bitIndex >> 5] |= (mask << shift); + } + + void clear() + { + PxMemSet(mMap, 0, getWordCount() * sizeof(PxU32)); + } + + void resizeAndClear(PxU32 newBitCount) + { + extendUninitialized(newBitCount); + PxMemSet(mMap, 0, getWordCount() * sizeof(PxU32)); + } + + void setEmpty() + { + mMap = NULL; + mWordCount = 0; + } + + void setWords(PxU32* map, PxU32 wordCount) + { + mMap = map; + mWordCount = wordCount; + mWordCount |= PX_SIGN_BITMASK; + } + + // !!! only sets /last/ bit to value + void resize(PxU32 newBitCount, bool value = false) + { + PX_ASSERT(!value); // only new class supports this + PX_UNUSED(value); + extend(newBitCount); + } + + PxU32 size() const { return getWordCount() * 32; } + + void copy(const PxBitMapBase& a) + { + extendUninitialized(a.getWordCount() << 5); + PxMemCopy(mMap, a.mMap, a.getWordCount() * sizeof(PxU32)); + if (getWordCount() > a.getWordCount()) + PxMemSet(mMap + a.getWordCount(), 0, (getWordCount() - a.getWordCount()) * sizeof(PxU32)); + } + + PX_INLINE PxU32 count() const + { + // NOTE: we can probably do this faster, since the last steps in PxcBitCount32 can be defered to + // the end of the seq. + 64/128bits at a time + native bit counting instructions(360 is fast non micro code). + PxU32 count = 0; + const PxU32 wordCount = getWordCount(); + for (PxU32 i = 0; i 0;) + { + if (mMap[i]) + return (i << 5) + PxHighestSetBit(mMap[i]); + } + return PxU32(0); + } + + // the obvious combiners and some used in the SDK + + struct OR { PX_INLINE PxU32 operator()(PxU32 a, PxU32 b) { return a | b; } }; + struct AND { PX_INLINE PxU32 operator()(PxU32 a, PxU32 b) { return a&b; } }; + struct XOR { PX_INLINE PxU32 operator()(PxU32 a, PxU32 b) { return a^b; } }; + + // we use auxiliary functions here so as not to generate combiners for every combination + // of allocators + + template + PX_INLINE void combineInPlace(const PxBitMapBase<_>& b) + { + combine1(b.mMap, b.getWordCount()); + } + + template + PX_INLINE void combine(const PxBitMapBase<_1>& a, const PxBitMapBase<_2>& b) + { + combine2(a.mMap, a.getWordCount(), b.mMap, b.getWordCount()); + } + + PX_FORCE_INLINE const PxU32* getWords() const { return mMap; } + PX_FORCE_INLINE PxU32* getWords() { return mMap; } + + // PX_SERIALIZATION + PX_FORCE_INLINE PxU32 getWordCount() const { return mWordCount & ~PX_SIGN_BITMASK; } + + // We need one bit to mark arrays that have been deserialized from a user-provided memory block. + PX_FORCE_INLINE PxU32 isInUserMemory() const { return mWordCount & PX_SIGN_BITMASK; } + //~PX_SERIALIZATION + + /*! + Iterate over indices in a bitmap + + This iterator is good because it finds the set bit without looping over the cached bits upto 31 times. + However it does require a variable shift. + */ + + class Iterator + { + public: + static const PxU32 DONE = 0xffffffff; + + PX_INLINE Iterator(const PxBitMapBase &map) : mBitMap(map) + { + reset(); + } + + PX_INLINE Iterator& operator=(const Iterator& other) + { + PX_ASSERT(&mBitMap == &other.mBitMap); + mBlock = other.mBlock; + mIndex = other.mIndex; + return *this; + } + + PX_INLINE PxU32 getNext() + { + if (mBlock) + { + PxU32 bitIndex = mIndex << 5 | PxLowestSetBit(mBlock); + mBlock &= mBlock - 1; + PxU32 wordCount = mBitMap.getWordCount(); + while (!mBlock && ++mIndex < wordCount) + mBlock = mBitMap.mMap[mIndex]; + return bitIndex; + } + return DONE; + } + + PX_INLINE void reset() + { + mIndex = mBlock = 0; + PxU32 wordCount = mBitMap.getWordCount(); + while (mIndex < wordCount && ((mBlock = mBitMap.mMap[mIndex]) == 0)) + ++mIndex; + } + private: + PxU32 mBlock, mIndex; + const PxBitMapBase& mBitMap; + }; + + // DS: faster but less general: hasBits() must be true or getNext() is illegal so it is the calling code's responsibility to ensure that getNext() is not called illegally. + class PxLoopIterator + { + PX_NOCOPY(PxLoopIterator) + + public: + PX_FORCE_INLINE PxLoopIterator(const PxBitMapBase &map) : mMap(map.getWords()), mBlock(0), mIndex(-1), mWordCount(PxI32(map.getWordCount())) {} + + PX_FORCE_INLINE bool hasBits() + { + PX_ASSERT(mIndex> 5; + if (newWordCount > getWordCount()) + { + PxU32* newMap = reinterpret_cast(mAllocator.allocate(newWordCount * sizeof(PxU32), __FILE__, __LINE__)); + if (mMap) + { + PxMemCopy(newMap, mMap, getWordCount() * sizeof(PxU32)); + if (!isInUserMemory()) + mAllocator.deallocate(mMap); + } + PxMemSet(newMap + getWordCount(), 0, (newWordCount - getWordCount()) * sizeof(PxU32)); + mMap = newMap; + // also resets the isInUserMemory bit + mWordCount = newWordCount; + } + } + + void extendUninitialized(PxU32 size) + { + PxU32 newWordCount = (size + 31) >> 5; + if (newWordCount > getWordCount()) + { + if (mMap && !isInUserMemory()) + mAllocator.deallocate(mMap); + // also resets the isInUserMemory bit + mWordCount = newWordCount; + mMap = reinterpret_cast(mAllocator.allocate(mWordCount * sizeof(PxU32), __FILE__, __LINE__)); + } + } + + template + void combine1(const PxU32* words, PxU32 length) + { + extend(length << 5); + PxU32 combineLength = PxMin(getWordCount(), length); + for (PxU32 i = 0; i + void combine2(const PxU32* words1, PxU32 length1, + const PxU32* words2, PxU32 length2) + { + extendUninitialized(PxMax(length1, length2) << 5); + + PxU32 commonSize = PxMin(length1, length2); + + for (PxU32 i = 0; i PxBitMap; + typedef PxBitMapBase PxBitMapPinned; +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif diff --git a/Source/ThirdParty/PhysX/foundation/PxBitUtils.h b/Source/ThirdParty/PhysX/foundation/PxBitUtils.h new file mode 100644 index 000000000..49942c171 --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxBitUtils.h @@ -0,0 +1,109 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_BIT_UTILS_H +#define PX_BIT_UTILS_H + +#include "foundation/PxMathIntrinsics.h" +#include "foundation/PxAssert.h" +#include "foundation/PxIntrinsics.h" +#include "foundation/PxMathIntrinsics.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif +PX_INLINE uint32_t PxBitCount(uint32_t v) +{ + // from http://graphics.stanford.edu/~seander/bithacks.html#CountBitsSetParallel + uint32_t const w = v - ((v >> 1) & 0x55555555); + uint32_t const x = (w & 0x33333333) + ((w >> 2) & 0x33333333); + return (((x + (x >> 4)) & 0xF0F0F0F) * 0x1010101) >> 24; +} + +PX_INLINE bool PxIsPowerOfTwo(uint32_t x) +{ + return x != 0 && (x & (x - 1)) == 0; +} + +// "Next Largest Power of 2 +// Given a binary integer value x, the next largest power of 2 can be computed by a SWAR algorithm +// that recursively "folds" the upper bits into the lower bits. This process yields a bit vector with +// the same most significant 1 as x, but all 1's below it. Adding 1 to that value yields the next +// largest power of 2. For a 32-bit value:" +PX_INLINE uint32_t PxNextPowerOfTwo(uint32_t x) +{ + x |= (x >> 1); + x |= (x >> 2); + x |= (x >> 4); + x |= (x >> 8); + x |= (x >> 16); + return x + 1; +} + +/*! +Return the index of the highest set bit. Not valid for zero arg. +*/ + +PX_INLINE uint32_t PxLowestSetBit(uint32_t x) +{ + PX_ASSERT(x); + return PxLowestSetBitUnsafe(x); +} + +/*! +Return the index of the highest set bit. Not valid for zero arg. +*/ + +PX_INLINE uint32_t PxHighestSetBit(uint32_t x) +{ + PX_ASSERT(x); + return PxHighestSetBitUnsafe(x); +} + +// Helper function to approximate log2 of an integer value +// assumes that the input is actually power of two. +PX_INLINE uint32_t PxILog2(uint32_t num) +{ + for(uint32_t i = 0; i < 32; i++) + { + num >>= 1; + if(num == 0) + return i; + } + + PX_ASSERT(0); + return uint32_t(-1); +} + +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxBounds3.h b/Source/ThirdParty/PhysX/foundation/PxBounds3.h index ef8ead25c..40d0ebe9b 100644 --- a/Source/ThirdParty/PhysX/foundation/PxBounds3.h +++ b/Source/ThirdParty/PhysX/foundation/PxBounds3.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PXFOUNDATION_PXBOUNDS3_H -#define PXFOUNDATION_PXBOUNDS3_H +#ifndef PX_BOUNDS3_H +#define PX_BOUNDS3_H /** \addtogroup foundation @{ @@ -71,6 +70,18 @@ class PxBounds3 */ PX_CUDA_CALLABLE PX_FORCE_INLINE PxBounds3(const PxVec3& minimum, const PxVec3& maximum); + PX_CUDA_CALLABLE PX_FORCE_INLINE void operator=(const PxBounds3& other) + { + minimum = other.minimum; + maximum = other.maximum; + } + + PX_CUDA_CALLABLE PX_FORCE_INLINE PxBounds3(const PxBounds3& other) + { + minimum = other.minimum; + maximum = other.maximum; + } + /** \brief Return empty bounds. */ @@ -93,8 +104,7 @@ class PxBounds3 /** \brief Construct from center, extent, and (not necessarily orthogonal) basis */ - static PX_CUDA_CALLABLE PX_INLINE PxBounds3 - basisExtent(const PxVec3& center, const PxMat33& basis, const PxVec3& extent); + static PX_CUDA_CALLABLE PX_INLINE PxBounds3 basisExtent(const PxVec3& center, const PxMat33& basis, const PxVec3& extent); /** \brief Construct from pose and extent @@ -257,6 +267,12 @@ class PxBounds3 */ PX_CUDA_CALLABLE PX_FORCE_INLINE bool isValid() const; + /** + Finds the closest point in the box to the point p. If p is contained, this will be p, otherwise it + will be the closest point on the surface of the box. + */ + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 closestPoint(const PxVec3& p) const; + PxVec3 minimum, maximum; }; @@ -289,15 +305,14 @@ PX_CUDA_CALLABLE PX_INLINE PxBounds3 PxBounds3::basisExtent(const PxVec3& center, const PxMat33& basis, const PxVec3& extent) { // extended basis vectors - PxVec3 c0 = basis.column0 * extent.x; - PxVec3 c1 = basis.column1 * extent.y; - PxVec3 c2 = basis.column2 * extent.z; + const PxVec3 c0 = basis.column0 * extent.x; + const PxVec3 c1 = basis.column1 * extent.y; + const PxVec3 c2 = basis.column2 * extent.z; - PxVec3 w; // find combination of base vectors that produces max. distance for each component = sum of abs() - w.x = PxAbs(c0.x) + PxAbs(c1.x) + PxAbs(c2.x); - w.y = PxAbs(c0.y) + PxAbs(c1.y) + PxAbs(c2.y); - w.z = PxAbs(c0.z) + PxAbs(c1.z) + PxAbs(c2.z); + const PxVec3 w( PxAbs(c0.x) + PxAbs(c1.x) + PxAbs(c2.x), + PxAbs(c0.y) + PxAbs(c1.y) + PxAbs(c2.y), + PxAbs(c0.z) + PxAbs(c1.z) + PxAbs(c2.z)); return PxBounds3(center - w, center + w); } @@ -321,40 +336,40 @@ PX_CUDA_CALLABLE PX_FORCE_INLINE void PxBounds3::setMaximal() PX_CUDA_CALLABLE PX_FORCE_INLINE void PxBounds3::include(const PxVec3& v) { - PX_SHARED_ASSERT(isValid()); + PX_ASSERT(isValid()); minimum = minimum.minimum(v); maximum = maximum.maximum(v); } PX_CUDA_CALLABLE PX_FORCE_INLINE void PxBounds3::include(const PxBounds3& b) { - PX_SHARED_ASSERT(isValid()); + PX_ASSERT(isValid()); minimum = minimum.minimum(b.minimum); maximum = maximum.maximum(b.maximum); } PX_CUDA_CALLABLE PX_FORCE_INLINE bool PxBounds3::isEmpty() const { - PX_SHARED_ASSERT(isValid()); + PX_ASSERT(isValid()); return minimum.x > maximum.x; } PX_CUDA_CALLABLE PX_FORCE_INLINE bool PxBounds3::intersects(const PxBounds3& b) const { - PX_SHARED_ASSERT(isValid() && b.isValid()); + PX_ASSERT(isValid() && b.isValid()); return !(b.minimum.x > maximum.x || minimum.x > b.maximum.x || b.minimum.y > maximum.y || minimum.y > b.maximum.y || b.minimum.z > maximum.z || minimum.z > b.maximum.z); } PX_CUDA_CALLABLE PX_FORCE_INLINE bool PxBounds3::intersects1D(const PxBounds3& a, uint32_t axis) const { - PX_SHARED_ASSERT(isValid() && a.isValid()); + PX_ASSERT(isValid() && a.isValid()); return maximum[axis] >= a.minimum[axis] && a.maximum[axis] >= minimum[axis]; } PX_CUDA_CALLABLE PX_FORCE_INLINE bool PxBounds3::contains(const PxVec3& v) const { - PX_SHARED_ASSERT(isValid()); + PX_ASSERT(isValid()); return !(v.x < minimum.x || v.x > maximum.x || v.y < minimum.y || v.y > maximum.y || v.z < minimum.z || v.z > maximum.z); @@ -362,7 +377,7 @@ PX_CUDA_CALLABLE PX_FORCE_INLINE bool PxBounds3::contains(const PxVec3& v) const PX_CUDA_CALLABLE PX_FORCE_INLINE bool PxBounds3::isInside(const PxBounds3& box) const { - PX_SHARED_ASSERT(isValid() && box.isValid()); + PX_ASSERT(isValid() && box.isValid()); if(box.minimum.x > minimum.x) return false; if(box.minimum.y > minimum.y) @@ -380,57 +395,57 @@ PX_CUDA_CALLABLE PX_FORCE_INLINE bool PxBounds3::isInside(const PxBounds3& box) PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 PxBounds3::getCenter() const { - PX_SHARED_ASSERT(isValid()); + PX_ASSERT(isValid()); return (minimum + maximum) * 0.5f; } PX_CUDA_CALLABLE PX_FORCE_INLINE float PxBounds3::getCenter(uint32_t axis) const { - PX_SHARED_ASSERT(isValid()); + PX_ASSERT(isValid()); return (minimum[axis] + maximum[axis]) * 0.5f; } PX_CUDA_CALLABLE PX_FORCE_INLINE float PxBounds3::getExtents(uint32_t axis) const { - PX_SHARED_ASSERT(isValid()); + PX_ASSERT(isValid()); return (maximum[axis] - minimum[axis]) * 0.5f; } PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 PxBounds3::getDimensions() const { - PX_SHARED_ASSERT(isValid()); + PX_ASSERT(isValid()); return maximum - minimum; } PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 PxBounds3::getExtents() const { - PX_SHARED_ASSERT(isValid()); + PX_ASSERT(isValid()); return getDimensions() * 0.5f; } PX_CUDA_CALLABLE PX_FORCE_INLINE void PxBounds3::scaleSafe(float scale) { - PX_SHARED_ASSERT(isValid()); + PX_ASSERT(isValid()); if(!isEmpty()) scaleFast(scale); } PX_CUDA_CALLABLE PX_FORCE_INLINE void PxBounds3::scaleFast(float scale) { - PX_SHARED_ASSERT(isValid()); + PX_ASSERT(isValid()); *this = centerExtents(getCenter(), getExtents() * scale); } PX_CUDA_CALLABLE PX_FORCE_INLINE void PxBounds3::fattenSafe(float distance) { - PX_SHARED_ASSERT(isValid()); + PX_ASSERT(isValid()); if(!isEmpty()) fattenFast(distance); } PX_CUDA_CALLABLE PX_FORCE_INLINE void PxBounds3::fattenFast(float distance) { - PX_SHARED_ASSERT(isValid()); + PX_ASSERT(isValid()); minimum.x -= distance; minimum.y -= distance; minimum.z -= distance; @@ -442,25 +457,25 @@ PX_CUDA_CALLABLE PX_FORCE_INLINE void PxBounds3::fattenFast(float distance) PX_CUDA_CALLABLE PX_INLINE PxBounds3 PxBounds3::transformSafe(const PxMat33& matrix, const PxBounds3& bounds) { - PX_SHARED_ASSERT(bounds.isValid()); + PX_ASSERT(bounds.isValid()); return !bounds.isEmpty() ? transformFast(matrix, bounds) : bounds; } PX_CUDA_CALLABLE PX_INLINE PxBounds3 PxBounds3::transformFast(const PxMat33& matrix, const PxBounds3& bounds) { - PX_SHARED_ASSERT(bounds.isValid()); + PX_ASSERT(bounds.isValid()); return PxBounds3::basisExtent(matrix * bounds.getCenter(), matrix, bounds.getExtents()); } PX_CUDA_CALLABLE PX_INLINE PxBounds3 PxBounds3::transformSafe(const PxTransform& transform, const PxBounds3& bounds) { - PX_SHARED_ASSERT(bounds.isValid()); + PX_ASSERT(bounds.isValid()); return !bounds.isEmpty() ? transformFast(transform, bounds) : bounds; } PX_CUDA_CALLABLE PX_INLINE PxBounds3 PxBounds3::transformFast(const PxTransform& transform, const PxBounds3& bounds) { - PX_SHARED_ASSERT(bounds.isValid()); + PX_ASSERT(bounds.isValid()); return PxBounds3::basisExtent(transform.transform(bounds.getCenter()), PxMat33(transform.q), bounds.getExtents()); } @@ -472,9 +487,15 @@ PX_CUDA_CALLABLE PX_FORCE_INLINE bool PxBounds3::isValid() const (maximum.y == -PX_MAX_BOUNDS_EXTENTS) && (maximum.z == -PX_MAX_BOUNDS_EXTENTS)))); } +PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 PxBounds3::closestPoint(const PxVec3& p) const +{ + return minimum.maximum(maximum.minimum(p)); +} + #if !PX_DOXYGEN } // namespace physx #endif /** @} */ -#endif // #ifndef PXFOUNDATION_PXBOUNDS3_H +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxBroadcast.h b/Source/ThirdParty/PhysX/foundation/PxBroadcast.h new file mode 100644 index 000000000..2d160896c --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxBroadcast.h @@ -0,0 +1,276 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_BROADCAST_H +#define PX_BROADCAST_H + +#include "foundation/PxInlineArray.h" +#include "foundation/PxSimpleTypes.h" +#include "foundation/PxErrorCallback.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +/** +\brief Abstract listener class that listens to allocation and deallocation events from the + foundation memory system. + +Threading: All methods of this class should be thread safe as it can be called from the user thread +or the physics processing thread(s). +*/ +class PxAllocationListener +{ + public: + /** + \brief callback when memory is allocated. + \param size Size of the allocation in bytes. + \param typeName Type this data is being allocated for. + \param filename File the allocation came from. + \param line the allocation came from. + \param allocatedMemory memory that will be returned from the allocation. + */ + virtual void onAllocation(size_t size, const char* typeName, const char* filename, int line, + void* allocatedMemory) = 0; + + /** + \brief callback when memory is deallocated. + \param allocatedMemory memory just before allocation. + */ + virtual void onDeallocation(void* allocatedMemory) = 0; + + protected: + virtual ~PxAllocationListener() + { + } +}; + +/** +\brief Broadcast class implementation, registering listeners. + +Threading: All methods of this class should be thread safe as it can be called from the user thread +or the physics processing thread(s). There is not internal locking +*/ +template +class PxBroadcast : public Base +{ + public: + static const uint32_t MAX_NB_LISTENERS = 16; + + /** + \brief The default constructor. + */ + PxBroadcast() + { + } + + /** + \brief Register new listener. + + \note It is NOT SAFE to register and deregister listeners while allocations may be taking place. + moreover, there is no thread safety to registration/deregistration. + + \param listener Listener to register. + */ + void registerListener(Listener& listener) + { + if(mListeners.size() < MAX_NB_LISTENERS) + mListeners.pushBack(&listener); + } + + /** + \brief Deregister an existing listener. + + \note It is NOT SAFE to register and deregister listeners while allocations may be taking place. + moreover, there is no thread safety to registration/deregistration. + + \param listener Listener to deregister. + */ + void deregisterListener(Listener& listener) + { + mListeners.findAndReplaceWithLast(&listener); + } + + /** + \brief Get number of registered listeners. + + \return Number of listeners. + */ + uint32_t getNbListeners() const + { + return mListeners.size(); + } + + /** + \brief Get an existing listener from given index. + + \param index Index of the listener. + \return Listener on given index. + */ + Listener& getListener(uint32_t index) + { + PX_ASSERT(index <= mListeners.size()); + return *mListeners[index]; + } + + protected: + virtual ~PxBroadcast() + { + } + + physx::PxInlineArray mListeners; +}; + +/** +\brief Abstract base class for an application defined memory allocator that allows an external listener +to audit the memory allocations. +*/ +class PxBroadcastingAllocator : public PxBroadcast +{ + PX_NOCOPY(PxBroadcastingAllocator) + + public: + /** + \brief The default constructor. + */ + PxBroadcastingAllocator(PxAllocatorCallback& allocator, PxErrorCallback& error) : mAllocator(allocator), mError(error) + { + mListeners.clear(); + } + + /** + \brief The default constructor. + */ + virtual ~PxBroadcastingAllocator() + { + mListeners.clear(); + } + + /** + \brief Allocates size bytes of memory, which must be 16-byte aligned. + + This method should never return NULL. If you run out of memory, then + you should terminate the app or take some other appropriate action. + + Threading: This function should be thread safe as it can be called in the context of the user thread + and physics processing thread(s). + + \param size Number of bytes to allocate. + \param typeName Name of the datatype that is being allocated + \param filename The source file which allocated the memory + \param line The source line which allocated the memory + \return The allocated block of memory. + */ + void* allocate(size_t size, const char* typeName, const char* filename, int line) + { + void* mem = mAllocator.allocate(size, typeName, filename, line); + + if(!mem) + { + mError.reportError(PxErrorCode::eABORT, "User allocator returned NULL.", __FILE__, __LINE__); + return NULL; + } + + if((size_t(mem) & 15)) + { + mError.reportError(PxErrorCode::eABORT, "Allocations must be 16-byte aligned.", __FILE__, __LINE__); + return NULL; + } + + for(uint32_t i = 0; i < mListeners.size(); i++) + mListeners[i]->onAllocation(size, typeName, filename, line, mem); + + return mem; + } + + /** + \brief Frees memory previously allocated by allocate(). + + Threading: This function should be thread safe as it can be called in the context of the user thread + and physics processing thread(s). + + \param ptr Memory to free. + */ + void deallocate(void* ptr) + { + for(uint32_t i = 0; i < mListeners.size(); i++) + { + mListeners[i]->onDeallocation(ptr); + } + mAllocator.deallocate(ptr); + } + + private: + PxAllocatorCallback& mAllocator; + PxErrorCallback& mError; +}; + +/** +\brief Abstract base class for an application defined error callback that allows an external listener +to report errors. +*/ +class PxBroadcastingErrorCallback : public PxBroadcast +{ + PX_NOCOPY(PxBroadcastingErrorCallback) + public: + /** + \brief The default constructor. + */ + PxBroadcastingErrorCallback(PxErrorCallback& errorCallback) + { + registerListener(errorCallback); + } + + /** + \brief The default destructor. + */ + virtual ~PxBroadcastingErrorCallback() + { + mListeners.clear(); + } + + /** + \brief Reports an error code. + \param code Error code, see #PxErrorCode + \param message Message to display. + \param file File error occured in. + \param line Line number error occured on. + */ + void reportError(PxErrorCode::Enum code, const char* message, const char* file, int line) + { + for(uint32_t i = 0; i < mListeners.size(); i++) + mListeners[i]->reportError(code, message, file, line); + } +}; +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxErrorCallback.h b/Source/ThirdParty/PhysX/foundation/PxErrorCallback.h index c0517dbef..3a9a52220 100644 --- a/Source/ThirdParty/PhysX/foundation/PxErrorCallback.h +++ b/Source/ThirdParty/PhysX/foundation/PxErrorCallback.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PXFOUNDATION_PXERRORCALLBACK_H -#define PXFOUNDATION_PXERRORCALLBACK_H +#ifndef PX_ERROR_CALLBACK_H +#define PX_ERROR_CALLBACK_H /** \addtogroup foundation @{ @@ -70,4 +69,5 @@ class PxErrorCallback #endif /** @} */ -#endif // #ifndef PXFOUNDATION_PXERRORCALLBACK_H +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxErrors.h b/Source/ThirdParty/PhysX/foundation/PxErrors.h index cf86d3ba5..17311daa9 100644 --- a/Source/ThirdParty/PhysX/foundation/PxErrors.h +++ b/Source/ThirdParty/PhysX/foundation/PxErrors.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PXFOUNDATION_PXERRORS_H -#define PXFOUNDATION_PXERRORS_H +#ifndef PX_ERRORS_H +#define PX_ERRORS_H /** \addtogroup foundation @{ */ @@ -47,7 +46,6 @@ These error codes are passed to #PxErrorCallback @see PxErrorCallback */ - struct PxErrorCode { enum Enum @@ -85,9 +83,50 @@ struct PxErrorCode }; }; +#if PX_CHECKED + #define PX_CHECK_MSG(exp, msg) (!!(exp) || (PxGetFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, PX_FL, msg), 0) ) + #define PX_CHECK_AND_RETURN(exp, msg) { if(!(exp)) { PxGetFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, PX_FL, msg); return; } } + #define PX_CHECK_AND_RETURN_NULL(exp, msg) { if(!(exp)) { PxGetFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, PX_FL, msg); return 0; } } + #define PX_CHECK_AND_RETURN_VAL(exp, msg, r) { if(!(exp)) { PxGetFoundation().error(physx::PxErrorCode::eINVALID_PARAMETER, PX_FL, msg); return r; } } +#else + #define PX_CHECK_MSG(exp, msg) + #define PX_CHECK_AND_RETURN(exp, msg) + #define PX_CHECK_AND_RETURN_NULL(exp, msg) + #define PX_CHECK_AND_RETURN_VAL(exp, msg, r) +#endif + +// shortcut macros: +// usage: PxGetFoundation().error(PX_WARN, "static friction %f is is lower than dynamic friction %d", sfr, dfr); +#define PX_WARN ::physx::PxErrorCode::eDEBUG_WARNING, PX_FL +#define PX_INFO ::physx::PxErrorCode::eDEBUG_INFO, PX_FL + +#if PX_DEBUG || PX_CHECKED + #define PX_WARN_ONCE(string) \ + { \ + static PxU32 timestamp = 0; \ + const PxU32 ts = PxGetWarnOnceTimeStamp(); \ + if(timestamp != ts) \ + { \ + timestamp = ts; \ + PxGetFoundation().error(PX_WARN, string); \ + } \ + } + #define PX_WARN_ONCE_IF(condition, string) \ + { \ + if(condition) \ + { \ + PX_WARN_ONCE(string) \ + } \ + } +#else + #define PX_WARN_ONCE(string) ((void)0) + #define PX_WARN_ONCE_IF(condition, string) ((void)0) +#endif + #if !PX_DOXYGEN } // namespace physx #endif /** @} */ -#endif // #ifndef PXFOUNDATION_PXERRORS_H +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxFPU.h b/Source/ThirdParty/PhysX/foundation/PxFPU.h new file mode 100644 index 000000000..f7668a6e4 --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxFPU.h @@ -0,0 +1,99 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_FPU_H +#define PX_FPU_H + +#include "foundation/PxIntrinsics.h" +#include "foundation/PxAssert.h" +#include "foundation/PxFoundationConfig.h" + +#define PX_IR(x) ((PxU32&)(x)) // integer representation of a floating-point value. +#define PX_SIR(x) ((PxI32&)(x)) // signed integer representation of a floating-point value. +#define PX_FR(x) ((PxReal&)(x)) // floating-point representation of a integer value. + +#define PX_FPU_GUARD PxFPUGuard scopedFpGuard; +#define PX_SIMD_GUARD PxSIMDGuard scopedFpGuard; +#define PX_SIMD_GUARD_CNDT(x) PxSIMDGuard scopedFpGuard(x); + +#if !PX_DOXYGEN +namespace physx +{ +#endif +// sets the default SDK state for scalar and SIMD units +class PX_FOUNDATION_API PxFPUGuard +{ + public: + PxFPUGuard(); // set fpu control word for PhysX + ~PxFPUGuard(); // restore fpu control word + private: + PxU32 mControlWords[8]; +}; + +// sets default SDK state for simd unit only, lighter weight than FPUGuard +class PxSIMDGuard +{ + public: + PX_INLINE PxSIMDGuard(bool enable = true); // set simd control word for PhysX + PX_INLINE ~PxSIMDGuard(); // restore simd control word + private: +#if !(PX_LINUX || PX_OSX) || (!PX_EMSCRIPTEN && PX_INTEL_FAMILY) + PxU32 mControlWord; + bool mEnabled; +#endif +}; + +/** +\brief Enables floating point exceptions for the scalar and SIMD unit +*/ +PX_FOUNDATION_API void PxEnableFPExceptions(); + +/** +\brief Disables floating point exceptions for the scalar and SIMD unit +*/ +PX_FOUNDATION_API void PxDisableFPExceptions(); + +#if !PX_DOXYGEN +} // namespace physx +#endif + +#if PX_WINDOWS_FAMILY +#include "foundation/windows/PxWindowsFPU.h" +#elif ((PX_LINUX || PX_OSX || PX_PS4 || PX_PS5) && PX_SSE2) +#include "foundation/unix/PxUnixFPU.h" +#else +PX_INLINE physx::PxSIMDGuard::PxSIMDGuard(bool) +{ +} +PX_INLINE physx::PxSIMDGuard::~PxSIMDGuard() +{ +} +#endif + +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxFlags.h b/Source/ThirdParty/PhysX/foundation/PxFlags.h index 85dce4ede..65d6ed2b8 100644 --- a/Source/ThirdParty/PhysX/foundation/PxFlags.h +++ b/Source/ThirdParty/PhysX/foundation/PxFlags.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PXFOUNDATION_PXFLAGS_H -#define PXFOUNDATION_PXFLAGS_H +#ifndef PX_FLAGS_H +#define PX_FLAGS_H /** \addtogroup foundation @{ @@ -83,8 +82,6 @@ class PxFlags PX_CUDA_CALLABLE PX_INLINE PxFlags(const PxFlags& f); PX_CUDA_CALLABLE PX_INLINE explicit PxFlags(storagetype b); - PX_CUDA_CALLABLE PX_INLINE bool isSet(enumtype e) const; - PX_CUDA_CALLABLE PX_INLINE PxFlags& set(enumtype e); PX_CUDA_CALLABLE PX_INLINE bool operator==(enumtype e) const; PX_CUDA_CALLABLE PX_INLINE bool operator==(const PxFlags& f) const; PX_CUDA_CALLABLE PX_INLINE bool operator==(bool b) const; @@ -117,6 +114,9 @@ class PxFlags PX_CUDA_CALLABLE PX_INLINE operator uint32_t(void) const; PX_CUDA_CALLABLE PX_INLINE void clear(enumtype e); + PX_CUDA_CALLABLE PX_INLINE void raise(enumtype e); + PX_CUDA_CALLABLE PX_INLINE bool isSet(enumtype e) const; + PX_CUDA_CALLABLE PX_INLINE PxFlags& setAll(enumtype e); public: friend PX_INLINE PxFlags operator&(enumtype a, PxFlags& b) @@ -132,26 +132,26 @@ class PxFlags #if !PX_DOXYGEN -#define PX_FLAGS_OPERATORS(enumtype, storagetype) \ - PX_CUDA_CALLABLE PX_INLINE PxFlags operator|(enumtype a, enumtype b) \ - { \ - PxFlags r(a); \ - r |= b; \ - return r; \ - } \ - PX_CUDA_CALLABLE PX_INLINE PxFlags operator&(enumtype a, enumtype b) \ - { \ - PxFlags r(a); \ - r &= b; \ - return r; \ - } \ - PX_CUDA_CALLABLE PX_INLINE PxFlags operator~(enumtype a) \ - { \ - return ~PxFlags(a); \ +#define PX_FLAGS_OPERATORS(enumtype, storagetype) \ + PX_CUDA_CALLABLE PX_INLINE PxFlags operator|(enumtype a, enumtype b) \ + { \ + PxFlags r(a); \ + r |= b; \ + return r; \ + } \ + PX_CUDA_CALLABLE PX_INLINE PxFlags operator&(enumtype a, enumtype b) \ + { \ + PxFlags r(a); \ + r &= b; \ + return r; \ + } \ + PX_CUDA_CALLABLE PX_INLINE PxFlags operator~(enumtype a) \ + { \ + return ~PxFlags(a); \ } -#define PX_FLAGS_TYPEDEF(x, y) \ - typedef PxFlags x##s; \ +#define PX_FLAGS_TYPEDEF(x, y) \ + typedef PxFlags x##s; \ PX_FLAGS_OPERATORS(x::Enum, y) template @@ -178,19 +178,6 @@ PX_CUDA_CALLABLE PX_INLINE PxFlags::PxFlags(storagetype b mBits = b; } -template -PX_CUDA_CALLABLE PX_INLINE bool PxFlags::isSet(enumtype e) const -{ - return (mBits & static_cast(e)) == static_cast(e); -} - -template -PX_CUDA_CALLABLE PX_INLINE PxFlags& PxFlags::set(enumtype e) -{ - mBits = static_cast(e); - return *this; -} - template PX_CUDA_CALLABLE PX_INLINE bool PxFlags::operator==(enumtype e) const { @@ -369,8 +356,28 @@ PX_CUDA_CALLABLE PX_INLINE void PxFlags::clear(enumtype e mBits &= ~static_cast(e); } +template +PX_CUDA_CALLABLE PX_INLINE void PxFlags::raise(enumtype e) +{ + mBits |= static_cast(e); +} + +template +PX_CUDA_CALLABLE PX_INLINE bool PxFlags::isSet(enumtype e) const +{ + return (mBits & static_cast(e)) == static_cast(e); +} + +template +PX_CUDA_CALLABLE PX_INLINE PxFlags& PxFlags::setAll(enumtype e) +{ + mBits = static_cast(e); + return *this; +} + } // namespace physx #endif //!PX_DOXYGEN /** @} */ -#endif // #ifndef PXFOUNDATION_PXFLAGS_H +#endif + diff --git a/Source/ThirdParty/PhysX/PxFoundation.h b/Source/ThirdParty/PhysX/foundation/PxFoundation.h similarity index 64% rename from Source/ThirdParty/PhysX/PxFoundation.h rename to Source/ThirdParty/PhysX/foundation/PxFoundation.h index 4a4a14dfd..c103b2d55 100644 --- a/Source/ThirdParty/PhysX/PxFoundation.h +++ b/Source/ThirdParty/PhysX/foundation/PxFoundation.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PX_FOUNDATION_PX_FOUNDATION_H -#define PX_FOUNDATION_PX_FOUNDATION_H +#ifndef PX_FOUNDATION_H +#define PX_FOUNDATION_H /** \addtogroup foundation @{ @@ -37,12 +36,18 @@ #include "foundation/Px.h" #include "foundation/PxErrors.h" #include "foundation/PxFoundationConfig.h" +#include "foundation/PxErrors.h" + +#include #if !PX_DOXYGEN namespace physx { #endif +class PxAllocationListener; +class PxErrorCallback; + /** \brief Foundation SDK singleton class. @@ -55,8 +60,7 @@ class PX_FOUNDATION_API PxFoundation \brief Destroys the instance it is called on. The operation will fail, if there are still modules referencing the foundation object. Release all dependent modules - prior - to calling this method. + prior to calling this method. @see PxCreateFoundation() */ @@ -93,6 +97,18 @@ class PX_FOUNDATION_API PxFoundation */ virtual void setReportAllocationNames(bool value) = 0; + virtual void registerAllocationListener(PxAllocationListener& listener) = 0; + + virtual void deregisterAllocationListener(PxAllocationListener& listener) = 0; + + virtual void registerErrorCallback(PxErrorCallback& callback) = 0; + + virtual void deregisterErrorCallback(PxErrorCallback& callback) = 0; + + virtual bool error(PxErrorCode::Enum c, const char* file, int line, const char* messageFmt, ...) = 0; + + virtual bool error(PxErrorCode::Enum, const char* file, int line, const char* messageFmt, va_list) = 0; + protected: virtual ~PxFoundation() { @@ -103,6 +119,15 @@ class PX_FOUNDATION_API PxFoundation } // namespace physx #endif +// PT: use this to make generated code shorter (e.g. from 52 to 24 bytes of assembly (10 to 4 instructions)) +// We must use a macro here to let __FILE__ expand to the proper filename (it doesn't work with an inlined function). +#define PX_IMPLEMENT_OUTPUT_ERROR \ +template \ +static PX_NOINLINE bool outputError(int line, const char* message) \ +{ \ + return PxGetFoundation().error(PxErrorCode::Enum(errorCode), __FILE__, line, message); \ +} + /** \brief Creates an instance of the foundation class @@ -117,9 +142,12 @@ returned. @see PxFoundation */ +PX_C_EXPORT PX_FOUNDATION_API physx::PxFoundation* PX_CALL_CONV PxCreateFoundation(physx::PxU32 version, physx::PxAllocatorCallback& allocator, physx::PxErrorCallback& errorCallback); + + +PX_C_EXPORT PX_FOUNDATION_API void PX_CALL_CONV PxSetFoundationInstance(physx::PxFoundation& foundation); + -PX_C_EXPORT PX_FOUNDATION_API physx::PxFoundation* PX_CALL_CONV -PxCreateFoundation(physx::PxU32 version, physx::PxAllocatorCallback& allocator, physx::PxErrorCallback& errorCallback); /** \brief Retrieves the Foundation SDK after it has been created. @@ -140,10 +168,16 @@ PX_C_EXPORT PX_FOUNDATION_API physx::PxFoundation& PX_CALL_CONV PxGetFoundation( #endif // PX_LINUX #endif // PX_CLANG +#if !PX_DOXYGEN namespace physx { +#endif class PxProfilerCallback; -} +class PxAllocatorCallback; +class PxErrorCallback; +#if !PX_DOXYGEN +} // namespace physx +#endif /** \brief Get the callback that will be used for all profiling. @@ -155,5 +189,41 @@ PX_C_EXPORT PX_FOUNDATION_API physx::PxProfilerCallback* PX_CALL_CONV PxGetProfi */ PX_C_EXPORT PX_FOUNDATION_API void PX_CALL_CONV PxSetProfilerCallback(physx::PxProfilerCallback* profiler); +/** +\brief Get the allocator callback +*/ +PX_C_EXPORT PX_FOUNDATION_API physx::PxAllocatorCallback* PX_CALL_CONV PxGetAllocatorCallback(); + +/** +\brief Get the broadcasting allocator callback +*/ +PX_C_EXPORT PX_FOUNDATION_API physx::PxAllocatorCallback* PX_CALL_CONV PxGetBroadcastAllocator(); + +/** +\brief Get the error callback +*/ +PX_C_EXPORT PX_FOUNDATION_API physx::PxErrorCallback* PX_CALL_CONV PxGetErrorCallback(); + +/** +\brief Get the broadcasting error callback +*/ +PX_C_EXPORT PX_FOUNDATION_API physx::PxErrorCallback* PX_CALL_CONV PxGetBroadcastError(); + +/** +\brief Get the warn once timestamp +*/ +PX_C_EXPORT PX_FOUNDATION_API physx::PxU32 PX_CALL_CONV PxGetWarnOnceTimeStamp(); + +/** +\brief Decrement the ref count of PxFoundation +*/ +PX_C_EXPORT PX_FOUNDATION_API void PX_CALL_CONV PxDecFoundationRefCount(); + +/** +\brief Increment the ref count of PxFoundation +*/ +PX_C_EXPORT PX_FOUNDATION_API void PX_CALL_CONV PxIncFoundationRefCount(); + /** @} */ -#endif // PX_FOUNDATION_PX_FOUNDATION_H +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxFoundationConfig.h b/Source/ThirdParty/PhysX/foundation/PxFoundationConfig.h index a2e74ecea..cae286da4 100644 --- a/Source/ThirdParty/PhysX/foundation/PxFoundationConfig.h +++ b/Source/ThirdParty/PhysX/foundation/PxFoundationConfig.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PX_FOUNDATION_PX_FOUNDATION_CONFIG_H -#define PX_FOUNDATION_PX_FOUNDATION_CONFIG_H +#ifndef PX_FOUNDATION_CONFIG_H +#define PX_FOUNDATION_CONFIG_H #include "foundation/PxPreprocessor.h" @@ -39,7 +38,7 @@ #if defined PX_PHYSX_STATIC_LIB #define PX_FOUNDATION_API #else - #if (PX_WINDOWS_FAMILY || PX_XBOXONE || PX_PS4) && !defined(__CUDACC__) + #if (PX_WINDOWS_FAMILY || PX_PS4 || PX_PS5) && !defined(__CUDACC__) #if defined PX_PHYSX_FOUNDATION_EXPORTS #define PX_FOUNDATION_API __declspec(dllexport) #else @@ -54,4 +53,4 @@ /** @} */ -#endif // PX_FOUNDATION_PX_ASSERT_H +#endif diff --git a/Source/ThirdParty/PhysX/foundation/PxHash.h b/Source/ThirdParty/PhysX/foundation/PxHash.h new file mode 100644 index 000000000..43ea55215 --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxHash.h @@ -0,0 +1,163 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_HASH_H +#define PX_HASH_H + +#include "foundation/PxBasicTemplates.h" +#include "foundation/PxString.h" + +#if PX_VC +#pragma warning(push) +#pragma warning(disable : 4302) +#endif + +#if PX_LINUX +#include "foundation/PxSimpleTypes.h" +#endif + +/*! +Central definition of hash functions +*/ + +#if !PX_DOXYGEN +namespace physx +{ +#endif +// Hash functions + +// Thomas Wang's 32 bit mix +// http://www.cris.com/~Ttwang/tech/inthash.htm +PX_FORCE_INLINE uint32_t PxComputeHash(const uint32_t key) +{ + uint32_t k = key; + k += ~(k << 15); + k ^= (k >> 10); + k += (k << 3); + k ^= (k >> 6); + k += ~(k << 11); + k ^= (k >> 16); + return uint32_t(k); +} + +PX_FORCE_INLINE uint32_t PxComputeHash(const int32_t key) +{ + return PxComputeHash(uint32_t(key)); +} + +// Thomas Wang's 64 bit mix +// http://www.cris.com/~Ttwang/tech/inthash.htm +PX_FORCE_INLINE uint32_t PxComputeHash(const uint64_t key) +{ + uint64_t k = key; + k += ~(k << 32); + k ^= (k >> 22); + k += ~(k << 13); + k ^= (k >> 8); + k += (k << 3); + k ^= (k >> 15); + k += ~(k << 27); + k ^= (k >> 31); + return uint32_t(UINT32_MAX & k); +} + +#if PX_APPLE_FAMILY +// hash for size_t, to make gcc happy +PX_INLINE uint32_t PxComputeHash(const size_t key) +{ +#if PX_P64_FAMILY + return PxComputeHash(uint64_t(key)); +#else + return PxComputeHash(uint32_t(key)); +#endif +} +#endif + +// Hash function for pointers +PX_INLINE uint32_t PxComputeHash(const void* ptr) +{ +#if PX_P64_FAMILY + return PxComputeHash(uint64_t(ptr)); +#else + return PxComputeHash(uint32_t(UINT32_MAX & size_t(ptr))); +#endif +} + +// Hash function for pairs +template +PX_INLINE uint32_t PxComputeHash(const PxPair& p) +{ + uint32_t seed = 0x876543; + uint32_t m = 1000007; + return PxComputeHash(p.second) ^ (m * (PxComputeHash(p.first) ^ (m * seed))); +} + +// hash object for hash map template parameter +template +struct PxHash +{ + uint32_t operator()(const Key& k) const + { + return PxComputeHash(k); + } + bool equal(const Key& k0, const Key& k1) const + { + return k0 == k1; + } +}; + +// specialization for strings +template <> +struct PxHash +{ + public: + uint32_t operator()(const char* _string) const + { + // "DJB" string hash + const uint8_t* string = reinterpret_cast(_string); + uint32_t h = 5381; + for(const uint8_t* ptr = string; *ptr; ptr++) + h = ((h << 5) + h) ^ uint32_t(*ptr); + return h; + } + bool equal(const char* string0, const char* string1) const + { + return !Pxstrcmp(string0, string1); + } +}; + +#if !PX_DOXYGEN +} // namespace physx +#endif + +#if PX_VC +#pragma warning(pop) +#endif + +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxHashInternals.h b/Source/ThirdParty/PhysX/foundation/PxHashInternals.h new file mode 100644 index 000000000..024084da2 --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxHashInternals.h @@ -0,0 +1,792 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_HASH_INTERNALS_H +#define PX_HASH_INTERNALS_H + +#include "foundation/PxAllocator.h" +#include "foundation/PxBitUtils.h" +#include "foundation/PxMathIntrinsics.h" +#include "foundation/PxBasicTemplates.h" +#include "foundation/PxHash.h" + +#if PX_VC +#pragma warning(push) +#pragma warning(disable : 4127) // conditional expression is constant +#endif +#if !PX_DOXYGEN +namespace physx +{ +#endif +template +class PxHashBase : private PxAllocator +{ + void init(uint32_t initialTableSize, float loadFactor) + { + mBuffer = NULL; + mEntries = NULL; + mEntriesNext = NULL; + mHash = NULL; + mEntriesCapacity = 0; + mHashSize = 0; + mLoadFactor = loadFactor; + mFreeList = uint32_t(EOL); + mTimestamp = 0; + mEntriesCount = 0; + + if(initialTableSize) + reserveInternal(initialTableSize); + } + + public: + typedef Entry EntryType; + + PxHashBase(uint32_t initialTableSize = 64, float loadFactor = 0.75f) : PxAllocator("hashBase") + { + init(initialTableSize, loadFactor); + } + + PxHashBase(uint32_t initialTableSize, float loadFactor, const PxAllocator& alloc) : PxAllocator(alloc) + { + init(initialTableSize, loadFactor); + } + + PxHashBase(const PxAllocator& alloc) : PxAllocator(alloc) + { + init(64, 0.75f); + } + + ~PxHashBase() + { + destroy(); // No need to clear() + + if(mBuffer) + PxAllocator::deallocate(mBuffer); + } + + static const uint32_t EOL = 0xffffffff; + + PX_INLINE Entry* create(const Key& k, bool& exists) + { + uint32_t h = 0; + if(mHashSize) + { + h = hash(k); + uint32_t index = mHash[h]; + while(index != EOL && !HashFn().equal(GetKey()(mEntries[index]), k)) + index = mEntriesNext[index]; + exists = index != EOL; + if(exists) + return mEntries + index; + } + else + exists = false; + + if(freeListEmpty()) + { + grow(); + h = hash(k); + } + + uint32_t entryIndex = freeListGetNext(); + + mEntriesNext[entryIndex] = mHash[h]; + mHash[h] = entryIndex; + + mEntriesCount++; + mTimestamp++; + + return mEntries + entryIndex; + } + + PX_INLINE const Entry* find(const Key& k) const + { + if(!mEntriesCount) + return NULL; + + const uint32_t h = hash(k); + uint32_t index = mHash[h]; + while(index != EOL && !HashFn().equal(GetKey()(mEntries[index]), k)) + index = mEntriesNext[index]; + return index != EOL ? mEntries + index : NULL; + } + + PX_INLINE bool erase(const Key& k, Entry& e) + { + if(!mEntriesCount) + return false; + + const uint32_t h = hash(k); + uint32_t* ptr = mHash + h; + while(*ptr != EOL && !HashFn().equal(GetKey()(mEntries[*ptr]), k)) + ptr = mEntriesNext + *ptr; + + if(*ptr == EOL) + return false; + + PX_PLACEMENT_NEW(&e, Entry)(mEntries[*ptr]); + + return eraseInternal(ptr); + } + + PX_INLINE bool erase(const Key& k) + { + if(!mEntriesCount) + return false; + + const uint32_t h = hash(k); + uint32_t* ptr = mHash + h; + while(*ptr != EOL && !HashFn().equal(GetKey()(mEntries[*ptr]), k)) + ptr = mEntriesNext + *ptr; + + if(*ptr == EOL) + return false; + + return eraseInternal(ptr); + } + + PX_INLINE uint32_t size() const + { + return mEntriesCount; + } + + PX_INLINE uint32_t capacity() const + { + return mHashSize; + } + + void clear() + { + if(!mHashSize || mEntriesCount == 0) + return; + + destroy(); + + intrinsics::memSet(mHash, EOL, mHashSize * sizeof(uint32_t)); + + const uint32_t sizeMinus1 = mEntriesCapacity - 1; + for(uint32_t i = 0; i < sizeMinus1; i++) + { + PxPrefetchLine(mEntriesNext + i, 128); + mEntriesNext[i] = i + 1; + } + mEntriesNext[mEntriesCapacity - 1] = uint32_t(EOL); + mFreeList = 0; + mEntriesCount = 0; + } + + void reserve(uint32_t size) + { + if(size > mHashSize) + reserveInternal(size); + } + + PX_INLINE const Entry* getEntries() const + { + return mEntries; + } + + PX_INLINE Entry* insertUnique(const Key& k) + { + PX_ASSERT(find(k) == NULL); + uint32_t h = hash(k); + + uint32_t entryIndex = freeListGetNext(); + + mEntriesNext[entryIndex] = mHash[h]; + mHash[h] = entryIndex; + + mEntriesCount++; + mTimestamp++; + + return mEntries + entryIndex; + } + + private: + void destroy() + { + for(uint32_t i = 0; i < mHashSize; i++) + { + for(uint32_t j = mHash[i]; j != EOL; j = mEntriesNext[j]) + mEntries[j].~Entry(); + } + } + + template + PX_NOINLINE void copy(const PxHashBase& other); + + // free list management - if we're coalescing, then we use mFreeList to hold + // the top of the free list and it should always be equal to size(). Otherwise, + // we build a free list in the next() pointers. + + PX_INLINE void freeListAdd(uint32_t index) + { + if(compacting) + { + mFreeList--; + PX_ASSERT(mFreeList == mEntriesCount); + } + else + { + mEntriesNext[index] = mFreeList; + mFreeList = index; + } + } + + PX_INLINE void freeListAdd(uint32_t start, uint32_t end) + { + if(!compacting) + { + for(uint32_t i = start; i < end - 1; i++) // add the new entries to the free list + mEntriesNext[i] = i + 1; + + // link in old free list + mEntriesNext[end - 1] = mFreeList; + PX_ASSERT(mFreeList != end - 1); + mFreeList = start; + } + else if(mFreeList == EOL) // don't reset the free ptr for the compacting hash unless it's empty + mFreeList = start; + } + + PX_INLINE uint32_t freeListGetNext() + { + PX_ASSERT(!freeListEmpty()); + if(compacting) + { + PX_ASSERT(mFreeList == mEntriesCount); + return mFreeList++; + } + else + { + uint32_t entryIndex = mFreeList; + mFreeList = mEntriesNext[mFreeList]; + return entryIndex; + } + } + + PX_INLINE bool freeListEmpty() const + { + if(compacting) + return mEntriesCount == mEntriesCapacity; + else + return mFreeList == EOL; + } + + PX_INLINE void replaceWithLast(uint32_t index) + { + PX_PLACEMENT_NEW(mEntries + index, Entry)(mEntries[mEntriesCount]); + mEntries[mEntriesCount].~Entry(); + mEntriesNext[index] = mEntriesNext[mEntriesCount]; + + uint32_t h = hash(GetKey()(mEntries[index])); + uint32_t* ptr; + for(ptr = mHash + h; *ptr != mEntriesCount; ptr = mEntriesNext + *ptr) + PX_ASSERT(*ptr != EOL); + *ptr = index; + } + + PX_INLINE uint32_t hash(const Key& k, uint32_t hashSize) const + { + return HashFn()(k) & (hashSize - 1); + } + + PX_INLINE uint32_t hash(const Key& k) const + { + return hash(k, mHashSize); + } + + PX_INLINE bool eraseInternal(uint32_t* ptr) + { + const uint32_t index = *ptr; + + *ptr = mEntriesNext[index]; + + mEntries[index].~Entry(); + + mEntriesCount--; + mTimestamp++; + + if (compacting && index != mEntriesCount) + replaceWithLast(index); + + freeListAdd(index); + return true; + } + + PX_NOINLINE void reserveInternal(uint32_t size) + { + if(!PxIsPowerOfTwo(size)) + size = PxNextPowerOfTwo(size); + + PX_ASSERT(!(size & (size - 1))); + + // decide whether iteration can be done on the entries directly + bool resizeCompact = compacting || freeListEmpty(); + + // define new table sizes + uint32_t oldEntriesCapacity = mEntriesCapacity; + uint32_t newEntriesCapacity = uint32_t(float(size) * mLoadFactor); + uint32_t newHashSize = size; + + // allocate new common buffer and setup pointers to new tables + uint8_t* newBuffer; + uint32_t* newHash; + uint32_t* newEntriesNext; + Entry* newEntries; + { + uint32_t newHashByteOffset = 0; + uint32_t newEntriesNextBytesOffset = newHashByteOffset + newHashSize * sizeof(uint32_t); + uint32_t newEntriesByteOffset = newEntriesNextBytesOffset + newEntriesCapacity * sizeof(uint32_t); + newEntriesByteOffset += (16 - (newEntriesByteOffset & 15)) & 15; + uint32_t newBufferByteSize = newEntriesByteOffset + newEntriesCapacity * sizeof(Entry); + + newBuffer = reinterpret_cast(PxAllocator::allocate(newBufferByteSize, __FILE__, __LINE__)); + PX_ASSERT(newBuffer); + + newHash = reinterpret_cast(newBuffer + newHashByteOffset); + newEntriesNext = reinterpret_cast(newBuffer + newEntriesNextBytesOffset); + newEntries = reinterpret_cast(newBuffer + newEntriesByteOffset); + } + + // initialize new hash table + intrinsics::memSet(newHash, uint32_t(EOL), newHashSize * sizeof(uint32_t)); + + // iterate over old entries, re-hash and create new entries + if(resizeCompact) + { + // check that old free list is empty - we don't need to copy the next entries + PX_ASSERT(compacting || mFreeList == EOL); + + for(uint32_t index = 0; index < mEntriesCount; ++index) + { + uint32_t h = hash(GetKey()(mEntries[index]), newHashSize); + newEntriesNext[index] = newHash[h]; + newHash[h] = index; + + PX_PLACEMENT_NEW(newEntries + index, Entry)(mEntries[index]); + mEntries[index].~Entry(); + } + } + else + { + // copy old free list, only required for non compact resizing + intrinsics::memCopy(newEntriesNext, mEntriesNext, mEntriesCapacity * sizeof(uint32_t)); + + for(uint32_t bucket = 0; bucket < mHashSize; bucket++) + { + uint32_t index = mHash[bucket]; + while(index != EOL) + { + uint32_t h = hash(GetKey()(mEntries[index]), newHashSize); + newEntriesNext[index] = newHash[h]; + PX_ASSERT(index != newHash[h]); + + newHash[h] = index; + + PX_PLACEMENT_NEW(newEntries + index, Entry)(mEntries[index]); + mEntries[index].~Entry(); + + index = mEntriesNext[index]; + } + } + } + + // swap buffer and pointers + PxAllocator::deallocate(mBuffer); + mBuffer = newBuffer; + mHash = newHash; + mHashSize = newHashSize; + mEntriesNext = newEntriesNext; + mEntries = newEntries; + mEntriesCapacity = newEntriesCapacity; + + freeListAdd(oldEntriesCapacity, newEntriesCapacity); + } + + void grow() + { + PX_ASSERT((mFreeList == EOL) || (compacting && (mEntriesCount == mEntriesCapacity))); + + uint32_t size = mHashSize == 0 ? 16 : mHashSize * 2; + reserve(size); + } + + uint8_t* mBuffer; + Entry* mEntries; + uint32_t* mEntriesNext; // same size as mEntries + uint32_t* mHash; + uint32_t mEntriesCapacity; + uint32_t mHashSize; + float mLoadFactor; + uint32_t mFreeList; + uint32_t mTimestamp; + uint32_t mEntriesCount; // number of entries + + public: + class Iter + { + public: + PX_INLINE Iter(PxHashBase& b) : mBucket(0), mEntry(uint32_t(b.EOL)), mTimestamp(b.mTimestamp), mBase(b) + { + if(mBase.mEntriesCapacity > 0) + { + mEntry = mBase.mHash[0]; + skip(); + } + } + + PX_INLINE void check() const + { + PX_ASSERT(mTimestamp == mBase.mTimestamp); + } + PX_INLINE const Entry& operator*() const + { + check(); + return mBase.mEntries[mEntry]; + } + PX_INLINE Entry& operator*() + { + check(); + return mBase.mEntries[mEntry]; + } + PX_INLINE const Entry* operator->() const + { + check(); + return mBase.mEntries + mEntry; + } + PX_INLINE Entry* operator->() + { + check(); + return mBase.mEntries + mEntry; + } + PX_INLINE Iter operator++() + { + check(); + advance(); + return *this; + } + PX_INLINE Iter operator++(int) + { + check(); + Iter i = *this; + advance(); + return i; + } + PX_INLINE bool done() const + { + check(); + return mEntry == mBase.EOL; + } + + private: + PX_INLINE void advance() + { + mEntry = mBase.mEntriesNext[mEntry]; + skip(); + } + PX_INLINE void skip() + { + while(mEntry == mBase.EOL) + { + if(++mBucket == mBase.mHashSize) + break; + mEntry = mBase.mHash[mBucket]; + } + } + + Iter& operator=(const Iter&); + + uint32_t mBucket; + uint32_t mEntry; + uint32_t mTimestamp; + PxHashBase& mBase; + }; + + /*! + Iterate over entries in a hash base and allow entry erase while iterating + */ + class PxEraseIterator + { + public: + PX_INLINE PxEraseIterator(PxHashBase& b): mBase(b) + { + reset(); + } + + PX_INLINE Entry* eraseCurrentGetNext(bool eraseCurrent) + { + if(eraseCurrent && mCurrentEntryIndexPtr) + { + mBase.eraseInternal(mCurrentEntryIndexPtr); + // if next was valid return the same ptr, if next was EOL search new hash entry + if(*mCurrentEntryIndexPtr != mBase.EOL) + return mBase.mEntries + *mCurrentEntryIndexPtr; + else + return traverseHashEntries(); + } + + // traverse mHash to find next entry + if(mCurrentEntryIndexPtr == NULL) + return traverseHashEntries(); + + const uint32_t index = *mCurrentEntryIndexPtr; + if(mBase.mEntriesNext[index] == mBase.EOL) + { + return traverseHashEntries(); + } + else + { + mCurrentEntryIndexPtr = mBase.mEntriesNext + index; + return mBase.mEntries + *mCurrentEntryIndexPtr; + } + } + + PX_INLINE void reset() + { + mCurrentHashIndex = 0; + mCurrentEntryIndexPtr = NULL; + } + + private: + PX_INLINE Entry* traverseHashEntries() + { + mCurrentEntryIndexPtr = NULL; + while (mCurrentEntryIndexPtr == NULL && mCurrentHashIndex < mBase.mHashSize) + { + if (mBase.mHash[mCurrentHashIndex] != mBase.EOL) + { + mCurrentEntryIndexPtr = mBase.mHash + mCurrentHashIndex; + mCurrentHashIndex++; + return mBase.mEntries + *mCurrentEntryIndexPtr; + } + else + { + mCurrentHashIndex++; + } + } + return NULL; + } + + PxEraseIterator& operator=(const PxEraseIterator&); + private: + uint32_t* mCurrentEntryIndexPtr; + uint32_t mCurrentHashIndex; + PxHashBase& mBase; + }; +}; + +template +template +PX_NOINLINE void +PxHashBase::copy(const PxHashBase& other) +{ + reserve(other.mEntriesCount); + + for(uint32_t i = 0; i < other.mEntriesCount; i++) + { + for(uint32_t j = other.mHash[i]; j != EOL; j = other.mEntriesNext[j]) + { + const Entry& otherEntry = other.mEntries[j]; + + bool exists; + Entry* newEntry = create(GK()(otherEntry), exists); + PX_ASSERT(!exists); + + PX_PLACEMENT_NEW(newEntry, Entry)(otherEntry); + } + } +} + +template ::Type, bool Coalesced = false> +class PxHashSetBase +{ + PX_NOCOPY(PxHashSetBase) + public: + struct GetKey + { + PX_INLINE const Key& operator()(const Key& e) + { + return e; + } + }; + + typedef PxHashBase BaseMap; + typedef typename BaseMap::Iter Iterator; + + PxHashSetBase(uint32_t initialTableSize, float loadFactor, const PxAllocator& alloc) + : mBase(initialTableSize, loadFactor, alloc) + { + } + + PxHashSetBase(const PxAllocator& alloc) : mBase(64, 0.75f, alloc) + { + } + + PxHashSetBase(uint32_t initialTableSize = 64, float loadFactor = 0.75f) : mBase(initialTableSize, loadFactor) + { + } + + bool insert(const Key& k) + { + bool exists; + Key* e = mBase.create(k, exists); + if(!exists) + PX_PLACEMENT_NEW(e, Key)(k); + return !exists; + } + + PX_INLINE bool contains(const Key& k) const + { + return mBase.find(k) != 0; + } + PX_INLINE bool erase(const Key& k) + { + return mBase.erase(k); + } + PX_INLINE uint32_t size() const + { + return mBase.size(); + } + PX_INLINE uint32_t capacity() const + { + return mBase.capacity(); + } + PX_INLINE void reserve(uint32_t size) + { + mBase.reserve(size); + } + PX_INLINE void clear() + { + mBase.clear(); + } + + protected: + BaseMap mBase; +}; + +template >::Type> +class PxHashMapBase +{ + PX_NOCOPY(PxHashMapBase) + public: + typedef PxPair Entry; + + struct GetKey + { + PX_INLINE const Key& operator()(const Entry& e) + { + return e.first; + } + }; + + typedef PxHashBase BaseMap; + typedef typename BaseMap::Iter Iterator; + typedef typename BaseMap::PxEraseIterator EraseIterator; + + PxHashMapBase(uint32_t initialTableSize, float loadFactor, const PxAllocator& alloc) + : mBase(initialTableSize, loadFactor, alloc) + { + } + + PxHashMapBase(const PxAllocator& alloc) : mBase(64, 0.75f, alloc) + { + } + + PxHashMapBase(uint32_t initialTableSize = 64, float loadFactor = 0.75f) : mBase(initialTableSize, loadFactor) + { + } + + bool insert(const Key /*&*/ k, const Value /*&*/ v) + { + bool exists; + Entry* e = mBase.create(k, exists); + if(!exists) + PX_PLACEMENT_NEW(e, Entry)(k, v); + return !exists; + } + + Value& operator[](const Key& k) + { + bool exists; + Entry* e = mBase.create(k, exists); + if(!exists) + PX_PLACEMENT_NEW(e, Entry)(k, Value()); + + return e->second; + } + + PX_INLINE const Entry* find(const Key& k) const + { + return mBase.find(k); + } + PX_INLINE bool erase(const Key& k) + { + return mBase.erase(k); + } + PX_INLINE bool erase(const Key& k, Entry& e) + { + return mBase.erase(k, e); + } + PX_INLINE uint32_t size() const + { + return mBase.size(); + } + PX_INLINE uint32_t capacity() const + { + return mBase.capacity(); + } + PX_INLINE Iterator getIterator() + { + return Iterator(mBase); + } + PX_INLINE EraseIterator getEraseIterator() + { + return EraseIterator(mBase); + } + PX_INLINE void reserve(uint32_t size) + { + mBase.reserve(size); + } + PX_INLINE void clear() + { + mBase.clear(); + } + + protected: + BaseMap mBase; +}; +#if !PX_DOXYGEN +} // namespace physx +#endif + +#if PX_VC +#pragma warning(pop) +#endif +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxHashMap.h b/Source/ThirdParty/PhysX/foundation/PxHashMap.h new file mode 100644 index 000000000..cc34ae177 --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxHashMap.h @@ -0,0 +1,119 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_HASHMAP_H +#define PX_HASHMAP_H + +#include "foundation/PxHashInternals.h" + +// TODO: make this doxy-format +// +// This header defines two hash maps. Hash maps +// * support custom initial table sizes (rounded up internally to power-of-2) +// * support custom static allocator objects +// * auto-resize, based on a load factor (i.e. a 64-entry .75 load factor hash will resize +// when the 49th element is inserted) +// * are based on open hashing +// * have O(1) contains, erase +// +// Maps have STL-like copying semantics, and properly initialize and destruct copies of objects +// +// There are two forms of map: coalesced and uncoalesced. Coalesced maps keep the entries in the +// initial segment of an array, so are fast to iterate over; however deletion is approximately +// twice as expensive. +// +// HashMap: +// bool insert(const Key& k, const Value& v) O(1) amortized (exponential resize policy) +// Value & operator[](const Key& k) O(1) for existing objects, else O(1) amortized +// const Entry * find(const Key& k); O(1) +// bool erase(const T& k); O(1) +// uint32_t size(); constant +// void reserve(uint32_t size); O(MAX(currentOccupancy,size)) +// void clear(); O(currentOccupancy) (with zero constant for objects +// without +// destructors) +// Iterator getIterator(); +// +// operator[] creates an entry if one does not exist, initializing with the default constructor. +// CoalescedHashMap does not support getIterator, but instead supports +// const Key *getEntries(); +// +// Use of iterators: +// +// for(HashMap::Iterator iter = test.getIterator(); !iter.done(); ++iter) +// myFunction(iter->first, iter->second); + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +template , class Allocator = PxAllocator> +class PxHashMap : public physx::PxHashMapBase +{ + public: + typedef physx::PxHashMapBase HashMapBase; + typedef typename HashMapBase::Iterator Iterator; + + PxHashMap(uint32_t initialTableSize = 64, float loadFactor = 0.75f) : HashMapBase(initialTableSize, loadFactor) + { + } + PxHashMap(uint32_t initialTableSize, float loadFactor, const Allocator& alloc) + : HashMapBase(initialTableSize, loadFactor, alloc) + { + } + PxHashMap(const Allocator& alloc) : HashMapBase(64, 0.75f, alloc) + { + } + Iterator getIterator() + { + return Iterator(HashMapBase::mBase); + } +}; + +template , class Allocator = PxAllocator> +class PxCoalescedHashMap : public physx::PxHashMapBase +{ + public: + typedef physx::PxHashMapBase HashMapBase; + + PxCoalescedHashMap(uint32_t initialTableSize = 64, float loadFactor = 0.75f) + : HashMapBase(initialTableSize, loadFactor) + { + } + const PxPair* getEntries() const + { + return HashMapBase::mBase.getEntries(); + } +}; +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxHashSet.h b/Source/ThirdParty/PhysX/foundation/PxHashSet.h new file mode 100644 index 000000000..354b04493 --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxHashSet.h @@ -0,0 +1,128 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_HASHSET_H +#define PX_HASHSET_H + +#include "foundation/PxHashInternals.h" + +// TODO: make this doxy-format + +// This header defines two hash sets. Hash sets +// * support custom initial table sizes (rounded up internally to power-of-2) +// * support custom static allocator objects +// * auto-resize, based on a load factor (i.e. a 64-entry .75 load factor hash will resize +// when the 49th element is inserted) +// * are based on open hashing +// +// Sets have STL-like copying semantics, and properly initialize and destruct copies of objects +// +// There are two forms of set: coalesced and uncoalesced. Coalesced sets keep the entries in the +// initial segment of an array, so are fast to iterate over; however deletion is approximately +// twice as expensive. +// +// HashSet: +// bool insert(const T& k) amortized O(1) (exponential resize policy) +// bool contains(const T& k) const; O(1) +// bool erase(const T& k); O(1) +// uint32_t size() const; constant +// void reserve(uint32_t size); O(MAX(size, currentOccupancy)) +// void clear(); O(currentOccupancy) (with zero constant for objects without +// destructors) +// Iterator getIterator(); +// +// Use of iterators: +// +// for(HashSet::Iterator iter = test.getIterator(); !iter.done(); ++iter) +// myFunction(*iter); +// +// CoalescedHashSet does not support getIterator, but instead supports +// const Key *getEntries(); +// +// insertion into a set already containing the element fails returning false, as does +// erasure of an element not in the set +// + +#if !PX_DOXYGEN +namespace physx +{ +#endif +template , class Allocator = PxAllocator> +class PxHashSet : public physx::PxHashSetBase +{ + public: + typedef physx::PxHashSetBase HashSetBase; + typedef typename HashSetBase::Iterator Iterator; + + PxHashSet(uint32_t initialTableSize = 64, float loadFactor = 0.75f) : HashSetBase(initialTableSize, loadFactor) + { + } + PxHashSet(uint32_t initialTableSize, float loadFactor, const Allocator& alloc) + : HashSetBase(initialTableSize, loadFactor, alloc) + { + } + PxHashSet(const Allocator& alloc) : HashSetBase(64, 0.75f, alloc) + { + } + Iterator getIterator() + { + return Iterator(HashSetBase::mBase); + } +}; + +template , class Allocator = PxAllocator> +class PxCoalescedHashSet : public physx::PxHashSetBase +{ + public: + typedef typename physx::PxHashSetBase HashSetBase; + + PxCoalescedHashSet(uint32_t initialTableSize = 64, float loadFactor = 0.75f) + : HashSetBase(initialTableSize, loadFactor) + { + } + + PxCoalescedHashSet(uint32_t initialTableSize, float loadFactor, const Allocator& alloc) + : HashSetBase(initialTableSize, loadFactor, alloc) + { + } + PxCoalescedHashSet(const Allocator& alloc) : HashSetBase(64, 0.75f, alloc) + { + } + + const Key* getEntries() const + { + return HashSetBase::mBase.getEntries(); + } +}; + +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxIO.h b/Source/ThirdParty/PhysX/foundation/PxIO.h index 1db6a8054..a3d53f755 100644 --- a/Source/ThirdParty/PhysX/foundation/PxIO.h +++ b/Source/ThirdParty/PhysX/foundation/PxIO.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PXFOUNDATION_PXIO_H -#define PXFOUNDATION_PXIO_H +#ifndef PX_IO_H +#define PX_IO_H /** \addtogroup common @{ @@ -135,4 +134,5 @@ class PxOutputStream #endif /** @} */ -#endif // #ifndef PXFOUNDATION_PXIO_H +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxInlineAllocator.h b/Source/ThirdParty/PhysX/foundation/PxInlineAllocator.h new file mode 100644 index 000000000..9ff73881a --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxInlineAllocator.h @@ -0,0 +1,92 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_INLINE_ALLOCATOR_H +#define PX_INLINE_ALLOCATOR_H + +#include "foundation/PxUserAllocated.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif +// this is used by the array class to allocate some space for a small number +// of objects along with the metadata +template +class PxInlineAllocator : private BaseAllocator +{ + public: + PxInlineAllocator(const PxEMPTY v) : BaseAllocator(v) + { + } + + PxInlineAllocator(const BaseAllocator& alloc = BaseAllocator()) : BaseAllocator(alloc), mBufferUsed(false) + { + } + + PxInlineAllocator(const PxInlineAllocator& aloc) : BaseAllocator(aloc), mBufferUsed(false) + { + } + + void* allocate(PxU32 size, const char* filename, PxI32 line) + { + if(!mBufferUsed && size <= N) + { + mBufferUsed = true; + return mBuffer; + } + return BaseAllocator::allocate(size, filename, line); + } + + void deallocate(void* ptr) + { + if(ptr == mBuffer) + mBufferUsed = false; + else + BaseAllocator::deallocate(ptr); + } + + PX_FORCE_INLINE PxU8* getInlineBuffer() + { + return mBuffer; + } + PX_FORCE_INLINE bool isBufferUsed() const + { + return mBufferUsed; + } + + protected: + PxU8 mBuffer[N]; + bool mBufferUsed; +}; +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxInlineAoS.h b/Source/ThirdParty/PhysX/foundation/PxInlineAoS.h new file mode 100644 index 000000000..f59cc5972 --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxInlineAoS.h @@ -0,0 +1,45 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_INLINE_AOS_H +#define PX_INLINE_AOS_H + +#include "foundation/PxPreprocessor.h" + +#if PX_WINDOWS +#include "windows/PxWindowsTrigConstants.h" +#include "windows/PxWindowsInlineAoS.h" +#elif (PX_UNIX_FAMILY || PX_PS4 || PX_PS5 || PX_SWITCH) +#include "unix/PxUnixTrigConstants.h" +#include "unix/PxUnixInlineAoS.h" +#else +#error "Platform not supported!" +#endif + +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxInlineArray.h b/Source/ThirdParty/PhysX/foundation/PxInlineArray.h new file mode 100644 index 000000000..f3c9d8428 --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxInlineArray.h @@ -0,0 +1,69 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_INLINE_ARRAY_H +#define PX_INLINE_ARRAY_H + +#include "foundation/PxArray.h" +#include "foundation/PxInlineAllocator.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +// array that pre-allocates for N elements +template ::Type> +class PxInlineArray : public PxArray > +{ + typedef PxInlineAllocator Allocator; + + public: + PxInlineArray(const PxEMPTY v) : PxArray(v) + { + if(isInlined()) + this->mData = reinterpret_cast(PxArray::getInlineBuffer()); + } + + PX_INLINE bool isInlined() const + { + return Allocator::isBufferUsed(); + } + + PX_INLINE explicit PxInlineArray(const Alloc& alloc = Alloc()) : PxArray(alloc) + { + this->mData = this->allocate(N); + this->mCapacity = N; + } +}; +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxIntrinsics.h b/Source/ThirdParty/PhysX/foundation/PxIntrinsics.h index 9f6d4a13a..85ba03af0 100644 --- a/Source/ThirdParty/PhysX/foundation/PxIntrinsics.h +++ b/Source/ThirdParty/PhysX/foundation/PxIntrinsics.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,25 +22,29 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PXFOUNDATION_PXINTRINSICS_H -#define PXFOUNDATION_PXINTRINSICS_H +#ifndef PX_INTRINSICS_H +#define PX_INTRINSICS_H #include "foundation/PxPreprocessor.h" #if PX_WINDOWS_FAMILY -#include "foundation/windows/PxWindowsIntrinsics.h" -#elif(PX_LINUX || PX_ANDROID || PX_APPLE_FAMILY || PX_PS4) -#include "foundation/unix/PxUnixIntrinsics.h" -#elif PX_XBOXONE -#include "foundation/XboxOne/PxXboxOneIntrinsics.h" +#include "windows/PxWindowsIntrinsics.h" +#elif (PX_LINUX || PX_ANDROID || PX_APPLE_FAMILY || PX_PS4 || PX_PS5) +#include "unix/PxUnixIntrinsics.h" #elif PX_SWITCH -#include +#include "switch/PxSwitchIntrinsics.h" #else #error "Platform not supported!" #endif -#endif // #ifndef PXFOUNDATION_PXINTRINSICS_H +#if PX_WINDOWS_FAMILY +#pragma intrinsic(memcmp) +#pragma intrinsic(memcpy) +#pragma intrinsic(memset) +#endif + +#endif // #ifndef PX_INTRINSICS_H diff --git a/Source/ThirdParty/PhysX/foundation/PxMat33.h b/Source/ThirdParty/PhysX/foundation/PxMat33.h index 3019ba2dd..0f5485827 100644 --- a/Source/ThirdParty/PhysX/foundation/PxMat33.h +++ b/Source/ThirdParty/PhysX/foundation/PxMat33.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PXFOUNDATION_PXMAT33_H -#define PXFOUNDATION_PXMAT33_H +#ifndef PX_MAT33_H +#define PX_MAT33_H /** \addtogroup foundation @{ */ @@ -85,86 +84,97 @@ which in C++ translates to M[column][row] The mathematical indexing is M_row,column and this is what is used for _-notation so _12 is 1st row, second column and operator(row, column)! - */ -class PxMat33 + +template +class PxMat33T { - public: + public: //! Default constructor - PX_CUDA_CALLABLE PX_FORCE_INLINE PxMat33() + PX_CUDA_CALLABLE PX_FORCE_INLINE PxMat33T() { } //! identity constructor - PX_CUDA_CALLABLE PX_INLINE PxMat33(PxIDENTITY r) - : column0(1.0f, 0.0f, 0.0f), column1(0.0f, 1.0f, 0.0f), column2(0.0f, 0.0f, 1.0f) + PX_CUDA_CALLABLE PX_INLINE PxMat33T(PxIDENTITY) : + column0(Type(1.0), Type(0.0), Type(0.0)), + column1(Type(0.0), Type(1.0), Type(0.0)), + column2(Type(0.0), Type(0.0), Type(1.0)) { - PX_UNUSED(r); } //! zero constructor - PX_CUDA_CALLABLE PX_INLINE PxMat33(PxZERO r) : column0(0.0f), column1(0.0f), column2(0.0f) + PX_CUDA_CALLABLE PX_INLINE PxMat33T(PxZERO) : + column0(Type(0.0)), + column1(Type(0.0)), + column2(Type(0.0)) { - PX_UNUSED(r); } //! Construct from three base vectors - PX_CUDA_CALLABLE PxMat33(const PxVec3& col0, const PxVec3& col1, const PxVec3& col2) - : column0(col0), column1(col1), column2(col2) + PX_CUDA_CALLABLE PxMat33T(const PxVec3T& col0, const PxVec3T& col1, const PxVec3T& col2) : + column0(col0), + column1(col1), + column2(col2) { } //! constructor from a scalar, which generates a multiple of the identity matrix - explicit PX_CUDA_CALLABLE PX_INLINE PxMat33(float r) - : column0(r, 0.0f, 0.0f), column1(0.0f, r, 0.0f), column2(0.0f, 0.0f, r) + explicit PX_CUDA_CALLABLE PX_INLINE PxMat33T(Type r) : + column0(r, Type(0.0), Type(0.0)), + column1(Type(0.0), r, Type(0.0)), + column2(Type(0.0), Type(0.0), r) { } - //! Construct from float[9] - explicit PX_CUDA_CALLABLE PX_INLINE PxMat33(float values[]) - : column0(values[0], values[1], values[2]) - , column1(values[3], values[4], values[5]) - , column2(values[6], values[7], values[8]) + //! Construct from Type[9] + explicit PX_CUDA_CALLABLE PX_INLINE PxMat33T(Type values[]) : + column0(values[0], values[1], values[2]), + column1(values[3], values[4], values[5]), + column2(values[6], values[7], values[8]) { } //! Construct from a quaternion - explicit PX_CUDA_CALLABLE PX_FORCE_INLINE PxMat33(const PxQuat& q) + explicit PX_CUDA_CALLABLE PX_FORCE_INLINE PxMat33T(const PxQuatT& q) { - const float x = q.x; - const float y = q.y; - const float z = q.z; - const float w = q.w; + // PT: TODO: PX-566 + const Type x = q.x; + const Type y = q.y; + const Type z = q.z; + const Type w = q.w; - const float x2 = x + x; - const float y2 = y + y; - const float z2 = z + z; + const Type x2 = x + x; + const Type y2 = y + y; + const Type z2 = z + z; - const float xx = x2 * x; - const float yy = y2 * y; - const float zz = z2 * z; + const Type xx = x2 * x; + const Type yy = y2 * y; + const Type zz = z2 * z; - const float xy = x2 * y; - const float xz = x2 * z; - const float xw = x2 * w; + const Type xy = x2 * y; + const Type xz = x2 * z; + const Type xw = x2 * w; - const float yz = y2 * z; - const float yw = y2 * w; - const float zw = z2 * w; + const Type yz = y2 * z; + const Type yw = y2 * w; + const Type zw = z2 * w; - column0 = PxVec3(1.0f - yy - zz, xy + zw, xz - yw); - column1 = PxVec3(xy - zw, 1.0f - xx - zz, yz + xw); - column2 = PxVec3(xz + yw, yz - xw, 1.0f - xx - yy); + column0 = PxVec3T(Type(1.0) - yy - zz, xy + zw, xz - yw); + column1 = PxVec3T(xy - zw, Type(1.0) - xx - zz, yz + xw); + column2 = PxVec3T(xz + yw, yz - xw, Type(1.0) - xx - yy); } //! Copy constructor - PX_CUDA_CALLABLE PX_INLINE PxMat33(const PxMat33& other) - : column0(other.column0), column1(other.column1), column2(other.column2) + PX_CUDA_CALLABLE PX_INLINE PxMat33T(const PxMat33T& other) : + column0(other.column0), + column1(other.column1), + column2(other.column2) { } //! Assignment operator - PX_CUDA_CALLABLE PX_FORCE_INLINE PxMat33& operator=(const PxMat33& other) + PX_CUDA_CALLABLE PX_FORCE_INLINE PxMat33T& operator=(const PxMat33T& other) { column0 = other.column0; column1 = other.column1; @@ -173,38 +183,46 @@ class PxMat33 } //! Construct from diagonal, off-diagonals are zero. - PX_CUDA_CALLABLE PX_INLINE static const PxMat33 createDiagonal(const PxVec3& d) + PX_CUDA_CALLABLE PX_INLINE static const PxMat33T createDiagonal(const PxVec3T& d) { - return PxMat33(PxVec3(d.x, 0.0f, 0.0f), PxVec3(0.0f, d.y, 0.0f), PxVec3(0.0f, 0.0f, d.z)); + return PxMat33T(PxVec3T(d.x, Type(0.0), Type(0.0)), + PxVec3T(Type(0.0), d.y, Type(0.0)), + PxVec3T(Type(0.0), Type(0.0), d.z)); + } + + //! Computes the outer product of two vectors + PX_CUDA_CALLABLE PX_INLINE static const PxMat33T outer(const PxVec3T& a, const PxVec3T& b) + { + return PxMat33T(a * b.x, a * b.y, a * b.z); } /** \brief returns true if the two matrices are exactly equal */ - PX_CUDA_CALLABLE PX_INLINE bool operator==(const PxMat33& m) const + PX_CUDA_CALLABLE PX_INLINE bool operator==(const PxMat33T& m) const { return column0 == m.column0 && column1 == m.column1 && column2 == m.column2; } //! Get transposed matrix - PX_CUDA_CALLABLE PX_FORCE_INLINE const PxMat33 getTranspose() const + PX_CUDA_CALLABLE PX_FORCE_INLINE const PxMat33T getTranspose() const { - const PxVec3 v0(column0.x, column1.x, column2.x); - const PxVec3 v1(column0.y, column1.y, column2.y); - const PxVec3 v2(column0.z, column1.z, column2.z); + const PxVec3T v0(column0.x, column1.x, column2.x); + const PxVec3T v1(column0.y, column1.y, column2.y); + const PxVec3T v2(column0.z, column1.z, column2.z); - return PxMat33(v0, v1, v2); + return PxMat33T(v0, v1, v2); } //! Get the real inverse - PX_CUDA_CALLABLE PX_INLINE const PxMat33 getInverse() const + PX_CUDA_CALLABLE PX_INLINE const PxMat33T getInverse() const { - const float det = getDeterminant(); - PxMat33 inverse; + const Type det = getDeterminant(); + PxMat33T inverse; - if(det != 0) + if(det != Type(0.0)) { - const float invDet = 1.0f / det; + const Type invDet = Type(1.0) / det; inverse.column0.x = invDet * (column1.y * column2.z - column2.y * column1.z); inverse.column0.y = invDet * -(column0.y * column2.z - column2.y * column0.z); @@ -222,44 +240,45 @@ class PxMat33 } else { - return PxMat33(PxIdentity); + return PxMat33T(PxIdentity); } } //! Get determinant - PX_CUDA_CALLABLE PX_INLINE float getDeterminant() const + PX_CUDA_CALLABLE PX_INLINE Type getDeterminant() const { return column0.dot(column1.cross(column2)); } //! Unary minus - PX_CUDA_CALLABLE PX_INLINE const PxMat33 operator-() const + PX_CUDA_CALLABLE PX_INLINE const PxMat33T operator-() const { - return PxMat33(-column0, -column1, -column2); + return PxMat33T(-column0, -column1, -column2); } //! Add - PX_CUDA_CALLABLE PX_INLINE const PxMat33 operator+(const PxMat33& other) const + PX_CUDA_CALLABLE PX_INLINE const PxMat33T operator+(const PxMat33T& other) const { - return PxMat33(column0 + other.column0, column1 + other.column1, column2 + other.column2); + return PxMat33T(column0 + other.column0, column1 + other.column1, column2 + other.column2); } //! Subtract - PX_CUDA_CALLABLE PX_INLINE const PxMat33 operator-(const PxMat33& other) const + PX_CUDA_CALLABLE PX_INLINE const PxMat33T operator-(const PxMat33T& other) const { - return PxMat33(column0 - other.column0, column1 - other.column1, column2 - other.column2); + return PxMat33T(column0 - other.column0, column1 - other.column1, column2 - other.column2); } //! Scalar multiplication - PX_CUDA_CALLABLE PX_INLINE const PxMat33 operator*(float scalar) const + PX_CUDA_CALLABLE PX_INLINE const PxMat33T operator*(Type scalar) const { - return PxMat33(column0 * scalar, column1 * scalar, column2 * scalar); + return PxMat33T(column0 * scalar, column1 * scalar, column2 * scalar); } - friend PxMat33 operator*(float, const PxMat33&); + template + PX_CUDA_CALLABLE PX_INLINE friend PxMat33T operator*(Type2, const PxMat33T&); //! Matrix vector multiplication (returns 'this->transform(vec)') - PX_CUDA_CALLABLE PX_INLINE const PxVec3 operator*(const PxVec3& vec) const + PX_CUDA_CALLABLE PX_INLINE const PxVec3T operator*(const PxVec3T& vec) const { return transform(vec); } @@ -267,15 +286,17 @@ class PxMat33 // a = b operators //! Matrix multiplication - PX_CUDA_CALLABLE PX_FORCE_INLINE const PxMat33 operator*(const PxMat33& other) const + PX_CUDA_CALLABLE PX_FORCE_INLINE const PxMat33T operator*(const PxMat33T& other) const { // Rows from this columns from other // column0 = transform(other.column0) etc - return PxMat33(transform(other.column0), transform(other.column1), transform(other.column2)); + return PxMat33T(transform(other.column0), + transform(other.column1), + transform(other.column2)); } //! Equals-add - PX_CUDA_CALLABLE PX_INLINE PxMat33& operator+=(const PxMat33& other) + PX_CUDA_CALLABLE PX_INLINE PxMat33T& operator+=(const PxMat33T& other) { column0 += other.column0; column1 += other.column1; @@ -284,7 +305,7 @@ class PxMat33 } //! Equals-sub - PX_CUDA_CALLABLE PX_INLINE PxMat33& operator-=(const PxMat33& other) + PX_CUDA_CALLABLE PX_INLINE PxMat33T& operator-=(const PxMat33T& other) { column0 -= other.column0; column1 -= other.column1; @@ -293,7 +314,7 @@ class PxMat33 } //! Equals scalar multiplication - PX_CUDA_CALLABLE PX_INLINE PxMat33& operator*=(float scalar) + PX_CUDA_CALLABLE PX_INLINE PxMat33T& operator*=(Type scalar) { column0 *= scalar; column1 *= scalar; @@ -302,20 +323,20 @@ class PxMat33 } //! Equals matrix multiplication - PX_CUDA_CALLABLE PX_INLINE PxMat33& operator*=(const PxMat33& other) + PX_CUDA_CALLABLE PX_INLINE PxMat33T& operator*=(const PxMat33T& other) { *this = *this * other; return *this; } //! Element access, mathematical way! - PX_CUDA_CALLABLE PX_FORCE_INLINE float operator()(unsigned int row, unsigned int col) const + PX_CUDA_CALLABLE PX_FORCE_INLINE Type operator()(PxU32 row, PxU32 col) const { return (*this)[col][row]; } //! Element access, mathematical way! - PX_CUDA_CALLABLE PX_FORCE_INLINE float& operator()(unsigned int row, unsigned int col) + PX_CUDA_CALLABLE PX_FORCE_INLINE Type& operator()(PxU32 row, PxU32 col) { return (*this)[col][row]; } @@ -323,74 +344,82 @@ class PxMat33 // Transform etc //! Transform vector by matrix, equal to v' = M*v - PX_CUDA_CALLABLE PX_FORCE_INLINE const PxVec3 transform(const PxVec3& other) const + PX_CUDA_CALLABLE PX_FORCE_INLINE const PxVec3T transform(const PxVec3T& other) const { return column0 * other.x + column1 * other.y + column2 * other.z; } //! Transform vector by matrix transpose, v' = M^t*v - PX_CUDA_CALLABLE PX_INLINE const PxVec3 transformTranspose(const PxVec3& other) const + PX_CUDA_CALLABLE PX_INLINE const PxVec3T transformTranspose(const PxVec3T& other) const { - return PxVec3(column0.dot(other), column1.dot(other), column2.dot(other)); + return PxVec3T(column0.dot(other), column1.dot(other), column2.dot(other)); } - PX_CUDA_CALLABLE PX_FORCE_INLINE const float* front() const + PX_CUDA_CALLABLE PX_FORCE_INLINE const Type* front() const { return &column0.x; } - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3& operator[](unsigned int num) + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T& operator[](PxU32 num) { return (&column0)[num]; } - PX_CUDA_CALLABLE PX_FORCE_INLINE const PxVec3& operator[](unsigned int num) const + + PX_CUDA_CALLABLE PX_FORCE_INLINE const PxVec3T& operator[](PxU32 num) const { return (&column0)[num]; } // Data, see above for format! - PxVec3 column0, column1, column2; // the three base vectors + PxVec3T column0, column1, column2; // the three base vectors }; -// implementation from PxQuat.h -PX_CUDA_CALLABLE PX_INLINE PxQuat::PxQuat(const PxMat33& m) +template +PX_CUDA_CALLABLE PX_INLINE PxMat33T operator*(Type scalar, const PxMat33T& m) { - if(m.column2.z < 0) + return PxMat33T(scalar * m.column0, scalar * m.column1, scalar * m.column2); +} + +// implementation from PxQuat.h +template +PX_CUDA_CALLABLE PX_INLINE PxQuatT::PxQuatT(const PxMat33T& m) +{ + if(m.column2.z < Type(0)) { if(m.column0.x > m.column1.y) { - float t = 1 + m.column0.x - m.column1.y - m.column2.z; - *this = PxQuat(t, m.column0.y + m.column1.x, m.column2.x + m.column0.z, m.column1.z - m.column2.y) * - (0.5f / PxSqrt(t)); + const Type t = Type(1.0) + m.column0.x - m.column1.y - m.column2.z; + *this = PxQuatT(t, m.column0.y + m.column1.x, m.column2.x + m.column0.z, m.column1.z - m.column2.y) * (Type(0.5) / PxSqrt(t)); } else { - float t = 1 - m.column0.x + m.column1.y - m.column2.z; - *this = PxQuat(m.column0.y + m.column1.x, t, m.column1.z + m.column2.y, m.column2.x - m.column0.z) * - (0.5f / PxSqrt(t)); + const Type t = Type(1.0) - m.column0.x + m.column1.y - m.column2.z; + *this = PxQuatT(m.column0.y + m.column1.x, t, m.column1.z + m.column2.y, m.column2.x - m.column0.z) * (Type(0.5) / PxSqrt(t)); } } else { if(m.column0.x < -m.column1.y) { - float t = 1 - m.column0.x - m.column1.y + m.column2.z; - *this = PxQuat(m.column2.x + m.column0.z, m.column1.z + m.column2.y, t, m.column0.y - m.column1.x) * - (0.5f / PxSqrt(t)); + const Type t = Type(1.0) - m.column0.x - m.column1.y + m.column2.z; + *this = PxQuatT(m.column2.x + m.column0.z, m.column1.z + m.column2.y, t, m.column0.y - m.column1.x) * (Type(0.5) / PxSqrt(t)); } else { - float t = 1 + m.column0.x + m.column1.y + m.column2.z; - *this = PxQuat(m.column1.z - m.column2.y, m.column2.x - m.column0.z, m.column0.y - m.column1.x, t) * - (0.5f / PxSqrt(t)); + const Type t = Type(1.0) + m.column0.x + m.column1.y + m.column2.z; + *this = PxQuatT(m.column1.z - m.column2.y, m.column2.x - m.column0.z, m.column0.y - m.column1.x, t) * (Type(0.5) / PxSqrt(t)); } } } +typedef PxMat33T PxMat33; +typedef PxMat33T PxMat33d; + #if !PX_DOXYGEN } // namespace physx #endif /** @} */ -#endif // #ifndef PXFOUNDATION_PXMAT33_H +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxMat34.h b/Source/ThirdParty/PhysX/foundation/PxMat34.h new file mode 100644 index 000000000..ccbc6c0d7 --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxMat34.h @@ -0,0 +1,277 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_MAT34_H +#define PX_MAT34_H +/** \addtogroup foundation +@{ +*/ + +#include "foundation/PxTransform.h" +#include "foundation/PxMat33.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif +/*! +Basic mathematical 3x4 matrix, implemented as a 3x3 rotation matrix and a translation + +See PxMat33 for the format of the rotation matrix. +*/ + +template +class PxMat34T +{ + public: + //! Default constructor + PX_CUDA_CALLABLE PX_FORCE_INLINE PxMat34T() + { + } + + //! Construct from four base vectors + PX_CUDA_CALLABLE PX_FORCE_INLINE PxMat34T(const PxVec3T& b0, const PxVec3T& b1, const PxVec3T& b2, const PxVec3T& b3) + : m(b0, b1, b2), p(b3) + { + } + + //! Construct from Type[12] + explicit PX_CUDA_CALLABLE PX_FORCE_INLINE PxMat34T(Type values[]) : + m(values), p(values[9], values[10], values[11]) + { + } + + //! Construct from a 3x3 matrix + explicit PX_CUDA_CALLABLE PX_FORCE_INLINE PxMat34T(const PxMat33T& other) + : m(other), p(PxZero) + { + } + + //! Construct from a 3x3 matrix and a translation vector + PX_CUDA_CALLABLE PX_FORCE_INLINE PxMat34T(const PxMat33T& other, const PxVec3T& t) + : m(other), p(t) + { + } + + //! Construct from a PxTransformT + explicit PX_CUDA_CALLABLE PX_FORCE_INLINE PxMat34T(const PxTransformT& other) + : m(other.q), p(other.p) + { + } + + //! Copy constructor + PX_CUDA_CALLABLE PX_FORCE_INLINE PxMat34T(const PxMat34T& other) : m(other.m), p(other.p) + { + } + + //! Assignment operator + PX_CUDA_CALLABLE PX_FORCE_INLINE const PxMat34T& operator=(const PxMat34T& other) + { + m = other.m; + p = other.p; + return *this; + } + + //! Set to identity matrix + PX_CUDA_CALLABLE PX_FORCE_INLINE void setIdentity() + { + m = PxMat33T(PxIdentity); + p = PxVec3T(0); + } + + // Simpler operators + //! Equality operator + PX_CUDA_CALLABLE PX_FORCE_INLINE bool operator==(const PxMat34T& other) const + { + return m == other.m && p == other.p; + } + + //! Inequality operator + PX_CUDA_CALLABLE PX_FORCE_INLINE bool operator!=(const PxMat34T& other) const + { + return !operator==(other); + } + + //! Unary minus + PX_CUDA_CALLABLE PX_FORCE_INLINE PxMat34T operator-() const + { + return PxMat34T(-m, -p); + } + + //! Add + PX_CUDA_CALLABLE PX_FORCE_INLINE PxMat34T operator+(const PxMat34T& other) const + { + return PxMat34T(m + other.m, p + other.p); + } + + //! Subtract + PX_CUDA_CALLABLE PX_FORCE_INLINE PxMat34T operator-(const PxMat34T& other) const + { + return PxMat34T(m - other.m, p - other.p); + } + + //! Scalar multiplication + PX_CUDA_CALLABLE PX_FORCE_INLINE PxMat34T operator*(Type scalar) const + { + return PxMat34T(m*scalar, p*scalar); + } + + //! Matrix multiplication + PX_CUDA_CALLABLE PX_FORCE_INLINE PxMat34T operator*(const PxMat34T& other) const + { + //Rows from this columns from other + //base0 = rotate(other.m.column0) etc + return PxMat34T(m*other.m, m*other.p + p); + } + + //! Matrix multiplication, extend the second matrix + PX_CUDA_CALLABLE PX_FORCE_INLINE PxMat34T operator*(const PxMat33T& other) const + { + //Rows from this columns from other + //base0 = transform(other.m.column0) etc + return PxMat34T(m*other, p); + } + + template + friend PxMat34T operator*(const PxMat33T& a, const PxMat34T& b); + + // a = b operators + + //! Equals-add + PX_CUDA_CALLABLE PX_FORCE_INLINE PxMat34T& operator+=(const PxMat34T& other) + { + m += other.m; + p += other.p; + return *this; + } + + //! Equals-sub + PX_CUDA_CALLABLE PX_FORCE_INLINE PxMat34T& operator-=(const PxMat34T& other) + { + m -= other.m; + p -= other.p; + return *this; + } + + //! Equals scalar multiplication + PX_CUDA_CALLABLE PX_FORCE_INLINE PxMat34T& operator*=(Type scalar) + { + m *= scalar; + p *= scalar; + return *this; + } + + //! Element access, mathematical way! + PX_CUDA_CALLABLE PX_FORCE_INLINE Type operator()(PxU32 row, PxU32 col) const + { + return (*this)[col][row]; + } + + //! Element access, mathematical way! + PX_CUDA_CALLABLE PX_FORCE_INLINE Type& operator()(PxU32 row, PxU32 col) + { + return (*this)[col][row]; + } + + // Transform etc + + //! Transform vector by matrix, equal to v' = M*v + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T rotate(const PxVec3T& other) const + { + return m*other; + } + + //! Transform vector by transpose of matrix, equal to v' = M^t*v + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T rotateTranspose(const PxVec3T& other) const + { + return m.transformTranspose(other); + } + + //! Transform point by matrix + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T transform(const PxVec3T& other) const + { + return m*other + p; + } + + //! Transform point by transposed matrix + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T transformTranspose(const PxVec3T& other) const + { + return m.transformTranspose(other - p); + } + + //! Transform point by transposed matrix + PX_CUDA_CALLABLE PX_FORCE_INLINE PxMat34T transformTranspose(const PxMat34T& other) const + { + return PxMat34T(m.transformTranspose(other.m.column0), + m.transformTranspose(other.m.column1), + m.transformTranspose(other.m.column2), + m.transformTranspose(other.p - p)); + } + + //! Invert matrix treating it as a rotation+translation matrix only + PX_CUDA_CALLABLE PX_FORCE_INLINE PxMat34T getInverseRT() const + { + return PxMat34T(m.getTranspose(), m.transformTranspose(-p)); + } + + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T& operator[](PxU32 num) { return (&m.column0)[num]; } + PX_CUDA_CALLABLE PX_FORCE_INLINE const PxVec3T& operator[](PxU32 num) const { return (&m.column0)[num]; } + + //Data, see above for format! + + PxMat33T m; + PxVec3T p; +}; + +//! Multiply a*b, a is extended +template +PX_INLINE PxMat34T operator*(const PxMat33T& a, const PxMat34T& b) +{ + return PxMat34T(a * b.m, a * b.p); +} + +typedef PxMat34T PxMat34; +typedef PxMat34T PxMat34d; + +//! A padded version of PxMat34, to safely load its data using SIMD +class PxMat34Padded : public PxMat34 +{ + public: + PX_FORCE_INLINE PxMat34Padded(const PxMat34& src) : PxMat34(src) {} + PX_FORCE_INLINE PxMat34Padded() {} + PX_FORCE_INLINE ~PxMat34Padded() {} + PxU32 padding; +}; +PX_COMPILE_TIME_ASSERT(0==(sizeof(PxMat34Padded)==16)); + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/foundation/PxMat44.h b/Source/ThirdParty/PhysX/foundation/PxMat44.h index 577a93fbd..92cfa51d4 100644 --- a/Source/ThirdParty/PhysX/foundation/PxMat44.h +++ b/Source/ThirdParty/PhysX/foundation/PxMat44.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PXFOUNDATION_PXMAT44_H -#define PXFOUNDATION_PXMAT44_H +#ifndef PX_MAT44_H +#define PX_MAT44_H /** \addtogroup foundation @{ */ @@ -51,126 +50,138 @@ This class is layout-compatible with D3D and OpenGL matrices. More notes on layo @see PxMat33 PxTransform */ -class PxMat44 +template +class PxMat44T { - public: + public: //! Default constructor - PX_CUDA_CALLABLE PX_INLINE PxMat44() + PX_CUDA_CALLABLE PX_INLINE PxMat44T() { } //! identity constructor - PX_CUDA_CALLABLE PX_INLINE PxMat44(PxIDENTITY r) - : column0(1.0f, 0.0f, 0.0f, 0.0f) - , column1(0.0f, 1.0f, 0.0f, 0.0f) - , column2(0.0f, 0.0f, 1.0f, 0.0f) - , column3(0.0f, 0.0f, 0.0f, 1.0f) + PX_CUDA_CALLABLE PX_INLINE PxMat44T(PxIDENTITY) : + column0(Type(1.0), Type(0.0), Type(0.0), Type(0.0)), + column1(Type(0.0), Type(1.0), Type(0.0), Type(0.0)), + column2(Type(0.0), Type(0.0), Type(1.0), Type(0.0)), + column3(Type(0.0), Type(0.0), Type(0.0), Type(1.0)) { - PX_UNUSED(r); } //! zero constructor - PX_CUDA_CALLABLE PX_INLINE PxMat44(PxZERO r) : column0(PxZero), column1(PxZero), column2(PxZero), column3(PxZero) + PX_CUDA_CALLABLE PX_INLINE PxMat44T(PxZERO) : column0(PxZero), column1(PxZero), column2(PxZero), column3(PxZero) { - PX_UNUSED(r); } //! Construct from four 4-vectors - PX_CUDA_CALLABLE PxMat44(const PxVec4& col0, const PxVec4& col1, const PxVec4& col2, const PxVec4& col3) - : column0(col0), column1(col1), column2(col2), column3(col3) + PX_CUDA_CALLABLE PxMat44T(const PxVec4T& col0, const PxVec4T& col1, const PxVec4T& col2, const PxVec4T& col3) : + column0(col0), + column1(col1), + column2(col2), + column3(col3) { } //! constructor that generates a multiple of the identity matrix - explicit PX_CUDA_CALLABLE PX_INLINE PxMat44(float r) - : column0(r, 0.0f, 0.0f, 0.0f) - , column1(0.0f, r, 0.0f, 0.0f) - , column2(0.0f, 0.0f, r, 0.0f) - , column3(0.0f, 0.0f, 0.0f, r) + explicit PX_CUDA_CALLABLE PX_INLINE PxMat44T(Type r) : + column0(r, Type(0.0), Type(0.0), Type(0.0)), + column1(Type(0.0), r, Type(0.0), Type(0.0)), + column2(Type(0.0), Type(0.0), r, Type(0.0)), + column3(Type(0.0), Type(0.0), Type(0.0), r) { } //! Construct from three base vectors and a translation - PX_CUDA_CALLABLE PxMat44(const PxVec3& col0, const PxVec3& col1, const PxVec3& col2, const PxVec3& col3) - : column0(col0, 0), column1(col1, 0), column2(col2, 0), column3(col3, 1.0f) + PX_CUDA_CALLABLE PxMat44T(const PxVec3T& col0, const PxVec3T& col1, const PxVec3T& col2, const PxVec3T& col3) : + column0(col0, Type(0.0)), + column1(col1, Type(0.0)), + column2(col2, Type(0.0)), + column3(col3, Type(1.0)) { } - //! Construct from float[16] - explicit PX_CUDA_CALLABLE PX_INLINE PxMat44(float values[]) - : column0(values[0], values[1], values[2], values[3]) - , column1(values[4], values[5], values[6], values[7]) - , column2(values[8], values[9], values[10], values[11]) - , column3(values[12], values[13], values[14], values[15]) + //! Construct from Type[16] + explicit PX_CUDA_CALLABLE PX_INLINE PxMat44T(Type values[]) : + column0(values[0], values[1], values[2], values[3]), + column1(values[4], values[5], values[6], values[7]), + column2(values[8], values[9], values[10], values[11]), + column3(values[12], values[13], values[14], values[15]) { } //! Construct from a quaternion - explicit PX_CUDA_CALLABLE PX_INLINE PxMat44(const PxQuat& q) + explicit PX_CUDA_CALLABLE PX_INLINE PxMat44T(const PxQuatT& q) { - const float x = q.x; - const float y = q.y; - const float z = q.z; - const float w = q.w; + // PT: TODO: PX-566 + const Type x = q.x; + const Type y = q.y; + const Type z = q.z; + const Type w = q.w; - const float x2 = x + x; - const float y2 = y + y; - const float z2 = z + z; + const Type x2 = x + x; + const Type y2 = y + y; + const Type z2 = z + z; - const float xx = x2 * x; - const float yy = y2 * y; - const float zz = z2 * z; + const Type xx = x2 * x; + const Type yy = y2 * y; + const Type zz = z2 * z; - const float xy = x2 * y; - const float xz = x2 * z; - const float xw = x2 * w; + const Type xy = x2 * y; + const Type xz = x2 * z; + const Type xw = x2 * w; - const float yz = y2 * z; - const float yw = y2 * w; - const float zw = z2 * w; + const Type yz = y2 * z; + const Type yw = y2 * w; + const Type zw = z2 * w; - column0 = PxVec4(1.0f - yy - zz, xy + zw, xz - yw, 0.0f); - column1 = PxVec4(xy - zw, 1.0f - xx - zz, yz + xw, 0.0f); - column2 = PxVec4(xz + yw, yz - xw, 1.0f - xx - yy, 0.0f); - column3 = PxVec4(0.0f, 0.0f, 0.0f, 1.0f); + column0 = PxVec4T(Type(1.0) - yy - zz, xy + zw, xz - yw, Type(0.0)); + column1 = PxVec4T(xy - zw, Type(1.0) - xx - zz, yz + xw, Type(0.0)); + column2 = PxVec4T(xz + yw, yz - xw, Type(1.0) - xx - yy, Type(0.0)); + column3 = PxVec4T(Type(0.0), Type(0.0), Type(0.0), Type(1.0)); } //! Construct from a diagonal vector - explicit PX_CUDA_CALLABLE PX_INLINE PxMat44(const PxVec4& diagonal) - : column0(diagonal.x, 0.0f, 0.0f, 0.0f) - , column1(0.0f, diagonal.y, 0.0f, 0.0f) - , column2(0.0f, 0.0f, diagonal.z, 0.0f) - , column3(0.0f, 0.0f, 0.0f, diagonal.w) + explicit PX_CUDA_CALLABLE PX_INLINE PxMat44T(const PxVec4T& diagonal) : + column0(diagonal.x, Type(0.0), Type(0.0), Type(0.0)), + column1(Type(0.0), diagonal.y, Type(0.0), Type(0.0)), + column2(Type(0.0), Type(0.0), diagonal.z, Type(0.0)), + column3(Type(0.0), Type(0.0), Type(0.0), diagonal.w) { } //! Construct from Mat33 and a translation - PX_CUDA_CALLABLE PxMat44(const PxMat33& axes, const PxVec3& position) - : column0(axes.column0, 0.0f), column1(axes.column1, 0.0f), column2(axes.column2, 0.0f), column3(position, 1.0f) + PX_CUDA_CALLABLE PxMat44T(const PxMat33T& axes, const PxVec3T& position) : + column0(axes.column0, Type(0.0)), + column1(axes.column1, Type(0.0)), + column2(axes.column2, Type(0.0)), + column3(position, Type(1.0)) { } - PX_CUDA_CALLABLE PxMat44(const PxTransform& t) + PX_CUDA_CALLABLE PxMat44T(const PxTransform& t) { - *this = PxMat44(PxMat33(t.q), t.p); + *this = PxMat44T(PxMat33T(t.q), t.p); } /** \brief returns true if the two matrices are exactly equal */ - PX_CUDA_CALLABLE PX_INLINE bool operator==(const PxMat44& m) const + PX_CUDA_CALLABLE PX_INLINE bool operator==(const PxMat44T& m) const { return column0 == m.column0 && column1 == m.column1 && column2 == m.column2 && column3 == m.column3; } //! Copy constructor - PX_CUDA_CALLABLE PX_INLINE PxMat44(const PxMat44& other) - : column0(other.column0), column1(other.column1), column2(other.column2), column3(other.column3) + PX_CUDA_CALLABLE PX_INLINE PxMat44T(const PxMat44T& other) : + column0(other.column0), + column1(other.column1), + column2(other.column2), + column3(other.column3) { } //! Assignment operator - PX_CUDA_CALLABLE PX_INLINE PxMat44& operator=(const PxMat44& other) + PX_CUDA_CALLABLE PX_INLINE PxMat44T& operator=(const PxMat44T& other) { column0 = other.column0; column1 = other.column1; @@ -180,54 +191,52 @@ class PxMat44 } //! Get transposed matrix - PX_CUDA_CALLABLE PX_INLINE const PxMat44 getTranspose() const + PX_CUDA_CALLABLE PX_INLINE const PxMat44T getTranspose() const { - return PxMat44( - PxVec4(column0.x, column1.x, column2.x, column3.x), PxVec4(column0.y, column1.y, column2.y, column3.y), - PxVec4(column0.z, column1.z, column2.z, column3.z), PxVec4(column0.w, column1.w, column2.w, column3.w)); + return PxMat44T( + PxVec4T(column0.x, column1.x, column2.x, column3.x), PxVec4T(column0.y, column1.y, column2.y, column3.y), + PxVec4T(column0.z, column1.z, column2.z, column3.z), PxVec4T(column0.w, column1.w, column2.w, column3.w)); } //! Unary minus - PX_CUDA_CALLABLE PX_INLINE const PxMat44 operator-() const + PX_CUDA_CALLABLE PX_INLINE const PxMat44T operator-() const { - return PxMat44(-column0, -column1, -column2, -column3); + return PxMat44T(-column0, -column1, -column2, -column3); } //! Add - PX_CUDA_CALLABLE PX_INLINE const PxMat44 operator+(const PxMat44& other) const + PX_CUDA_CALLABLE PX_INLINE const PxMat44T operator+(const PxMat44T& other) const { - return PxMat44(column0 + other.column0, column1 + other.column1, column2 + other.column2, - column3 + other.column3); + return PxMat44T(column0 + other.column0, column1 + other.column1, column2 + other.column2, column3 + other.column3); } //! Subtract - PX_CUDA_CALLABLE PX_INLINE const PxMat44 operator-(const PxMat44& other) const + PX_CUDA_CALLABLE PX_INLINE const PxMat44T operator-(const PxMat44T& other) const { - return PxMat44(column0 - other.column0, column1 - other.column1, column2 - other.column2, - column3 - other.column3); + return PxMat44T(column0 - other.column0, column1 - other.column1, column2 - other.column2, column3 - other.column3); } //! Scalar multiplication - PX_CUDA_CALLABLE PX_INLINE const PxMat44 operator*(float scalar) const + PX_CUDA_CALLABLE PX_INLINE const PxMat44T operator*(Type scalar) const { - return PxMat44(column0 * scalar, column1 * scalar, column2 * scalar, column3 * scalar); + return PxMat44T(column0 * scalar, column1 * scalar, column2 * scalar, column3 * scalar); } - friend PxMat44 operator*(float, const PxMat44&); + template + friend PxMat44T operator*(Type2, const PxMat44T&); //! Matrix multiplication - PX_CUDA_CALLABLE PX_INLINE const PxMat44 operator*(const PxMat44& other) const + PX_CUDA_CALLABLE PX_INLINE const PxMat44T operator*(const PxMat44T& other) const { // Rows from this columns from other // column0 = transform(other.column0) etc - return PxMat44(transform(other.column0), transform(other.column1), transform(other.column2), - transform(other.column3)); + return PxMat44T(transform(other.column0), transform(other.column1), transform(other.column2), transform(other.column3)); } // a = b operators //! Equals-add - PX_CUDA_CALLABLE PX_INLINE PxMat44& operator+=(const PxMat44& other) + PX_CUDA_CALLABLE PX_INLINE PxMat44T& operator+=(const PxMat44T& other) { column0 += other.column0; column1 += other.column1; @@ -237,7 +246,7 @@ class PxMat44 } //! Equals-sub - PX_CUDA_CALLABLE PX_INLINE PxMat44& operator-=(const PxMat44& other) + PX_CUDA_CALLABLE PX_INLINE PxMat44T& operator-=(const PxMat44T& other) { column0 -= other.column0; column1 -= other.column1; @@ -247,7 +256,7 @@ class PxMat44 } //! Equals scalar multiplication - PX_CUDA_CALLABLE PX_INLINE PxMat44& operator*=(float scalar) + PX_CUDA_CALLABLE PX_INLINE PxMat44T& operator*=(Type scalar) { column0 *= scalar; column1 *= scalar; @@ -257,81 +266,81 @@ class PxMat44 } //! Equals matrix multiplication - PX_CUDA_CALLABLE PX_INLINE PxMat44& operator*=(const PxMat44& other) + PX_CUDA_CALLABLE PX_INLINE PxMat44T& operator*=(const PxMat44T& other) { *this = *this * other; return *this; } //! Element access, mathematical way! - PX_CUDA_CALLABLE PX_FORCE_INLINE float operator()(unsigned int row, unsigned int col) const + PX_CUDA_CALLABLE PX_FORCE_INLINE Type operator()(PxU32 row, PxU32 col) const { return (*this)[col][row]; } //! Element access, mathematical way! - PX_CUDA_CALLABLE PX_FORCE_INLINE float& operator()(unsigned int row, unsigned int col) + PX_CUDA_CALLABLE PX_FORCE_INLINE Type& operator()(PxU32 row, PxU32 col) { return (*this)[col][row]; } //! Transform vector by matrix, equal to v' = M*v - PX_CUDA_CALLABLE PX_INLINE const PxVec4 transform(const PxVec4& other) const + PX_CUDA_CALLABLE PX_INLINE const PxVec4T transform(const PxVec4T& other) const { return column0 * other.x + column1 * other.y + column2 * other.z + column3 * other.w; } //! Transform vector by matrix, equal to v' = M*v - PX_CUDA_CALLABLE PX_INLINE const PxVec3 transform(const PxVec3& other) const + PX_CUDA_CALLABLE PX_INLINE const PxVec3T transform(const PxVec3T& other) const { - return transform(PxVec4(other, 1.0f)).getXYZ(); + return transform(PxVec4T(other, Type(1.0))).getXYZ(); } //! Rotate vector by matrix, equal to v' = M*v - PX_CUDA_CALLABLE PX_INLINE const PxVec4 rotate(const PxVec4& other) const + PX_CUDA_CALLABLE PX_INLINE const PxVec4T rotate(const PxVec4T& other) const { return column0 * other.x + column1 * other.y + column2 * other.z; // + column3*0; } //! Rotate vector by matrix, equal to v' = M*v - PX_CUDA_CALLABLE PX_INLINE const PxVec3 rotate(const PxVec3& other) const + PX_CUDA_CALLABLE PX_INLINE const PxVec3T rotate(const PxVec3T& other) const { - return rotate(PxVec4(other, 1.0f)).getXYZ(); + return rotate(PxVec4T(other, Type(1.0))).getXYZ(); } - PX_CUDA_CALLABLE PX_INLINE const PxVec3 getBasis(int num) const + PX_CUDA_CALLABLE PX_INLINE const PxVec3T getBasis(PxU32 num) const { - PX_SHARED_ASSERT(num >= 0 && num < 3); + PX_ASSERT(num < 3); return (&column0)[num].getXYZ(); } - PX_CUDA_CALLABLE PX_INLINE const PxVec3 getPosition() const + PX_CUDA_CALLABLE PX_INLINE const PxVec3T getPosition() const { return column3.getXYZ(); } - PX_CUDA_CALLABLE PX_INLINE void setPosition(const PxVec3& position) + PX_CUDA_CALLABLE PX_INLINE void setPosition(const PxVec3T& position) { column3.x = position.x; column3.y = position.y; column3.z = position.z; } - PX_CUDA_CALLABLE PX_FORCE_INLINE const float* front() const + PX_CUDA_CALLABLE PX_FORCE_INLINE const Type* front() const { return &column0.x; } - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec4& operator[](unsigned int num) + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec4T& operator[](PxU32 num) { return (&column0)[num]; } - PX_CUDA_CALLABLE PX_FORCE_INLINE const PxVec4& operator[](unsigned int num) const + PX_CUDA_CALLABLE PX_FORCE_INLINE const PxVec4T& operator[](PxU32 num) const { return (&column0)[num]; } - PX_CUDA_CALLABLE PX_INLINE void scale(const PxVec4& p) + PX_CUDA_CALLABLE PX_INLINE void scale(const PxVec4T& p) { column0 *= p.x; column1 *= p.y; @@ -339,12 +348,13 @@ class PxMat44 column3 *= p.w; } - PX_CUDA_CALLABLE PX_INLINE const PxMat44 inverseRT(void) const + PX_CUDA_CALLABLE PX_INLINE const PxMat44T inverseRT(void) const { - PxVec3 r0(column0.x, column1.x, column2.x), r1(column0.y, column1.y, column2.y), - r2(column0.z, column1.z, column2.z); + const PxVec3T r0(column0.x, column1.x, column2.x); + const PxVec3T r1(column0.y, column1.y, column2.y); + const PxVec3T r2(column0.z, column1.z, column2.z); - return PxMat44(r0, r1, r2, -(r0 * column3.x + r1 * column3.y + r2 * column3.z)); + return PxMat44T(r0, r1, r2, -(r0 * column3.x + r1 * column3.y + r2 * column3.z)); } PX_CUDA_CALLABLE PX_INLINE bool isFinite() const @@ -354,23 +364,28 @@ class PxMat44 // Data, see above for format! - PxVec4 column0, column1, column2, column3; // the four base vectors + PxVec4T column0, column1, column2, column3; // the four base vectors }; // implementation from PxTransform.h -PX_CUDA_CALLABLE PX_FORCE_INLINE PxTransform::PxTransform(const PxMat44& m) +template +PX_CUDA_CALLABLE PX_FORCE_INLINE PxTransformT::PxTransformT(const PxMat44T& m) { - PxVec3 column0 = PxVec3(m.column0.x, m.column0.y, m.column0.z); - PxVec3 column1 = PxVec3(m.column1.x, m.column1.y, m.column1.z); - PxVec3 column2 = PxVec3(m.column2.x, m.column2.y, m.column2.z); + const PxVec3T column0(m.column0.x, m.column0.y, m.column0.z); + const PxVec3T column1(m.column1.x, m.column1.y, m.column1.z); + const PxVec3T column2(m.column2.x, m.column2.y, m.column2.z); - q = PxQuat(PxMat33(column0, column1, column2)); - p = PxVec3(m.column3.x, m.column3.y, m.column3.z); + q = PxQuatT(PxMat33T(column0, column1, column2)); + p = PxVec3T(m.column3.x, m.column3.y, m.column3.z); } +typedef PxMat44T PxMat44; +typedef PxMat44T PxMat44d; + #if !PX_DOXYGEN } // namespace physx #endif /** @} */ -#endif // #ifndef PXFOUNDATION_PXMAT44_H +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxMath.h b/Source/ThirdParty/PhysX/foundation/PxMath.h index d75d8bc37..cff5b1795 100644 --- a/Source/ThirdParty/PhysX/foundation/PxMath.h +++ b/Source/ThirdParty/PhysX/foundation/PxMath.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PXFOUNDATION_PXMATH_H -#define PXFOUNDATION_PXMATH_H +#ifndef PX_MATH_H +#define PX_MATH_H /** \addtogroup foundation @{ @@ -36,6 +35,7 @@ #include "foundation/PxPreprocessor.h" + #if PX_VC #pragma warning(push) #pragma warning(disable : 4985) // 'symbol name': attributes not present on previous declaration @@ -45,9 +45,15 @@ #pragma warning(pop) #endif +#if (PX_LINUX_FAMILY && !PX_ARM_FAMILY) +// Force linking against nothing newer than glibc v2.17 to remain compatible with platforms with older glibc versions +__asm__(".symver expf,expf@GLIBC_2.2.5"); +__asm__(".symver powf,powf@GLIBC_2.2.5"); +#endif + #include -#include "foundation/PxIntrinsics.h" -#include "foundation/PxSharedAssert.h" +#include "foundation/PxMathIntrinsics.h" +#include "foundation/PxAssert.h" #if !PX_DOXYGEN namespace physx @@ -62,6 +68,8 @@ static const float PxInvPi = float(0.31830988618379067154); static const float PxInvTwoPi = float(0.15915494309189533577); static const float PxPiDivTwo = float(1.57079632679489661923); static const float PxPiDivFour = float(0.78539816339744830962); +static const float PxSqrt2 = float(1.4142135623730951); +static const float PxInvSqrt2 = float(0.7071067811865476); /** \brief The return value is the greater of the two specified values. @@ -136,7 +144,7 @@ PX_CUDA_CALLABLE PX_FORCE_INLINE int32_t PxAbs(int32_t a) template PX_CUDA_CALLABLE PX_FORCE_INLINE T PxClamp(T v, T lo, T hi) { - PX_SHARED_ASSERT(lo <= hi); + PX_ASSERT(lo <= hi); return PxMin(hi, PxMax(lo, v)); } @@ -164,6 +172,12 @@ PX_CUDA_CALLABLE PX_FORCE_INLINE double PxRecipSqrt(double a) return 1 / ::sqrt(a); } +//! \brief square of the argument +PX_CUDA_CALLABLE PX_FORCE_INLINE PxF32 PxSqr(const PxF32 a) +{ + return a * a; +} + //! trigonometry -- all angles are in radians. //! \brief Sine of an angle ( Unit: Radians ) @@ -190,6 +204,24 @@ PX_CUDA_CALLABLE PX_FORCE_INLINE double PxCos(double a) return ::cos(a); } +//! \brief compute sine and cosine at the same time +PX_CUDA_CALLABLE PX_FORCE_INLINE void PxSinCos(const PxF32 a, PxF32& sin, PxF32& cos) +{ +#if defined(__CUDACC__) && __CUDA_ARCH__ >= 350 + __sincosf(a, &sin, &cos); +#else + sin = PxSin(a); + cos = PxCos(a); +#endif +} + +//! \brief compute sine and cosine at the same time +PX_CUDA_CALLABLE PX_FORCE_INLINE void PxSinCos(const double a, double& sin, double& cos) +{ + sin = PxSin(a); + cos = PxCos(a); +} + /** \brief Tangent of an angle. Unit: Radians @@ -288,6 +320,14 @@ PX_CUDA_CALLABLE PX_FORCE_INLINE double PxAtan2(double x, double y) return ::atan2(x, y); } +/** +\brief Converts degrees to radians. +*/ +PX_CUDA_CALLABLE PX_FORCE_INLINE PxF32 PxDegToRad(const PxF32 a) +{ + return 0.01745329251994329547f * a; +} + //! \brief returns true if the passed number is a finite floating point number as opposed to INF, NAN, etc. PX_CUDA_CALLABLE PX_FORCE_INLINE bool PxIsFinite(float f) { @@ -320,6 +360,11 @@ PX_CUDA_CALLABLE PX_FORCE_INLINE float PxSign(float a) return physx::intrinsics::sign(a); } +PX_CUDA_CALLABLE PX_FORCE_INLINE float PxSign2(float a, float eps = FLT_EPSILON) +{ + return (a < -eps) ? -1.0f : (a > eps) ? 1.0f : 0.0f; +} + PX_CUDA_CALLABLE PX_FORCE_INLINE float PxPow(float x, float y) { return ::powf(x, y); @@ -335,4 +380,5 @@ PX_CUDA_CALLABLE PX_FORCE_INLINE float PxLog(float x) #endif /** @} */ -#endif // #ifndef PXFOUNDATION_PXMATH_H +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/Ps.h b/Source/ThirdParty/PhysX/foundation/PxMathIntrinsics.h similarity index 64% rename from Source/ThirdParty/PhysX/foundation/Ps.h rename to Source/ThirdParty/PhysX/foundation/PxMathIntrinsics.h index ca4c50d09..8c56ce578 100644 --- a/Source/ThirdParty/PhysX/foundation/Ps.h +++ b/Source/ThirdParty/PhysX/foundation/PxMathIntrinsics.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,48 +22,31 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PSFOUNDATION_PS_H -#define PSFOUNDATION_PS_H +#ifndef PX_MATH_INTRINSICS_H +#define PX_MATH_INTRINSICS_H -/*! \file top level include file for shared foundation */ +#include "foundation/PxPreprocessor.h" -#include "foundation/Px.h" +#if PX_WINDOWS_FAMILY +#include "foundation/windows/PxWindowsMathIntrinsics.h" +#elif(PX_LINUX || PX_ANDROID || PX_APPLE_FAMILY) +#include "foundation/unix/PxUnixMathIntrinsics.h" +#elif PX_SWITCH +#include "foundation/switch/PxSwitchMathIntrinsics.h" +#else +#error "Platform not supported!" +#endif /** Platform specific defines */ -#if PX_WINDOWS_FAMILY || PX_XBOXONE -#pragma intrinsic(memcmp) -#pragma intrinsic(memcpy) -#pragma intrinsic(memset) +#if PX_WINDOWS_FAMILY #pragma intrinsic(abs) #pragma intrinsic(labs) #endif -// An expression that should expand to nothing in non PX_CHECKED builds. -// We currently use this only for tagging the purpose of containers for memory use tracking. -#if PX_CHECKED -#define PX_DEBUG_EXP(x) (x) -#else -#define PX_DEBUG_EXP(x) -#endif - -#define PX_SIGN_BITMASK 0x80000000 - -namespace physx -{ -namespace shdfnd -{ -// Int-as-bool type - has some uses for efficiency and with SIMD -typedef int IntBool; -static const IntBool IntFalse = 0; -static const IntBool IntTrue = 1; -} - -} // namespace physx - -#endif // #ifndef PSFOUNDATION_PS_H +#endif diff --git a/Source/ThirdParty/PhysX/foundation/PxMathUtils.h b/Source/ThirdParty/PhysX/foundation/PxMathUtils.h index 445439c0c..bfbf3b7be 100644 --- a/Source/ThirdParty/PhysX/foundation/PxMathUtils.h +++ b/Source/ThirdParty/PhysX/foundation/PxMathUtils.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,19 +22,22 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PXFOUNDATION_PXMATHUTILS_H -#define PXFOUNDATION_PXMATHUTILS_H +#ifndef PX_MATH_UTILS_H +#define PX_MATH_UTILS_H /** \addtogroup common @{ */ -#include "foundation/Px.h" #include "foundation/PxFoundationConfig.h" +#include "foundation/Px.h" +#include "foundation/PxVec4.h" +#include "foundation/PxAssert.h" +#include "foundation/PxPlane.h" #if !PX_DOXYGEN namespace physx @@ -49,7 +51,6 @@ namespace physx \param[in] target the vector to rotate to \return a rotation about an axis normal to the two vectors which takes one to the other via the shortest path */ - PX_FOUNDATION_API PxQuat PxShortestRotation(const PxVec3& from, const PxVec3& target); /* \brief diagonalizes a 3x3 symmetric matrix y @@ -63,9 +64,435 @@ If the matrix is not symmetric, the result is undefined. \param[out] axes a quaternion rotation which diagonalizes the matrix \return the vector diagonal of the diagonalized matrix. */ - PX_FOUNDATION_API PxVec3 PxDiagonalize(const PxMat33& m, PxQuat& axes); +/** \brief creates a transform from the endpoints of a segment, suitable for an actor transform for a PxCapsuleGeometry + +\param[in] p0 one end of major axis of the capsule +\param[in] p1 the other end of the axis of the capsule +\param[out] halfHeight the halfHeight of the capsule. This parameter is optional. +\return A PxTransform which will transform the vector (1,0,0) to the capsule axis shrunk by the halfHeight +*/ +PX_FOUNDATION_API PxTransform PxTransformFromSegment(const PxVec3& p0, const PxVec3& p1, PxReal* halfHeight = NULL); + +/** \brief creates a transform from a plane equation, suitable for an actor transform for a PxPlaneGeometry + +\param[in] plane the desired plane equation +\return a PxTransform which will transform the plane PxPlane(1,0,0,0) to the specified plane +*/ +PX_FOUNDATION_API PxTransform PxTransformFromPlaneEquation(const PxPlane& plane); + +/** \brief creates a plane equation from a transform, such as the actor transform for a PxPlaneGeometry + +\param[in] pose the transform +\return the plane +*/ +PX_INLINE PxPlane PxPlaneEquationFromTransform(const PxTransform& pose) +{ + return PxPlane(1.0f, 0.0f, 0.0f, 0.0f).transform(pose); +} + +/** +\brief Spherical linear interpolation of two quaternions. +\param[in] t is the interpolation parameter in range (0, 1) +\param[in] left is the start of the interpolation +\param[in] right is the end of the interpolation +\return Returns left when t=0, right when t=1 and a linear interpolation of left and right when 0 < t < 1. +Returns angle between -PI and PI in radians +*/ +PX_FOUNDATION_API PxQuat PxSlerp(const PxReal t, const PxQuat& left, const PxQuat& right); + +/** +\brief integrate transform. +\param[in] curTrans The current transform +\param[in] linvel Linear velocity +\param[in] angvel Angular velocity +\param[in] timeStep The time-step for integration +\param[out] result The integrated transform +*/ +PX_FOUNDATION_API void PxIntegrateTransform(const PxTransform& curTrans, const PxVec3& linvel, const PxVec3& angvel, + PxReal timeStep, PxTransform& result); + +//! \brief Compute the exponent of a PxVec3 +PX_CUDA_CALLABLE PX_FORCE_INLINE PxQuat PxExp(const PxVec3& v) +{ + const PxReal m = v.magnitudeSquared(); + return m < 1e-24f ? PxQuat(PxIdentity) : PxQuat(PxSqrt(m), v * PxRecipSqrt(m)); +} + +/** +\brief computes a oriented bounding box around the scaled basis. +\param basis Input = skewed basis, Output = (normalized) orthogonal basis. +\return Bounding box extent. +*/ +PX_FOUNDATION_API PxVec3 PxOptimizeBoundingBox(PxMat33& basis); + +/** +\brief return Returns the log of a PxQuat +*/ +PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 PxLog(const PxQuat& q) +{ + const PxReal s = q.getImaginaryPart().magnitude(); + if (s < 1e-12f) + return PxVec3(0.0f); + // force the half-angle to have magnitude <= pi/2 + PxReal halfAngle = q.w < 0 ? PxAtan2(-s, -q.w) : PxAtan2(s, q.w); + PX_ASSERT(halfAngle >= -PxPi / 2 && halfAngle <= PxPi / 2); + + return q.getImaginaryPart().getNormalized() * 2.f * halfAngle; +} + +/** +\brief return Returns 0 if v.x is largest element of v, 1 if v.y is largest element, 2 if v.z is largest element. +*/ +PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 PxLargestAxis(const PxVec3& v) +{ + PxU32 m = PxU32(v.y > v.x ? 1 : 0); + return v.z > v[m] ? 2 : m; +} + +/** +\brief Compute tan(theta/2) given sin(theta) and cos(theta) as inputs. +\param[in] sin has value sin(theta) +\param[in] cos has value cos(theta) +\return Returns tan(theta/2) +*/ +PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal PxTanHalf(PxReal sin, PxReal cos) +{ + // PT: avoids divide by zero for singularity. We return sqrt(FLT_MAX) instead of FLT_MAX + // to make sure the calling code doesn't generate INF values when manipulating the returned value + // (some joints multiply it by 4, etc). + if (cos == -1.0f) + return sin < 0.0f ? -sqrtf(FLT_MAX) : sqrtf(FLT_MAX); + + // PT: half-angle formula: tan(a/2) = sin(a)/(1+cos(a)) + return sin / (1.0f + cos); +} + +/** +\brief Compute the closest point on an 2d ellipse to a given 2d point. +\param[in] point is a 2d point in the y-z plane represented by (point.y, point.z) +\param[in] radii are the radii of the ellipse (radii.y and radii.z) in the y-z plane. +\return Returns the 2d position on the surface of the ellipse that is closest to point. +*/ +PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 PxEllipseClamp(const PxVec3& point, const PxVec3& radii) +{ + // lagrange multiplier method with Newton/Halley hybrid root-finder. + // see http://www.geometrictools.com/Documentation/DistancePointToEllipse2.pdf + // for proof of Newton step robustness and initial estimate. + // Halley converges much faster but sometimes overshoots - when that happens we take + // a newton step instead + + // converges in 1-2 iterations where D&C works well, and it's good with 4 iterations + // with any ellipse that isn't completely crazy + + const PxU32 MAX_ITERATIONS = 20; + const PxReal convergenceThreshold = 1e-4f; + + // iteration requires first quadrant but we recover generality later + + PxVec3 q(0, PxAbs(point.y), PxAbs(point.z)); + const PxReal tinyEps = 1e-6f; // very close to minor axis is numerically problematic but trivial + if (radii.y >= radii.z) + { + if (q.z < tinyEps) + return PxVec3(0, point.y > 0 ? radii.y : -radii.y, 0); + } + else + { + if (q.y < tinyEps) + return PxVec3(0, 0, point.z > 0 ? radii.z : -radii.z); + } + + PxVec3 denom, e2 = radii.multiply(radii), eq = radii.multiply(q); + + // we can use any initial guess which is > maximum(-e.y^2,-e.z^2) and for which f(t) is > 0. + // this guess works well near the axes, but is weak along the diagonals. + + PxReal t = PxMax(eq.y - e2.y, eq.z - e2.z); + + for (PxU32 i = 0; i < MAX_ITERATIONS; i++) + { + denom = PxVec3(0, 1 / (t + e2.y), 1 / (t + e2.z)); + PxVec3 denom2 = eq.multiply(denom); + + PxVec3 fv = denom2.multiply(denom2); + PxReal f = fv.y + fv.z - 1; + + // although in exact arithmetic we are guaranteed f>0, we can get here + // on the first iteration via catastrophic cancellation if the point is + // very close to the origin. In that case we just behave as if f=0 + + if (f < convergenceThreshold) + return e2.multiply(point).multiply(denom); + + PxReal df = fv.dot(denom) * -2.0f; + t = t - f / df; + } + + // we didn't converge, so clamp what we have + PxVec3 r = e2.multiply(point).multiply(denom); + return r * PxRecipSqrt(PxSqr(r.y / radii.y) + PxSqr(r.z / radii.z)); +} + +/** +\brief Compute from an input quaternion q a pair of quaternions (swing, twist) such that +q = swing * twist +with the caveats that swing.x = twist.y = twist.z = 0. +\param[in] q is the quaternion to be decomposed into swing and twist quaternions. +\param[out] swing is the swing component of the quaternion decomposition. +\param[out] twist is the twist component of the quaternion decomposition. +*/ +PX_CUDA_CALLABLE PX_FORCE_INLINE void PxSeparateSwingTwist(const PxQuat& q, PxQuat& swing, PxQuat& twist) +{ + twist = q.x != 0.0f ? PxQuat(q.x, 0, 0, q.w).getNormalized() : PxQuat(PxIdentity); + swing = q * twist.getConjugate(); +} + +/** +\brief Compute the angle between two non-unit vectors +\param[in] v0 is one of the non-unit vectors +\param[in] v1 is the other of the two non-unit vectors +\return Returns the angle (in radians) between the two vector v0 and v1. +*/ +PX_CUDA_CALLABLE PX_FORCE_INLINE PxF32 PxComputeAngle(const PxVec3& v0, const PxVec3& v1) +{ + const PxF32 cos = v0.dot(v1); // |v0|*|v1|*Cos(Angle) + const PxF32 sin = (v0.cross(v1)).magnitude(); // |v0|*|v1|*Sin(Angle) + return PxAtan2(sin, cos); +} + +/** +\brief Compute two normalized vectors (right and up) that are perpendicular to an input normalized vector (dir). +\param[in] dir is a normalized vector that is used to compute the perpendicular vectors. +\param[out] right is the first of the two vectors perpendicular to dir +\param[out] up is the second of the two vectors perpendicular to dir +*/ +PX_INLINE void PxComputeBasisVectors(const PxVec3& dir, PxVec3& right, PxVec3& up) +{ + // Derive two remaining vectors + if (PxAbs(dir.y) <= 0.9999f) + { + right = PxVec3(dir.z, 0.0f, -dir.x); + right.normalize(); + + // PT: normalize not needed for 'up' because dir & right are unit vectors, + // and by construction the angle between them is 90 degrees (i.e. sin(angle)=1) + up = PxVec3(dir.y * right.z, dir.z * right.x - dir.x * right.z, -dir.y * right.x); + } + else + { + right = PxVec3(1.0f, 0.0f, 0.0f); + + up = PxVec3(0.0f, dir.z, -dir.y); + up.normalize(); + } +} + +/** +\brief Compute three normalized vectors (dir, right and up) that are parallel to (dir) and perpendicular to (right, up) the +normalized direction vector (p1 - p0)/||p1 - p0||. +\param[in] p0 is used to compute the normalized vector dir = (p1 - p0)/||p1 - p0||. +\param[in] p1 is used to compute the normalized vector dir = (p1 - p0)/||p1 - p0||. +\param[out] dir is the normalized vector (p1 - p0)/||p1 - p0||. +\param[out] right is the first of the two normalized vectors perpendicular to dir +\param[out] up is the second of the two normalized vectors perpendicular to dir +*/ +PX_INLINE void PxComputeBasisVectors(const PxVec3& p0, const PxVec3& p1, PxVec3& dir, PxVec3& right, PxVec3& up) +{ + // Compute the new direction vector + dir = p1 - p0; + dir.normalize(); + + // Derive two remaining vectors + PxComputeBasisVectors(dir, right, up); +} + + +/** +\brief Compute (i+1)%3 +*/ +PX_INLINE PxU32 PxGetNextIndex3(PxU32 i) +{ + return (i + 1 + (i >> 1)) & 3; +} + +PX_INLINE PX_CUDA_CALLABLE void computeBarycentric(const PxVec3& a, const PxVec3& b, const PxVec3& c, const PxVec3& d, const PxVec3& p, PxVec4& bary) +{ + const PxVec3 ba = b - a; + const PxVec3 ca = c - a; + const PxVec3 da = d - a; + const PxVec3 pa = p - a; + + const PxReal detBcd = ba.dot(ca.cross(da)); + const PxReal detPcd = pa.dot(ca.cross(da)); + + bary.y = detPcd / detBcd; + + const PxReal detBpd = ba.dot(pa.cross(da)); + bary.z = detBpd / detBcd; + + const PxReal detBcp = ba.dot(ca.cross(pa)); + + bary.w = detBcp / detBcd; + bary.x = 1 - bary.y - bary.z - bary.w; +} + +PX_INLINE PX_CUDA_CALLABLE void computeBarycentric(const PxVec3& a, const PxVec3& b, const PxVec3& c, const PxVec3& p, PxVec4& bary) +{ + const PxVec3 v0 = b - a; + const PxVec3 v1 = c - a; + const PxVec3 v2 = p - a; + + const float d00 = v0.dot(v0); + const float d01 = v0.dot(v1); + const float d11 = v1.dot(v1); + const float d20 = v2.dot(v0); + const float d21 = v2.dot(v1); + + const float denom = d00 * d11 - d01 * d01; + const float v = (d11 * d20 - d01 * d21) / denom; + const float w = (d00 * d21 - d01 * d20) / denom; + const float u = 1.f - v - w; + + bary.x = u; bary.y = v; bary.z = w; + bary.w = 0.f; +} + + +// lerp +struct Interpolation +{ + PX_INLINE PX_CUDA_CALLABLE static float PxLerp(float a, float b, float t) + { + return a + t * (b - a); + } + + PX_INLINE PX_CUDA_CALLABLE static PxReal PxBiLerp( + const PxReal f00, + const PxReal f10, + const PxReal f01, + const PxReal f11, + const PxReal tx, const PxReal ty) + { + return PxLerp( + PxLerp(f00, f10, tx), + PxLerp(f01, f11, tx), + ty); + } + + PX_INLINE PX_CUDA_CALLABLE static PxReal PxTriLerp( + const PxReal f000, + const PxReal f100, + const PxReal f010, + const PxReal f110, + const PxReal f001, + const PxReal f101, + const PxReal f011, + const PxReal f111, + const PxReal tx, + const PxReal ty, + const PxReal tz) + { + return PxLerp( + PxBiLerp(f000, f100, f010, f110, tx, ty), + PxBiLerp(f001, f101, f011, f111, tx, ty), + tz); + } + + PX_INLINE PX_CUDA_CALLABLE static PxU32 PxSDFIdx(PxU32 i, PxU32 j, PxU32 k, PxU32 nbX, PxU32 nbY) + { + return i + j * nbX + k * nbX*nbY; + } + + PX_INLINE PX_CUDA_CALLABLE static PxReal PxSDFSampleImpl(const PxReal* PX_RESTRICT sdf, const PxVec3& localPos, const PxVec3& sdfBoxLower, + const PxVec3& sdfBoxHigher, const PxReal sdfDx, const PxReal invSdfDx, const PxU32 dimX, const PxU32 dimY, const PxU32 dimZ, PxReal tolerance) + { + PxVec3 clampedGridPt = localPos.maximum(sdfBoxLower).minimum(sdfBoxHigher); + + const PxVec3 diff = (localPos - clampedGridPt); + + if (diff.magnitudeSquared() > tolerance*tolerance) + return PX_MAX_F32; + + PxVec3 f = (clampedGridPt - sdfBoxLower) * invSdfDx; + + PxU32 i = PxU32(f.x); + PxU32 j = PxU32(f.y); + PxU32 k = PxU32(f.z); + + f -= PxVec3(PxReal(i), PxReal(j), PxReal(k)); + + if (i >= (dimX - 1)) + { + i = dimX - 2; + clampedGridPt.x -= f.x * sdfDx; + f.x = 1.f; + } + if (j >= (dimY - 1)) + { + j = dimY - 2; + clampedGridPt.y -= f.y * sdfDx; + f.y = 1.f; + } + if (k >= (dimZ - 1)) + { + k = dimZ - 2; + clampedGridPt.z -= f.z * sdfDx; + f.z = 1.f; + } + + const PxReal s000 = sdf[Interpolation::PxSDFIdx(i, j, k, dimX, dimY)]; + const PxReal s100 = sdf[Interpolation::PxSDFIdx(i + 1, j, k, dimX, dimY)]; + const PxReal s010 = sdf[Interpolation::PxSDFIdx(i, j + 1, k, dimX, dimY)]; + const PxReal s110 = sdf[Interpolation::PxSDFIdx(i + 1, j + 1, k, dimX, dimY)]; + const PxReal s001 = sdf[Interpolation::PxSDFIdx(i, j, k + 1, dimX, dimY)]; + const PxReal s101 = sdf[Interpolation::PxSDFIdx(i + 1, j, k + 1, dimX, dimY)]; + const PxReal s011 = sdf[Interpolation::PxSDFIdx(i, j + 1, k + 1, dimX, dimY)]; + const PxReal s111 = sdf[Interpolation::PxSDFIdx(i + 1, j + 1, k + 1, dimX, dimY)]; + + PxReal dist = PxTriLerp( + s000, + s100, + s010, + s110, + s001, + s101, + s011, + s111, + f.x, f.y, f.z); + + dist += diff.magnitude(); + + return dist; + } + +}; + +PX_INLINE PX_CUDA_CALLABLE PxReal PxSdfSample(const PxReal* PX_RESTRICT sdf, const PxVec3& localPos, const PxVec3& sdfBoxLower, + const PxVec3& sdfBoxHigher, const PxReal sdfDx, const PxReal invSdfDx, const PxU32 dimX, const PxU32 dimY, const PxU32 dimZ, PxVec3& gradient, PxReal tolerance = PX_MAX_F32) +{ + + PxReal dist = Interpolation::PxSDFSampleImpl(sdf, localPos, sdfBoxLower, sdfBoxHigher, sdfDx, invSdfDx, dimX, dimY, dimZ, tolerance); + + if (dist < tolerance) + { + + PxVec3 grad; + grad.x = Interpolation::PxSDFSampleImpl(sdf, localPos + PxVec3(sdfDx, 0.f, 0.f), sdfBoxLower, sdfBoxHigher, sdfDx, invSdfDx, dimX, dimY, dimZ, tolerance) - + Interpolation::PxSDFSampleImpl(sdf, localPos - PxVec3(sdfDx, 0.f, 0.f), sdfBoxLower, sdfBoxHigher, sdfDx, invSdfDx, dimX, dimY, dimZ, tolerance); + grad.y = Interpolation::PxSDFSampleImpl(sdf, localPos + PxVec3(0.f, sdfDx, 0.f), sdfBoxLower, sdfBoxHigher, sdfDx, invSdfDx, dimX, dimY, dimZ, tolerance) - + Interpolation::PxSDFSampleImpl(sdf, localPos - PxVec3(0.f, sdfDx, 0.f), sdfBoxLower, sdfBoxHigher, sdfDx, invSdfDx, dimX, dimY, dimZ, tolerance); + grad.z = Interpolation::PxSDFSampleImpl(sdf, localPos + PxVec3(0.f, 0.f, sdfDx), sdfBoxLower, sdfBoxHigher, sdfDx, invSdfDx, dimX, dimY, dimZ, tolerance) - + Interpolation::PxSDFSampleImpl(sdf, localPos - PxVec3(0.f, 0.f, sdfDx), sdfBoxLower, sdfBoxHigher, sdfDx, invSdfDx, dimX, dimY, dimZ, tolerance); + + gradient = grad; + + } + + return dist; +} + #if !PX_DOXYGEN } // namespace physx #endif diff --git a/Source/ThirdParty/PhysX/foundation/PxMemory.h b/Source/ThirdParty/PhysX/foundation/PxMemory.h index 911b0d48f..750a5faef 100644 --- a/Source/ThirdParty/PhysX/foundation/PxMemory.h +++ b/Source/ThirdParty/PhysX/foundation/PxMemory.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,19 +22,19 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PXFOUNDATION_PXMEMORY_H -#define PXFOUNDATION_PXMEMORY_H +#ifndef PX_MEMORY_H +#define PX_MEMORY_H /** \addtogroup foundation @{ */ #include "foundation/Px.h" -#include "foundation/PxIntrinsics.h" +#include "foundation/PxMathIntrinsics.h" #include "foundation/PxSimpleTypes.h" #if !PX_DOXYGEN @@ -43,68 +42,86 @@ namespace physx { #endif -/** -\brief Sets the bytes of the provided buffer to zero. + /** + \brief Sets the bytes of the provided buffer to zero. -\param dest Pointer to block of memory to set zero. -\param count Number of bytes to set to zero. + \param dest [out] Pointer to block of memory to set zero. + \param count [in] Number of bytes to set to zero. -\return Pointer to memory block (same as input) -*/ -PX_FORCE_INLINE void* PxMemZero(void* dest, PxU32 count) -{ - return physx::intrinsics::memZero(dest, count); -} + \return Pointer to memory block (same as input) + */ + PX_FORCE_INLINE void* PxMemZero(void* dest, PxU32 count) + { + return physx::intrinsics::memZero(dest, count); + } -/** -\brief Sets the bytes of the provided buffer to the specified value. + /** + \brief Sets the bytes of the provided buffer to the specified value. -\param dest Pointer to block of memory to set to the specified value. -\param c Value to set the bytes of the block of memory to. -\param count Number of bytes to set to the specified value. + \param dest [out] Pointer to block of memory to set to the specified value. + \param c [in] Value to set the bytes of the block of memory to. + \param count [in] Number of bytes to set to the specified value. -\return Pointer to memory block (same as input) -*/ -PX_FORCE_INLINE void* PxMemSet(void* dest, PxI32 c, PxU32 count) -{ - return physx::intrinsics::memSet(dest, c, count); -} + \return Pointer to memory block (same as input) + */ + PX_FORCE_INLINE void* PxMemSet(void* dest, PxI32 c, PxU32 count) + { + return physx::intrinsics::memSet(dest, c, count); + } -/** -\brief Copies the bytes of one memory block to another. The memory blocks must not overlap. + /** + \brief Copies the bytes of one memory block to another. The memory blocks must not overlap. -\note Use #PxMemMove if memory blocks overlap. + \note Use #PxMemMove if memory blocks overlap. -\param dest Pointer to block of memory to copy to. -\param src Pointer to block of memory to copy from. -\param count Number of bytes to copy. + \param dest [out] Pointer to block of memory to copy to. + \param src [in] Pointer to block of memory to copy from. + \param count [in] Number of bytes to copy. -\return Pointer to destination memory block -*/ -PX_FORCE_INLINE void* PxMemCopy(void* dest, const void* src, PxU32 count) -{ - return physx::intrinsics::memCopy(dest, src, count); -} + \return Pointer to destination memory block + */ + PX_FORCE_INLINE void* PxMemCopy(void* dest, const void* src, PxU32 count) + { + return physx::intrinsics::memCopy(dest, src, count); + } -/** -\brief Copies the bytes of one memory block to another. The memory blocks can overlap. + /** + \brief Copies the bytes of one memory block to another. The memory blocks can overlap. -\note Use #PxMemCopy if memory blocks do not overlap. + \note Use #PxMemCopy if memory blocks do not overlap. -\param dest Pointer to block of memory to copy to. -\param src Pointer to block of memory to copy from. -\param count Number of bytes to copy. + \param dest [out] Pointer to block of memory to copy to. + \param src [in] Pointer to block of memory to copy from. + \param count [in] Number of bytes to copy. -\return Pointer to destination memory block -*/ -PX_FORCE_INLINE void* PxMemMove(void* dest, const void* src, PxU32 count) -{ - return physx::intrinsics::memMove(dest, src, count); -} + \return Pointer to destination memory block + */ + PX_FORCE_INLINE void* PxMemMove(void* dest, const void* src, PxU32 count) + { + return physx::intrinsics::memMove(dest, src, count); + } + + /** + Mark a specified amount of memory with 0xcd pattern. This is used to check that the meta data + definition for serialized classes is complete in checked builds. + + \param ptr [out] Pointer to block of memory to initialize. + \param byteSize [in] Number of bytes to initialize. + */ + PX_INLINE void PxMarkSerializedMemory(void* ptr, PxU32 byteSize) + { +#if PX_CHECKED + PxMemSet(ptr, 0xcd, byteSize); +#else + PX_UNUSED(ptr); + PX_UNUSED(byteSize); +#endif + } #if !PX_DOXYGEN } // namespace physx #endif /** @} */ -#endif // PXFOUNDATION_PXMEMORY_H +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxMutex.h b/Source/ThirdParty/PhysX/foundation/PxMutex.h new file mode 100644 index 000000000..fcb8e021b --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxMutex.h @@ -0,0 +1,183 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_MUTEX_H +#define PX_MUTEX_H + +#include "foundation/PxAllocator.h" + +/* + * This inclusion is a best known fix for gcc 4.4.1 error: + * Creating object file for apex/src/PsAllocator.cpp ... + * In file included from apex/include/PsFoundation.h:30, + * from apex/src/PsAllocator.cpp:26: + * apex/include/PsMutex.h: In constructor 'physx::PxMutexT::MutexT(const Alloc&)': + * apex/include/PsMutex.h:92: error: no matching function for call to 'operator new(unsigned int, + * physx::PxMutexImpl*&)' + * :0: note: candidates are: void* operator new(unsigned int) + */ +#include + +#if !PX_DOXYGEN +namespace physx +{ +#endif +class PX_FOUNDATION_API PxMutexImpl +{ + public: + /** + The constructor for Mutex creates a mutex. It is initially unlocked. + */ + PxMutexImpl(); + + /** + The destructor for Mutex deletes the mutex. + */ + ~PxMutexImpl(); + + /** + Acquire (lock) the mutex. If the mutex is already locked + by another thread, this method blocks until the mutex is + unlocked. + */ + void lock(); + + /** + Acquire (lock) the mutex. If the mutex is already locked + by another thread, this method returns false without blocking. + */ + bool trylock(); + + /** + Release (unlock) the mutex. + */ + void unlock(); + + /** + Size of this class. + */ + static uint32_t getSize(); +}; + +template > +class PxMutexT : protected Alloc +{ + PX_NOCOPY(PxMutexT) + public: + class ScopedLock + { + PxMutexT& mMutex; + PX_NOCOPY(ScopedLock) + public: + PX_INLINE ScopedLock(PxMutexT& mutex) : mMutex(mutex) + { + mMutex.lock(); + } + PX_INLINE ~ScopedLock() + { + mMutex.unlock(); + } + }; + + /** + The constructor for Mutex creates a mutex. It is initially unlocked. + */ + PxMutexT(const Alloc& alloc = Alloc()) : Alloc(alloc) + { + mImpl = reinterpret_cast(Alloc::allocate(PxMutexImpl::getSize(), __FILE__, __LINE__)); + PX_PLACEMENT_NEW(mImpl, PxMutexImpl)(); + } + + /** + The destructor for Mutex deletes the mutex. + */ + ~PxMutexT() + { + mImpl->~PxMutexImpl(); + Alloc::deallocate(mImpl); + } + + /** + Acquire (lock) the mutex. If the mutex is already locked + by another thread, this method blocks until the mutex is + unlocked. + */ + PX_FORCE_INLINE void lock() const + { + mImpl->lock(); + } + + /** + Acquire (lock) the mutex. If the mutex is already locked + by another thread, this method returns false without blocking, + returns true if lock is successfully acquired + */ + PX_FORCE_INLINE bool trylock() const + { + return mImpl->trylock(); + } + + /** + Release (unlock) the mutex, the calling thread must have + previously called lock() or method will error + */ + PX_FORCE_INLINE void unlock() const + { + mImpl->unlock(); + } + + private: + PxMutexImpl* mImpl; +}; + +class PX_FOUNDATION_API PxReadWriteLock +{ + PX_NOCOPY(PxReadWriteLock) + public: + PxReadWriteLock(); + ~PxReadWriteLock(); + + // "takeLock" can only be false if the thread already holds the mutex, e.g. if it already acquired the write lock + void lockReader(bool takeLock); + void lockWriter(); + + void unlockReader(); + void unlockWriter(); + + private: + class ReadWriteLockImpl* mImpl; +}; + +typedef PxMutexT<> PxMutex; + +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif + diff --git a/Source/ThirdParty/PhysX/PxPhysicsVersion.h b/Source/ThirdParty/PhysX/foundation/PxPhysicsVersion.h similarity index 88% rename from Source/ThirdParty/PhysX/PxPhysicsVersion.h rename to Source/ThirdParty/PhysX/foundation/PxPhysicsVersion.h index 4f8c67c07..bab58af26 100644 --- a/Source/ThirdParty/PhysX/PxPhysicsVersion.h +++ b/Source/ThirdParty/PhysX/foundation/PxPhysicsVersion.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PX_PHYSICS_VERSION_NUMBER_H -#define PX_PHYSICS_VERSION_NUMBER_H +#ifndef PX_PHYSICS_VERSION_H +#define PX_PHYSICS_VERSION_H /* VersionNumbers: The combination of these @@ -49,9 +48,9 @@ sometimes they are stored in a byte. @{ */ -#define PX_PHYSICS_VERSION_MAJOR 4 +#define PX_PHYSICS_VERSION_MAJOR 5 #define PX_PHYSICS_VERSION_MINOR 1 -#define PX_PHYSICS_VERSION_BUGFIX 1 +#define PX_PHYSICS_VERSION_BUGFIX 3 /** The constant PX_PHYSICS_VERSION is used when creating certain PhysX module objects. @@ -59,7 +58,6 @@ This is to ensure that the application is using the same header version as the l */ #define PX_PHYSICS_VERSION ((PX_PHYSICS_VERSION_MAJOR<<24) + (PX_PHYSICS_VERSION_MINOR<<16) + (PX_PHYSICS_VERSION_BUGFIX<<8) + 0) - -#endif // PX_PHYSICS_VERSION_NUMBER_H +#endif /** @} */ diff --git a/Source/ThirdParty/PhysX/foundation/PxPinnedArray.h b/Source/ThirdParty/PhysX/foundation/PxPinnedArray.h new file mode 100644 index 000000000..020fb4383 --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxPinnedArray.h @@ -0,0 +1,53 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_PINNED_ARRAY_H +#define PX_PINNED_ARRAY_H + +#include "foundation/PxArray.h" +#include "foundation/PxAllocator.h" +#include "foundation/PxBounds3.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + template + using PxPinnedArray = PxArray; + + typedef PxArray PxBoundsArrayPinned; + typedef PxArray PxFloatArrayPinned; + typedef PxArray PxInt32ArrayPinned; + typedef PxArray PxInt8ArrayPinned; + +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxPlane.h b/Source/ThirdParty/PhysX/foundation/PxPlane.h index 76f63f2cd..a04186204 100644 --- a/Source/ThirdParty/PhysX/foundation/PxPlane.h +++ b/Source/ThirdParty/PhysX/foundation/PxPlane.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,19 +22,18 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PXFOUNDATION_PXPLANE_H -#define PXFOUNDATION_PXPLANE_H +#ifndef PX_PLANE_H +#define PX_PLANE_H /** \addtogroup foundation @{ */ -#include "foundation/PxMath.h" -#include "foundation/PxVec3.h" +#include "foundation/PxTransform.h" #if !PX_DOXYGEN namespace physx @@ -133,6 +131,24 @@ class PxPlane d *= denom; } + /** + \brief transform plane + */ + PX_CUDA_CALLABLE PX_FORCE_INLINE PxPlane transform(const PxTransform& pose) const + { + const PxVec3 transformedNormal = pose.rotate(n); + return PxPlane(transformedNormal, d - pose.p.dot(transformedNormal)); + } + + /** + \brief inverse-transform plane + */ + PX_CUDA_CALLABLE PX_FORCE_INLINE PxPlane inverseTransform(const PxTransform& pose) const + { + const PxVec3 transformedNormal = pose.rotateInv(n); + return PxPlane(transformedNormal, d + pose.p.dot(n)); + } + PxVec3 n; //!< The normal to the plane float d; //!< The distance from the origin }; @@ -142,4 +158,5 @@ class PxPlane #endif /** @} */ -#endif // #ifndef PXFOUNDATION_PXPLANE_H +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxPool.h b/Source/ThirdParty/PhysX/foundation/PxPool.h new file mode 100644 index 000000000..21c83678a --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxPool.h @@ -0,0 +1,269 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_POOL_H +#define PX_POOL_H + +#include "foundation/PxArray.h" +#include "foundation/PxSort.h" +#include "foundation/PxBasicTemplates.h" +#include "foundation/PxInlineArray.h" +#include "foundation/PxMemory.h" + +namespace physx +{ + +/*! +Simple allocation pool +*/ +template ::Type> +class PxPoolBase : public PxUserAllocated, public Alloc +{ + PX_NOCOPY(PxPoolBase) + protected: + PxPoolBase(const Alloc& alloc, uint32_t elementsPerSlab, uint32_t slabSize) + : Alloc(alloc), mSlabs(alloc), mElementsPerSlab(elementsPerSlab), mUsed(0), mSlabSize(slabSize), mFreeElement(0) + { + mSlabs.reserve(64); +#if PX_CLANG +#if PX_LINUX +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunused-local-typedef" +#endif // PX_LINUX +#endif // PX_CLANG + PX_COMPILE_TIME_ASSERT(sizeof(T) >= sizeof(size_t)); +#if PX_CLANG +#if PX_LINUX +#pragma clang diagnostic pop +#endif +#endif + } + + public: + ~PxPoolBase() + { + if(mUsed) + disposeElements(); + + for(void** slabIt = mSlabs.begin(), *slabEnd = mSlabs.end(); slabIt != slabEnd; ++slabIt) + Alloc::deallocate(*slabIt); + } + + // Allocate space for single object + PX_INLINE T* allocate() + { + if(mFreeElement == 0) + allocateSlab(); + T* p = reinterpret_cast(mFreeElement); + mFreeElement = mFreeElement->mNext; + mUsed++; + + PxMarkSerializedMemory(p, sizeof(T)); + return p; + } + + // Put space for a single element back in the lists + PX_INLINE void deallocate(T* p) + { + if(p) + { + PX_ASSERT(mUsed); + mUsed--; + push(reinterpret_cast(p)); + } + } + + PX_INLINE T* construct() + { + T* t = allocate(); + return t ? PX_PLACEMENT_NEW(t, T()) : NULL; + } + + template + PX_INLINE T* construct(A1& a) + { + T* t = allocate(); + return t ? PX_PLACEMENT_NEW(t, T(a)) : NULL; + } + + template + PX_INLINE T* construct(A1& a, A2& b) + { + T* t = allocate(); + return t ? PX_PLACEMENT_NEW(t, T(a, b)) : NULL; + } + + template + PX_INLINE T* construct(A1& a, A2& b, A3& c) + { + T* t = allocate(); + return t ? PX_PLACEMENT_NEW(t, T(a, b, c)) : NULL; + } + + template + PX_INLINE T* construct(A1* a, A2& b, A3& c) + { + T* t = allocate(); + return t ? PX_PLACEMENT_NEW(t, T(a, b, c)) : NULL; + } + + template + PX_INLINE T* construct(A1& a, A2& b, A3& c, A4& d) + { + T* t = allocate(); + return t ? PX_PLACEMENT_NEW(t, T(a, b, c, d)) : NULL; + } + + template + PX_INLINE T* construct(A1& a, A2& b, A3& c, A4& d, A5& e) + { + T* t = allocate(); + return t ? PX_PLACEMENT_NEW(t, T(a, b, c, d, e)) : NULL; + } + + template + PX_INLINE T* construct(A1& a, A2& b, A3& c, A4& d, A5& e, A6& f) + { + T* t = allocate(); + return t ? PX_PLACEMENT_NEW(t, T(a, b, c, d, e, f)) : NULL; + } + + template + PX_INLINE T* construct(A1& a, A2& b, A3& c, A4& d, A5& e, A6& f, A7& g) + { + T* t = allocate(); + return t ? PX_PLACEMENT_NEW(t, T(a, b, c, d, e, f, g)) : NULL; + } + + template + PX_INLINE T* construct(A1& a, A2& b, A3& c, A4& d, A5& e, A6& f, A7& g, A8& h) + { + T* t = allocate(); + return t ? PX_PLACEMENT_NEW(t, T(a, b, c, d, e, f, g, h)) : NULL; + } + + PX_INLINE void destroy(T* const p) + { + if(p) + { + p->~T(); + deallocate(p); + } + } + + protected: + struct FreeList + { + FreeList* mNext; + }; + + // All the allocated slabs, sorted by pointer + PxArray mSlabs; + + uint32_t mElementsPerSlab; + uint32_t mUsed; + uint32_t mSlabSize; + + FreeList* mFreeElement; // Head of free-list + + // Helper function to get bitmap of allocated elements + + void push(FreeList* p) + { + p->mNext = mFreeElement; + mFreeElement = p; + } + + // Allocate a slab and segregate it into the freelist + void allocateSlab() + { + T* slab = reinterpret_cast(Alloc::allocate(mSlabSize, __FILE__, __LINE__)); + + mSlabs.pushBack(slab); + + // Build a chain of nodes for the freelist + T* it = slab + mElementsPerSlab; + while(--it >= slab) + push(reinterpret_cast(it)); + } + + /* + Cleanup method. Go through all active slabs and call destructor for live objects, + then free their memory + */ + void disposeElements() + { + PxArray freeNodes(*this); + while(mFreeElement) + { + freeNodes.pushBack(mFreeElement); + mFreeElement = mFreeElement->mNext; + } + Alloc& alloc(*this); + PxSort(freeNodes.begin(), freeNodes.size(), PxLess(), alloc); + PxSort(mSlabs.begin(), mSlabs.size(), PxLess(), alloc); + + typename PxArray::Iterator slabIt = mSlabs.begin(), slabEnd = mSlabs.end(); + for(typename PxArray::Iterator freeIt = freeNodes.begin(); slabIt != slabEnd; ++slabIt) + { + for(T* tIt = reinterpret_cast(*slabIt), *tEnd = tIt + mElementsPerSlab; tIt != tEnd; ++tIt) + { + if(freeIt != freeNodes.end() && *freeIt == tIt) + ++freeIt; + else + tIt->~T(); + } + } + } +}; + +// original pool implementation +template ::Type> +class PxPool : public PxPoolBase +{ + public: + PxPool(const Alloc& alloc = Alloc(), uint32_t elementsPerSlab = 32) + : PxPoolBase(alloc, elementsPerSlab, elementsPerSlab * sizeof(T)) + { + } +}; + +// allows specification of the slab size instead of the occupancy +template ::Type> +class PxPool2 : public PxPoolBase +{ + public: + PxPool2(const Alloc& alloc = Alloc()) : PxPoolBase(alloc, slabSize / sizeof(T), slabSize) + { + } +}; + +} // namespace physx + +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxPreprocessor.h b/Source/ThirdParty/PhysX/foundation/PxPreprocessor.h index 3b7a8f37e..ab37b6ac4 100644 --- a/Source/ThirdParty/PhysX/foundation/PxPreprocessor.h +++ b/Source/ThirdParty/PhysX/foundation/PxPreprocessor.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PXFOUNDATION_PXPREPROCESSOR_H -#define PXFOUNDATION_PXPREPROCESSOR_H +#ifndef PX_PREPROCESSOR_H +#define PX_PREPROCESSOR_H #include #if !defined(PX_GENERATE_META_DATA) @@ -38,6 +37,10 @@ @{ */ +#ifndef PX_ENABLE_FEATURES_UNDER_CONSTRUCTION +#define PX_ENABLE_FEATURES_UNDER_CONSTRUCTION 0 +#endif + #define PX_STRINGIZE_HELPER(X) #X #define PX_STRINGIZE(X) PX_STRINGIZE_HELPER(X) @@ -53,20 +56,22 @@ All definitions have a value of 1 or 0, use '#if' instead of '#ifdef'. Compiler defines, see http://sourceforge.net/p/predef/wiki/Compilers/ */ #if defined(_MSC_VER) -#if _MSC_VER >= 1910 -#define PX_VC 15 +#if _MSC_VER >= 1920 + #define PX_VC 16 +#elif _MSC_VER >= 1910 + #define PX_VC 15 #elif _MSC_VER >= 1900 -#define PX_VC 14 + #define PX_VC 14 #elif _MSC_VER >= 1800 -#define PX_VC 12 + #define PX_VC 12 #elif _MSC_VER >= 1700 -#define PX_VC 11 + #define PX_VC 11 #elif _MSC_VER >= 1600 -#define PX_VC 10 + #define PX_VC 10 #elif _MSC_VER >= 1500 -#define PX_VC 9 + #define PX_VC 9 #else -#error "Unknown VC version" + #error "Unknown VC version" #endif #elif defined(__clang__) #define PX_CLANG 1 @@ -78,160 +83,158 @@ Compiler defines, see http://sourceforge.net/p/predef/wiki/Compilers/ #define PX_CLANG_MAJOR 0 #endif #elif defined(__GNUC__) // note: __clang__ implies __GNUC__ -#define PX_GCC 1 + #define PX_GCC 1 #else -#error "Unknown compiler" + #error "Unknown compiler" #endif /** Operating system defines, see http://sourceforge.net/p/predef/wiki/OperatingSystems/ */ -#if defined(_XBOX_ONE) -#define PX_XBOXONE 1 -#elif defined(WINAPI_FAMILY) && WINAPI_FAMILY == WINAPI_FAMILY_APP -#define PX_UWP 1 -#elif defined(_WIN64) // note: _XBOX_ONE implies _WIN64 -#define PX_WIN64 1 +#if defined(_WIN64) + #define PX_WIN64 1 #elif defined(_WIN32) // note: _M_PPC implies _WIN32 -#define PX_WIN32 1 + #define PX_WIN32 1 #elif defined(__ANDROID__) -#define PX_ANDROID 1 + #define PX_ANDROID 1 #elif defined(__linux__) || defined (__EMSCRIPTEN__) // note: __ANDROID__ implies __linux__ -#define PX_LINUX 1 -#elif defined(__APPLE__) && (defined(__arm__) || defined(__arm64__)) -#define PX_IOS 1 + #define PX_LINUX 1 #elif defined(__APPLE__) -#define PX_OSX 1 + #define PX_OSX 1 + #include + #if TARGET_OS_IPHONE + #define PX_IOS 1 + #elif TARGET_OS_OSX + #define PX_OSX 1 + #else + #error "Unknown Apple target OS" + #endif #elif defined(__PROSPERO__) -#define PX_PS4 1 -#define PX_PS5 1 + #define PX_PS5 1 #elif defined(__ORBIS__) -#define PX_PS4 1 + #define PX_PS4 1 #elif defined(__NX__) -#define PX_SWITCH 1 + #define PX_SWITCH 1 #else -#error "Unknown operating system" + #error "Unknown operating system" #endif /** Architecture defines, see http://sourceforge.net/p/predef/wiki/Architectures/ */ -#if defined(__x86_64__) || defined(_M_X64) // ps4 compiler defines _M_X64 without value -#define PX_X64 1 +#if defined(__x86_64__) || defined(_M_X64) + #define PX_X64 1 #elif defined(__i386__) || defined(_M_IX86) || defined (__EMSCRIPTEN__) -#define PX_X86 1 + #define PX_X86 1 #elif defined(__arm64__) || defined(__aarch64__) || defined(_M_ARM64) -#define PX_A64 1 + #define PX_A64 1 #elif defined(__arm__) || defined(_M_ARM) -#define PX_ARM 1 + #define PX_ARM 1 #elif defined(__ppc__) || defined(_M_PPC) || defined(__CELLOS_LV2__) -#define PX_PPC 1 + #define PX_PPC 1 #else -#error "Unknown architecture" + #error "Unknown architecture" #endif /** SIMD defines */ #if !defined(PX_SIMD_DISABLED) -#if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) || (defined (__EMSCRIPTEN__) && defined(__SSE2__)) -#define PX_SSE2 1 -#endif -#if defined(_M_ARM) || defined(__ARM_NEON__) || defined(__ARM_NEON) -#define PX_NEON 1 -#endif -#if defined(_M_PPC) || defined(__CELLOS_LV2__) -#define PX_VMX 1 -#endif + #if defined(__i386__) || defined(_M_IX86) || defined(__x86_64__) || defined(_M_X64) || (defined (__EMSCRIPTEN__) && defined(__SSE2__)) + #define PX_SSE2 1 + #endif + #if defined(_M_ARM) || defined(__ARM_NEON__) || defined(__ARM_NEON) + #define PX_NEON 1 + #endif + #if defined(_M_PPC) || defined(__CELLOS_LV2__) + #define PX_VMX 1 + #endif #endif /** define anything not defined on this platform to 0 */ #ifndef PX_VC -#define PX_VC 0 + #define PX_VC 0 #endif #ifndef PX_CLANG -#define PX_CLANG 0 + #define PX_CLANG 0 #endif #ifndef PX_GCC -#define PX_GCC 0 -#endif -#ifndef PX_XBOXONE -#define PX_XBOXONE 0 + #define PX_GCC 0 #endif #ifndef PX_WIN64 -#define PX_WIN64 0 + #define PX_WIN64 0 #endif #ifndef PX_WIN32 -#define PX_WIN32 0 + #define PX_WIN32 0 #endif #ifndef PX_ANDROID -#define PX_ANDROID 0 + #define PX_ANDROID 0 #endif #ifndef PX_LINUX -#define PX_LINUX 0 + #define PX_LINUX 0 #endif #ifndef PX_IOS -#define PX_IOS 0 + #define PX_IOS 0 #endif #ifndef PX_OSX -#define PX_OSX 0 + #define PX_OSX 0 #endif #ifndef PX_PS4 -#define PX_PS4 0 + #define PX_PS4 0 +#endif +#ifndef PX_PS5 + #define PX_PS5 0 #endif #ifndef PX_SWITCH -#define PX_SWITCH 0 -#endif -#ifndef PX_UWP -#define PX_UWP 0 + #define PX_SWITCH 0 #endif #ifndef PX_X64 -#define PX_X64 0 + #define PX_X64 0 #endif #ifndef PX_X86 -#define PX_X86 0 + #define PX_X86 0 #endif #ifndef PX_A64 -#define PX_A64 0 + #define PX_A64 0 #endif #ifndef PX_ARM -#define PX_ARM 0 + #define PX_ARM 0 #endif #ifndef PX_PPC -#define PX_PPC 0 + #define PX_PPC 0 #endif #ifndef PX_SSE2 -#define PX_SSE2 0 + #define PX_SSE2 0 #endif #ifndef PX_NEON -#define PX_NEON 0 + #define PX_NEON 0 #endif #ifndef PX_VMX -#define PX_VMX 0 + #define PX_VMX 0 #endif /* define anything not defined through the command line to 0 */ #ifndef PX_DEBUG -#define PX_DEBUG 0 + #define PX_DEBUG 0 #endif #ifndef PX_CHECKED -#define PX_CHECKED 0 + #define PX_CHECKED 0 #endif #ifndef PX_PROFILE -#define PX_PROFILE 0 + #define PX_PROFILE 0 #endif #ifndef PX_DEBUG_CRT -#define PX_DEBUG_CRT 0 + #define PX_DEBUG_CRT 0 #endif #ifndef PX_NVTX -#define PX_NVTX 0 + #define PX_NVTX 0 #endif #ifndef PX_DOXYGEN -#define PX_DOXYGEN 0 + #define PX_DOXYGEN 0 #endif /** @@ -240,15 +243,14 @@ family shortcuts // compiler #define PX_GCC_FAMILY (PX_CLANG || PX_GCC) // os -#define PX_WINDOWS_FAMILY (PX_WIN32 || PX_WIN64 || PX_UWP) -#define PX_MICROSOFT_FAMILY (PX_XBOXONE || PX_WINDOWS_FAMILY) +#define PX_WINDOWS_FAMILY (PX_WIN32 || PX_WIN64) #define PX_LINUX_FAMILY (PX_LINUX || PX_ANDROID) #define PX_APPLE_FAMILY (PX_IOS || PX_OSX) // equivalent to #if __APPLE__ #define PX_UNIX_FAMILY (PX_LINUX_FAMILY || PX_APPLE_FAMILY) // shortcut for unix/posix platforms #if defined(__EMSCRIPTEN__) -#define PX_EMSCRIPTEN 1 + #define PX_EMSCRIPTEN 1 #else -#define PX_EMSCRIPTEN 0 + #define PX_EMSCRIPTEN 0 #endif // architecture #define PX_INTEL_FAMILY (PX_X64 || PX_X86) @@ -258,10 +260,10 @@ family shortcuts /** C++ standard library defines */ -#if defined(_LIBCPP_VERSION) || PX_WIN64 || PX_WIN32 || PX_PS4 || PX_XBOXONE || PX_UWP || PX_EMSCRIPTEN -#define PX_LIBCPP 1 +#if defined(_LIBCPP_VERSION) || PX_WIN64 || PX_WIN32 || PX_PS4 || PX_PS5 || PX_EMSCRIPTEN + #define PX_LIBCPP 1 #else -#define PX_LIBCPP 0 + #define PX_LIBCPP 0 #endif // legacy define for PhysX @@ -271,111 +273,122 @@ C++ standard library defines Assert macro */ #ifndef PX_ENABLE_ASSERTS -#if PX_DEBUG && !defined(__CUDACC__) -#define PX_ENABLE_ASSERTS 1 -#else -#define PX_ENABLE_ASSERTS 0 -#endif + #if PX_DEBUG && !defined(__CUDACC__) + #define PX_ENABLE_ASSERTS 1 + #else + #define PX_ENABLE_ASSERTS 0 + #endif #endif /** DLL export macros */ #ifndef PX_C_EXPORT -#if PX_WINDOWS_FAMILY || PX_LINUX -#define PX_C_EXPORT extern "C" -#else -#define PX_C_EXPORT -#endif + #if PX_WINDOWS_FAMILY || PX_LINUX + #define PX_C_EXPORT extern "C" + #else + #define PX_C_EXPORT + #endif #endif #if PX_UNIX_FAMILY&& __GNUC__ >= 4 -#define PX_UNIX_EXPORT __attribute__((visibility("default"))) + #define PX_UNIX_EXPORT __attribute__((visibility("default"))) #else -#define PX_UNIX_EXPORT + #define PX_UNIX_EXPORT #endif -#if (PX_WINDOWS_FAMILY || PX_XBOXONE || PX_PS4) -#define PX_DLL_EXPORT __declspec(dllexport) -#define PX_DLL_IMPORT __declspec(dllimport) +#if (PX_WINDOWS_FAMILY || PX_PS4 || PX_PS5) + #define PX_DLL_EXPORT __declspec(dllexport) + #define PX_DLL_IMPORT __declspec(dllimport) #else -#define PX_DLL_EXPORT PX_UNIX_EXPORT -#define PX_DLL_IMPORT + #define PX_DLL_EXPORT PX_UNIX_EXPORT + #define PX_DLL_IMPORT #endif /** Calling convention */ #ifndef PX_CALL_CONV -#if PX_MICROSOFT_FAMILY -#define PX_CALL_CONV __cdecl -#else -#define PX_CALL_CONV -#endif + #if PX_WINDOWS_FAMILY + #define PX_CALL_CONV __cdecl + #else + #define PX_CALL_CONV + #endif #endif /** Pack macros - disabled on SPU because they are not supported */ #if PX_VC -#define PX_PUSH_PACK_DEFAULT __pragma(pack(push, 8)) -#define PX_POP_PACK __pragma(pack(pop)) + #define PX_PUSH_PACK_DEFAULT __pragma(pack(push, 8)) + #define PX_POP_PACK __pragma(pack(pop)) #elif PX_GCC_FAMILY -#define PX_PUSH_PACK_DEFAULT _Pragma("pack(push, 8)") -#define PX_POP_PACK _Pragma("pack(pop)") + #define PX_PUSH_PACK_DEFAULT _Pragma("pack(push, 8)") + #define PX_POP_PACK _Pragma("pack(pop)") #else -#define PX_PUSH_PACK_DEFAULT -#define PX_POP_PACK + #define PX_PUSH_PACK_DEFAULT + #define PX_POP_PACK #endif /** Inline macro */ #define PX_INLINE inline -#if PX_MICROSOFT_FAMILY -#pragma inline_depth(255) +#if PX_WINDOWS_FAMILY + #pragma inline_depth(255) #endif /** Force inline macro */ #if PX_VC -#define PX_FORCE_INLINE __forceinline + #define PX_FORCE_INLINE __forceinline #elif PX_LINUX // Workaround; Fedora Core 3 do not agree with force inline and PxcPool -#define PX_FORCE_INLINE inline + #define PX_FORCE_INLINE inline #elif PX_GCC_FAMILY -#define PX_FORCE_INLINE inline __attribute__((always_inline)) + #define PX_FORCE_INLINE inline __attribute__((always_inline)) #else -#define PX_FORCE_INLINE inline + #define PX_FORCE_INLINE inline #endif /** Noinline macro */ -#if PX_MICROSOFT_FAMILY -#define PX_NOINLINE __declspec(noinline) +#if PX_WINDOWS_FAMILY + #define PX_NOINLINE __declspec(noinline) #elif PX_GCC_FAMILY -#define PX_NOINLINE __attribute__((noinline)) + #define PX_NOINLINE __attribute__((noinline)) #else -#define PX_NOINLINE + #define PX_NOINLINE #endif /** Restrict macro */ #if defined(__CUDACC__) -#define PX_RESTRICT __restrict__ + #define PX_RESTRICT __restrict__ #else -#define PX_RESTRICT __restrict + #define PX_RESTRICT __restrict #endif /** Noalias macro */ -#if PX_MICROSOFT_FAMILY -#define PX_NOALIAS __declspec(noalias) +#if PX_WINDOWS_FAMILY + #define PX_NOALIAS __declspec(noalias) #else -#define PX_NOALIAS + #define PX_NOALIAS +#endif + +/** +Override macro +*/ +#if PX_WINDOWS_FAMILY + #define PX_OVERRIDE override +#else + // PT: we don't really need to support it on all platforms, as long as + // we compile the code on at least one platform that supports it. + #define PX_OVERRIDE #endif /** @@ -387,32 +400,31 @@ struct A { ... } PX_ALIGN_SUFFIX(16); This declaration style is parsed correctly by Visual Assist. - */ #ifndef PX_ALIGN -#if PX_MICROSOFT_FAMILY -#define PX_ALIGN(alignment, decl) __declspec(align(alignment)) decl -#define PX_ALIGN_PREFIX(alignment) __declspec(align(alignment)) -#define PX_ALIGN_SUFFIX(alignment) -#elif PX_GCC_FAMILY -#define PX_ALIGN(alignment, decl) decl __attribute__((aligned(alignment))) -#define PX_ALIGN_PREFIX(alignment) -#define PX_ALIGN_SUFFIX(alignment) __attribute__((aligned(alignment))) -#elif defined __CUDACC__ -#define PX_ALIGN(alignment, decl) __align__(alignment) decl -#define PX_ALIGN_PREFIX(alignment) -#define PX_ALIGN_SUFFIX(alignment) __align__(alignment)) -#else -#define PX_ALIGN(alignment, decl) -#define PX_ALIGN_PREFIX(alignment) -#define PX_ALIGN_SUFFIX(alignment) -#endif + #if PX_WINDOWS_FAMILY + #define PX_ALIGN(alignment, decl) __declspec(align(alignment)) decl + #define PX_ALIGN_PREFIX(alignment) __declspec(align(alignment)) + #define PX_ALIGN_SUFFIX(alignment) + #elif PX_GCC_FAMILY + #define PX_ALIGN(alignment, decl) decl __attribute__((aligned(alignment))) + #define PX_ALIGN_PREFIX(alignment) + #define PX_ALIGN_SUFFIX(alignment) __attribute__((aligned(alignment))) + #elif defined __CUDACC__ + #define PX_ALIGN(alignment, decl) __align__(alignment) decl + #define PX_ALIGN_PREFIX(alignment) + #define PX_ALIGN_SUFFIX(alignment) __align__(alignment)) + #else + #define PX_ALIGN(alignment, decl) + #define PX_ALIGN_PREFIX(alignment) + #define PX_ALIGN_SUFFIX(alignment) + #endif #endif /** Deprecated macro - To deprecate a function: Place PX_DEPRECATED at the start of the function header (leftmost word). -- To deprecate a 'typedef', a 'struct' or a 'class': Place PX_DEPRECATED directly after the keywords ('typdef', +- To deprecate a 'typedef', a 'struct' or a 'class': Place PX_DEPRECATED directly after the keywords ('typedef', 'struct', 'class'). Use these macro definitions to create warnings for deprecated functions @@ -426,36 +438,35 @@ General defines */ // static assert -#if(defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))) || (PX_PS4) || (PX_APPLE_FAMILY) || (PX_SWITCH) || (PX_CLANG && PX_ARM) -#define PX_COMPILE_TIME_ASSERT(exp) typedef char PX_CONCAT(PxCompileTimeAssert_Dummy, __COUNTER__)[(exp) ? 1 : -1] __attribute__((unused)) +#if(defined(__GNUC__) && (__GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 7))) || (PX_APPLE_FAMILY) || (PX_SWITCH || PX_PS4 || PX_PS5) || (PX_CLANG && PX_ARM) || (PX_CLANG && PX_A64) + #define PX_COMPILE_TIME_ASSERT(exp) typedef char PX_CONCAT(PxCompileTimeAssert_Dummy, __COUNTER__)[(exp) ? 1 : -1] __attribute__((unused)) #else -#define PX_COMPILE_TIME_ASSERT(exp) typedef char PxCompileTimeAssert_Dummy[(exp) ? 1 : -1] + #define PX_COMPILE_TIME_ASSERT(exp) typedef char PxCompileTimeAssert_Dummy[(exp) ? 1 : -1] #endif #if PX_GCC_FAMILY -#define PX_OFFSET_OF(X, Y) __builtin_offsetof(X, Y) + #define PX_OFFSET_OF(X, Y) __builtin_offsetof(X, Y) #else -#define PX_OFFSET_OF(X, Y) offsetof(X, Y) + #define PX_OFFSET_OF(X, Y) offsetof(X, Y) #endif #define PX_OFFSETOF_BASE 0x100 // casting the null ptr takes a special-case code path, which we don't want -#define PX_OFFSET_OF_RT(Class, Member) \ - (reinterpret_cast(&reinterpret_cast(PX_OFFSETOF_BASE)->Member) - size_t(PX_OFFSETOF_BASE)) +#define PX_OFFSET_OF_RT(Class, Member) (reinterpret_cast(&reinterpret_cast(PX_OFFSETOF_BASE)->Member) - size_t(PX_OFFSETOF_BASE)) // check that exactly one of NDEBUG and _DEBUG is defined #if !defined(NDEBUG) ^ defined(_DEBUG) -#error Exactly one of NDEBUG and _DEBUG needs to be defined! + #error Exactly one of NDEBUG and _DEBUG needs to be defined! #endif // make sure PX_CHECKED is defined in all _DEBUG configurations as well #if !PX_CHECKED && PX_DEBUG -#error PX_CHECKED must be defined when PX_DEBUG is defined + #error PX_CHECKED must be defined when PX_DEBUG is defined #endif #ifdef __CUDACC__ -#define PX_CUDA_CALLABLE __host__ __device__ + #define PX_CUDA_CALLABLE __host__ __device__ #else -#define PX_CUDA_CALLABLE + #define PX_CUDA_CALLABLE #endif // avoid unreferenced parameter warning @@ -470,69 +481,70 @@ PX_CUDA_CALLABLE PX_INLINE void PX_UNUSED(T const&) // This assert works on win32/win64, but may need further specialization on other platforms. // Some GCC compilers need the compiler flag -malign-double to be set. // Apparently the apple-clang-llvm compiler doesn't support malign-double. -#if PX_PS4 || PX_APPLE_FAMILY || (PX_CLANG && !PX_ARM) -struct PxPackValidation -{ - char _; - long a; -}; +#if PX_PS4 || PX_PS5 || (PX_CLANG && !PX_ARM) + struct PxPackValidation + { + char _; + long a; + }; #elif PX_ANDROID || (PX_CLANG && PX_ARM) -struct PxPackValidation -{ - char _; - double a; -}; + struct PxPackValidation + { + char _; + double a; + }; #else -struct PxPackValidation -{ - char _; - long long a; -}; + struct PxPackValidation + { + char _; + long long a; + }; #endif // clang (as of version 3.9) cannot align doubles on 8 byte boundary when compiling for Intel 32 bit target #if !PX_APPLE_FAMILY && !PX_EMSCRIPTEN && !(PX_CLANG && PX_X86) -PX_COMPILE_TIME_ASSERT(PX_OFFSET_OF(PxPackValidation, a) == 8); + PX_COMPILE_TIME_ASSERT(PX_OFFSET_OF(PxPackValidation, a) == 8); #endif // use in a cpp file to suppress LNK4221 #if PX_VC -#define PX_DUMMY_SYMBOL \ - namespace \ - { \ - char PxDummySymbol; \ - } + #define PX_DUMMY_SYMBOL \ + namespace \ + { \ + char PxDummySymbol; \ + } #else -#define PX_DUMMY_SYMBOL + #define PX_DUMMY_SYMBOL #endif #if PX_GCC_FAMILY -#define PX_WEAK_SYMBOL __attribute__((weak)) // this is to support SIMD constant merging in template specialization + #define PX_WEAK_SYMBOL __attribute__((weak)) // this is to support SIMD constant merging in template specialization #else -#define PX_WEAK_SYMBOL + #define PX_WEAK_SYMBOL #endif // Macro for avoiding default assignment and copy, because doing this by inheritance can increase class size on some // platforms. -#define PX_NOCOPY(Class) \ - \ -protected: \ - Class(const Class&); \ +#define PX_NOCOPY(Class) \ +protected: \ + Class(const Class&); \ Class& operator=(const Class&); +//#define DISABLE_CUDA_PHYSX #ifndef DISABLE_CUDA_PHYSX -//CUDA is currently supported only on windows -#define PX_SUPPORT_GPU_PHYSX ((PX_WINDOWS_FAMILY) || (PX_LINUX && PX_X64)) + //CUDA is currently supported on x86_64 windows and linux, and ARM_64 linux + #define PX_SUPPORT_GPU_PHYSX ((PX_X64 && (PX_WINDOWS_FAMILY || PX_LINUX)) || (PX_A64 && PX_LINUX)) #else -#define PX_SUPPORT_GPU_PHYSX 0 + #define PX_SUPPORT_GPU_PHYSX 0 #endif -#define PX_SUPPORT_COMPUTE_PHYSX 0 - #ifndef PX_SUPPORT_EXTERN_TEMPLATE -#define PX_SUPPORT_EXTERN_TEMPLATE ((!PX_ANDROID) && (PX_VC != 11)) + #define PX_SUPPORT_EXTERN_TEMPLATE ((!PX_ANDROID) && (PX_VC != 11)) #else -#define PX_SUPPORT_EXTERN_TEMPLATE 0 + #define PX_SUPPORT_EXTERN_TEMPLATE 0 #endif +#define PX_FL __FILE__, __LINE__ + /** @} */ -#endif // #ifndef PXFOUNDATION_PXPREPROCESSOR_H +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxProfiler.h b/Source/ThirdParty/PhysX/foundation/PxProfiler.h index a949b723c..b72a6b2f8 100644 --- a/Source/ThirdParty/PhysX/foundation/PxProfiler.h +++ b/Source/ThirdParty/PhysX/foundation/PxProfiler.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,15 +22,17 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. -#ifndef PXFOUNDATION_PXPROFILER_H -#define PXFOUNDATION_PXPROFILER_H +#ifndef PX_PROFILER_H +#define PX_PROFILER_H #include "foundation/Px.h" +#if !PX_DOXYGEN namespace physx { +#endif /** \brief The pure virtual callback interface for general purpose instrumentation and profiling of GameWorks modules as @@ -94,6 +95,9 @@ class PxProfileScoped bool mDetached; }; -} // end of physx namespace +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif -#endif // PXFOUNDATION_PXPROFILER_H diff --git a/Source/ThirdParty/PhysX/foundation/PxQuat.h b/Source/ThirdParty/PhysX/foundation/PxQuat.h index f29a37277..70d0ca6bd 100644 --- a/Source/ThirdParty/PhysX/foundation/PxQuat.h +++ b/Source/ThirdParty/PhysX/foundation/PxQuat.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PXFOUNDATION_PXQUAT_H -#define PXFOUNDATION_PXQUAT_H +#ifndef PX_QUAT_H +#define PX_QUAT_H /** \addtogroup foundation @{ @@ -43,36 +42,36 @@ namespace physx /** \brief This is a quaternion class. For more information on quaternion mathematics consult a mathematics source on complex numbers. - */ -class PxQuat +template +class PxQuatT { public: + /** \brief Default constructor, does not do any initialization. */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxQuat() + PX_CUDA_CALLABLE PX_FORCE_INLINE PxQuatT() { } //! identity constructor - PX_CUDA_CALLABLE PX_INLINE PxQuat(PxIDENTITY r) : x(0.0f), y(0.0f), z(0.0f), w(1.0f) + PX_CUDA_CALLABLE PX_FORCE_INLINE PxQuatT(PxIDENTITY) : x(Type(0.0)), y(Type(0.0)), z(Type(0.0)), w(Type(1.0)) { - PX_UNUSED(r); } /** \brief Constructor from a scalar: sets the real part w to the scalar value, and the imaginary parts (x,y,z) to zero */ - explicit PX_CUDA_CALLABLE PX_FORCE_INLINE PxQuat(float r) : x(0.0f), y(0.0f), z(0.0f), w(r) + explicit PX_CUDA_CALLABLE PX_FORCE_INLINE PxQuatT(Type r) : x(Type(0.0)), y(Type(0.0)), z(Type(0.0)), w(r) { } /** - \brief Constructor. Take note of the order of the elements! + \brief Constructor. Take note of the order of the elements! */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxQuat(float nx, float ny, float nz, float nw) : x(nx), y(ny), z(nz), w(nw) + PX_CUDA_CALLABLE PX_FORCE_INLINE PxQuatT(Type nx, Type ny, Type nz, Type nw) : x(nx), y(ny), z(nz), w(nw) { } @@ -85,12 +84,13 @@ class PxQuat Unit: Radians */ - PX_CUDA_CALLABLE PX_INLINE PxQuat(float angleRadians, const PxVec3& unitAxis) + PX_CUDA_CALLABLE PX_INLINE PxQuatT(Type angleRadians, const PxVec3T& unitAxis) { - PX_SHARED_ASSERT(PxAbs(1.0f - unitAxis.magnitude()) < 1e-3f); - const float a = angleRadians * 0.5f; - const float s = PxSin(a); - w = PxCos(a); + PX_ASSERT(PxAbs(Type(1.0) - unitAxis.magnitude()) < Type(1e-3)); + const Type a = angleRadians * Type(0.5); + + Type s; + PxSinCos(a, s, w); x = unitAxis.x * s; y = unitAxis.y * s; z = unitAxis.z * s; @@ -99,7 +99,7 @@ class PxQuat /** \brief Copy ctor. */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxQuat(const PxQuat& v) : x(v.x), y(v.y), z(v.z), w(v.w) + PX_CUDA_CALLABLE PX_FORCE_INLINE PxQuatT(const PxQuatT& v) : x(v.x), y(v.y), z(v.z), w(v.w) { } @@ -108,14 +108,14 @@ class PxQuat \param[in] m Rotation matrix to extract quaternion from. */ - PX_CUDA_CALLABLE PX_INLINE explicit PxQuat(const PxMat33& m); /* defined in PxMat33.h */ + PX_CUDA_CALLABLE PX_INLINE explicit PxQuatT(const PxMat33T& m); /* defined in PxMat33.h */ /** \brief returns true if quat is identity */ PX_CUDA_CALLABLE PX_FORCE_INLINE bool isIdentity() const { - return x==0.0f && y==0.0f && z==0.0f && w==1.0f; + return x==Type(0.0) && y==Type(0.0) && z==Type(0.0) && w==Type(1.0); } /** @@ -131,8 +131,8 @@ class PxQuat */ PX_CUDA_CALLABLE bool isUnit() const { - const float unitTolerance = 1e-4f; - return isFinite() && PxAbs(magnitude() - 1) < unitTolerance; + const Type unitTolerance = Type(1e-3); + return isFinite() && PxAbs(magnitude() - Type(1.0)) < unitTolerance; } /** @@ -141,14 +141,14 @@ class PxQuat */ PX_CUDA_CALLABLE bool isSane() const { - const float unitTolerance = 1e-2f; - return isFinite() && PxAbs(magnitude() - 1) < unitTolerance; + const Type unitTolerance = Type(1e-2); + return isFinite() && PxAbs(magnitude() - Type(1.0)) < unitTolerance; } /** \brief returns true if the two quaternions are exactly equal */ - PX_CUDA_CALLABLE PX_INLINE bool operator==(const PxQuat& q) const + PX_CUDA_CALLABLE PX_FORCE_INLINE bool operator==(const PxQuatT& q) const { return x == q.x && y == q.y && z == q.z && w == q.w; } @@ -156,20 +156,20 @@ class PxQuat /** \brief converts this quaternion to angle-axis representation */ - PX_CUDA_CALLABLE PX_INLINE void toRadiansAndUnitAxis(float& angle, PxVec3& axis) const + PX_CUDA_CALLABLE PX_INLINE void toRadiansAndUnitAxis(Type& angle, PxVec3T& axis) const { - const float quatEpsilon = 1.0e-8f; - const float s2 = x * x + y * y + z * z; + const Type quatEpsilon = Type(1.0e-8); + const Type s2 = x * x + y * y + z * z; if(s2 < quatEpsilon * quatEpsilon) // can't extract a sensible axis { - angle = 0.0f; - axis = PxVec3(1.0f, 0.0f, 0.0f); + angle = Type(0.0); + axis = PxVec3T(Type(1.0), Type(0.0), Type(0.0)); } else { - const float s = PxRecipSqrt(s2); - axis = PxVec3(x, y, z) * s; - angle = PxAbs(w) < quatEpsilon ? PxPi : PxAtan2(s2 * s, w) * 2.0f; + const Type s = PxRecipSqrt(s2); + axis = PxVec3T(x, y, z) * s; + angle = PxAbs(w) < quatEpsilon ? Type(PxPi) : PxAtan2(s2 * s, w) * Type(2.0); } } @@ -178,9 +178,9 @@ class PxQuat Unit: Radians */ - PX_CUDA_CALLABLE PX_INLINE float getAngle() const + PX_CUDA_CALLABLE PX_FORCE_INLINE Type getAngle() const { - return PxAcos(w) * 2.0f; + return PxAcos(w) * Type(2.0); } /** @@ -188,15 +188,15 @@ class PxQuat Unit: Radians */ - PX_CUDA_CALLABLE PX_INLINE float getAngle(const PxQuat& q) const + PX_CUDA_CALLABLE PX_FORCE_INLINE Type getAngle(const PxQuatT& q) const { - return PxAcos(dot(q)) * 2.0f; + return PxAcos(dot(q)) * Type(2.0); } /** \brief This is the squared 4D vector length, should be 1 for unit quaternions. */ - PX_CUDA_CALLABLE PX_FORCE_INLINE float magnitudeSquared() const + PX_CUDA_CALLABLE PX_FORCE_INLINE Type magnitudeSquared() const { return x * x + y * y + z * z + w * w; } @@ -204,18 +204,18 @@ class PxQuat /** \brief returns the scalar product of this and other. */ - PX_CUDA_CALLABLE PX_FORCE_INLINE float dot(const PxQuat& v) const + PX_CUDA_CALLABLE PX_FORCE_INLINE Type dot(const PxQuatT& v) const { return x * v.x + y * v.y + z * v.z + w * v.w; } - PX_CUDA_CALLABLE PX_INLINE PxQuat getNormalized() const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxQuatT getNormalized() const { - const float s = 1.0f / magnitude(); - return PxQuat(x * s, y * s, z * s, w * s); + const Type s = Type(1.0) / magnitude(); + return PxQuatT(x * s, y * s, z * s, w * s); } - PX_CUDA_CALLABLE PX_INLINE float magnitude() const + PX_CUDA_CALLABLE PX_FORCE_INLINE Type magnitude() const { return PxSqrt(magnitudeSquared()); } @@ -224,12 +224,12 @@ class PxQuat /** \brief maps to the closest unit quaternion. */ - PX_CUDA_CALLABLE PX_INLINE float normalize() // convert this PxQuat to a unit quaternion + PX_CUDA_CALLABLE PX_FORCE_INLINE Type normalize() // convert this PxQuatT to a unit quaternion { - const float mag = magnitude(); - if(mag != 0.0f) + const Type mag = magnitude(); + if(mag != Type(0.0)) { - const float imag = 1.0f / mag; + const Type imag = Type(1.0) / mag; x *= imag; y *= imag; @@ -244,75 +244,75 @@ class PxQuat \note for unit quaternions, this is the inverse. */ - PX_CUDA_CALLABLE PX_INLINE PxQuat getConjugate() const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxQuatT getConjugate() const { - return PxQuat(-x, -y, -z, w); + return PxQuatT(-x, -y, -z, w); } /* \brief returns imaginary part. */ - PX_CUDA_CALLABLE PX_INLINE PxVec3 getImaginaryPart() const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T getImaginaryPart() const { - return PxVec3(x, y, z); + return PxVec3T(x, y, z); } /** brief computes rotation of x-axis */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 getBasisVector0() const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T getBasisVector0() const { - const float x2 = x * 2.0f; - const float w2 = w * 2.0f; - return PxVec3((w * w2) - 1.0f + x * x2, (z * w2) + y * x2, (-y * w2) + z * x2); + const Type x2 = x * Type(2.0); + const Type w2 = w * Type(2.0); + return PxVec3T((w * w2) - Type(1.0) + x * x2, (z * w2) + y * x2, (-y * w2) + z * x2); } /** brief computes rotation of y-axis */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 getBasisVector1() const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T getBasisVector1() const { - const float y2 = y * 2.0f; - const float w2 = w * 2.0f; - return PxVec3((-z * w2) + x * y2, (w * w2) - 1.0f + y * y2, (x * w2) + z * y2); + const Type y2 = y * Type(2.0); + const Type w2 = w * Type(2.0); + return PxVec3T((-z * w2) + x * y2, (w * w2) - Type(1.0) + y * y2, (x * w2) + z * y2); } /** brief computes rotation of z-axis */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 getBasisVector2() const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T getBasisVector2() const { - const float z2 = z * 2.0f; - const float w2 = w * 2.0f; - return PxVec3((y * w2) + x * z2, (-x * w2) + y * z2, (w * w2) - 1.0f + z * z2); + const Type z2 = z * Type(2.0); + const Type w2 = w * Type(2.0); + return PxVec3T((y * w2) + x * z2, (-x * w2) + y * z2, (w * w2) - Type(1.0) + z * z2); } /** rotates passed vec by this (assumed unitary) */ - PX_CUDA_CALLABLE PX_FORCE_INLINE const PxVec3 rotate(const PxVec3& v) const + PX_CUDA_CALLABLE PX_FORCE_INLINE const PxVec3T rotate(const PxVec3T& v) const { - const float vx = 2.0f * v.x; - const float vy = 2.0f * v.y; - const float vz = 2.0f * v.z; - const float w2 = w * w - 0.5f; - const float dot2 = (x * vx + y * vy + z * vz); - return PxVec3((vx * w2 + (y * vz - z * vy) * w + x * dot2), (vy * w2 + (z * vx - x * vz) * w + y * dot2), - (vz * w2 + (x * vy - y * vx) * w + z * dot2)); + const Type vx = Type(2.0) * v.x; + const Type vy = Type(2.0) * v.y; + const Type vz = Type(2.0) * v.z; + const Type w2 = w * w - 0.5f; + const Type dot2 = (x * vx + y * vy + z * vz); + return PxVec3T((vx * w2 + (y * vz - z * vy) * w + x * dot2), (vy * w2 + (z * vx - x * vz) * w + y * dot2), + (vz * w2 + (x * vy - y * vx) * w + z * dot2)); } /** inverse rotates passed vec by this (assumed unitary) */ - PX_CUDA_CALLABLE PX_FORCE_INLINE const PxVec3 rotateInv(const PxVec3& v) const + PX_CUDA_CALLABLE PX_FORCE_INLINE const PxVec3T rotateInv(const PxVec3T& v) const { - const float vx = 2.0f * v.x; - const float vy = 2.0f * v.y; - const float vz = 2.0f * v.z; - const float w2 = w * w - 0.5f; - const float dot2 = (x * vx + y * vy + z * vz); - return PxVec3((vx * w2 - (y * vz - z * vy) * w + x * dot2), (vy * w2 - (z * vx - x * vz) * w + y * dot2), - (vz * w2 - (x * vy - y * vx) * w + z * dot2)); + const Type vx = Type(2.0) * v.x; + const Type vy = Type(2.0) * v.y; + const Type vz = Type(2.0) * v.z; + const Type w2 = w * w - 0.5f; + const Type dot2 = (x * vx + y * vy + z * vz); + return PxVec3T((vx * w2 - (y * vz - z * vy) * w + x * dot2), (vy * w2 - (z * vx - x * vz) * w + y * dot2), + (vz * w2 - (x * vy - y * vx) * w + z * dot2)); } /** \brief Assignment operator */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxQuat& operator=(const PxQuat& p) + PX_CUDA_CALLABLE PX_FORCE_INLINE PxQuatT& operator=(const PxQuatT& p) { x = p.x; y = p.y; @@ -321,21 +321,20 @@ class PxQuat return *this; } - PX_CUDA_CALLABLE PX_FORCE_INLINE PxQuat& operator*=(const PxQuat& q) + PX_CUDA_CALLABLE PX_FORCE_INLINE PxQuatT& operator*=(const PxQuatT& q) { - const float tx = w * q.x + q.w * x + y * q.z - q.y * z; - const float ty = w * q.y + q.w * y + z * q.x - q.z * x; - const float tz = w * q.z + q.w * z + x * q.y - q.x * y; + const Type tx = w * q.x + q.w * x + y * q.z - q.y * z; + const Type ty = w * q.y + q.w * y + z * q.x - q.z * x; + const Type tz = w * q.z + q.w * z + x * q.y - q.x * y; w = w * q.w - q.x * x - y * q.y - q.z * z; x = tx; y = ty; z = tz; - return *this; } - PX_CUDA_CALLABLE PX_FORCE_INLINE PxQuat& operator+=(const PxQuat& q) + PX_CUDA_CALLABLE PX_FORCE_INLINE PxQuatT& operator+=(const PxQuatT& q) { x += q.x; y += q.y; @@ -344,7 +343,7 @@ class PxQuat return *this; } - PX_CUDA_CALLABLE PX_FORCE_INLINE PxQuat& operator-=(const PxQuat& q) + PX_CUDA_CALLABLE PX_FORCE_INLINE PxQuatT& operator-=(const PxQuatT& q) { x -= q.x; y -= q.y; @@ -353,7 +352,7 @@ class PxQuat return *this; } - PX_CUDA_CALLABLE PX_FORCE_INLINE PxQuat& operator*=(const float s) + PX_CUDA_CALLABLE PX_FORCE_INLINE PxQuatT& operator*=(const Type s) { x *= s; y *= s; @@ -363,41 +362,45 @@ class PxQuat } /** quaternion multiplication */ - PX_CUDA_CALLABLE PX_INLINE PxQuat operator*(const PxQuat& q) const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxQuatT operator*(const PxQuatT& q) const { - return PxQuat(w * q.x + q.w * x + y * q.z - q.y * z, w * q.y + q.w * y + z * q.x - q.z * x, + return PxQuatT(w * q.x + q.w * x + y * q.z - q.y * z, w * q.y + q.w * y + z * q.x - q.z * x, w * q.z + q.w * z + x * q.y - q.x * y, w * q.w - x * q.x - y * q.y - z * q.z); } /** quaternion addition */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxQuat operator+(const PxQuat& q) const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxQuatT operator+(const PxQuatT& q) const { - return PxQuat(x + q.x, y + q.y, z + q.z, w + q.w); + return PxQuatT(x + q.x, y + q.y, z + q.z, w + q.w); } /** quaternion subtraction */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxQuat operator-() const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxQuatT operator-() const { - return PxQuat(-x, -y, -z, -w); + return PxQuatT(-x, -y, -z, -w); } - PX_CUDA_CALLABLE PX_FORCE_INLINE PxQuat operator-(const PxQuat& q) const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxQuatT operator-(const PxQuatT& q) const { - return PxQuat(x - q.x, y - q.y, z - q.z, w - q.w); + return PxQuatT(x - q.x, y - q.y, z - q.z, w - q.w); } - PX_CUDA_CALLABLE PX_FORCE_INLINE PxQuat operator*(float r) const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxQuatT operator*(Type r) const { - return PxQuat(x * r, y * r, z * r, w * r); + return PxQuatT(x * r, y * r, z * r, w * r); } /** the quaternion elements */ - float x, y, z, w; + Type x, y, z, w; }; +typedef PxQuatT PxQuat; +typedef PxQuatT PxQuatd; + #if !PX_DOXYGEN } // namespace physx #endif /** @} */ -#endif // #ifndef PXFOUNDATION_PXQUAT_H +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxSIMDHelpers.h b/Source/ThirdParty/PhysX/foundation/PxSIMDHelpers.h new file mode 100644 index 000000000..85e065679 --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxSIMDHelpers.h @@ -0,0 +1,72 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_SIMD_HELPERS_H +#define PX_SIMD_HELPERS_H + +#include "foundation/PxMat33.h" +#include "foundation/PxVecMath.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + //! A padded version of PxMat33, to safely load its data using SIMD + class PxMat33Padded : public PxMat33 + { + public: + explicit PX_FORCE_INLINE PxMat33Padded(const PxQuat& q) + { + using namespace aos; + const QuatV qV = V4LoadU(&q.x); + Vec3V column0V, column1V, column2V; + QuatGetMat33V(qV, column0V, column1V, column2V); +#if defined(PX_SIMD_DISABLED) || (PX_LINUX && (PX_ARM || PX_A64)) + V3StoreU(column0V, column0); + V3StoreU(column1V, column1); + V3StoreU(column2V, column2); +#else + V4StoreU(column0V, &column0.x); + V4StoreU(column1V, &column1.x); + V4StoreU(column2V, &column2.x); +#endif + } + PX_FORCE_INLINE ~PxMat33Padded() {} + PX_FORCE_INLINE void operator=(const PxMat33& other) + { + column0 = other.column0; + column1 = other.column1; + column2 = other.column2; + } + PxU32 padding; + }; +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif diff --git a/Source/ThirdParty/PhysX/foundation/PxSList.h b/Source/ThirdParty/PhysX/foundation/PxSList.h new file mode 100644 index 000000000..e0a33617f --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxSList.h @@ -0,0 +1,133 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_SLIST_H +#define PX_SLIST_H + +#include "foundation/Px.h" +#include "foundation/PxAssert.h" +#include "foundation/PxAlignedMalloc.h" + +#if PX_P64_FAMILY + #define PX_SLIST_ALIGNMENT 16 +#else + #define PX_SLIST_ALIGNMENT 8 +#endif + +#if !PX_DOXYGEN +namespace physx +{ +#endif +#if PX_VC + #pragma warning(push) + #pragma warning(disable : 4324) // Padding was added at the end of a structure because of a __declspec(align) value. +#endif + +PX_ALIGN_PREFIX(PX_SLIST_ALIGNMENT) +class PxSListEntry +{ + friend struct PxSListImpl; + + public: + PxSListEntry() : mNext(NULL) + { + PX_ASSERT((size_t(this) & (PX_SLIST_ALIGNMENT - 1)) == 0); + } + + // Only use on elements returned by SList::flush() + // because the operation is not atomic. + PxSListEntry* next() + { + return mNext; + } + + private: + PxSListEntry* mNext; +}PX_ALIGN_SUFFIX(PX_SLIST_ALIGNMENT); + +#if PX_VC + #pragma warning(pop) +#endif + +// template-less implementation +struct PX_FOUNDATION_API PxSListImpl +{ + PxSListImpl(); + ~PxSListImpl(); + void push(PxSListEntry* entry); + PxSListEntry* pop(); + PxSListEntry* flush(); + static uint32_t getSize(); +}; + +template > +class PxSListT : protected Alloc +{ + public: + PxSListT(const Alloc& alloc = Alloc()) : Alloc(alloc) + { + mImpl = reinterpret_cast(Alloc::allocate(PxSListImpl::getSize(), __FILE__, __LINE__)); + PX_ASSERT((size_t(mImpl) & (PX_SLIST_ALIGNMENT - 1)) == 0); + PX_PLACEMENT_NEW(mImpl, PxSListImpl)(); + } + ~PxSListT() + { + mImpl->~PxSListImpl(); + Alloc::deallocate(mImpl); + } + + // pushes a new element to the list + void push(PxSListEntry& entry) + { + mImpl->push(&entry); + } + + // pops an element from the list + PxSListEntry* pop() + { + return mImpl->pop(); + } + + // removes all items from list, returns pointer to first element + PxSListEntry* flush() + { + return mImpl->flush(); + } + + private: + PxSListImpl* mImpl; +}; + +typedef PxSListT<> PxSList; + +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxSimpleTypes.h b/Source/ThirdParty/PhysX/foundation/PxSimpleTypes.h index a9ced086c..87e8bb958 100644 --- a/Source/ThirdParty/PhysX/foundation/PxSimpleTypes.h +++ b/Source/ThirdParty/PhysX/foundation/PxSimpleTypes.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PXFOUNDATION_PXSIMPLETYPES_H -#define PXFOUNDATION_PXSIMPLETYPES_H +#ifndef PX_SIMPLE_TYPES_H +#define PX_SIMPLE_TYPES_H /** \addtogroup foundation @{ @@ -56,15 +55,17 @@ #if PX_VC // we could use inttypes.h starting with VC12 #define PX_PRIu64 "I64u" #else -#if !PX_PS4 && !PX_APPLE_FAMILY +#if !PX_PS4 && !PX_PS5 && !PX_APPLE_FAMILY #define __STDC_FORMAT_MACROS #endif #include #define PX_PRIu64 PRIu64 #endif +#if !PX_DOXYGEN namespace physx { +#endif typedef int64_t PxI64; typedef uint64_t PxU64; typedef int32_t PxI32; @@ -76,13 +77,18 @@ typedef uint8_t PxU8; typedef float PxF32; typedef double PxF64; typedef float PxReal; -} +// Int-as-bool type - has some uses for efficiency and with SIMD +typedef PxI32 PxIntBool; +static const PxIntBool PxIntFalse = 0; +static const PxIntBool PxIntTrue = 1; +#if !PX_DOXYGEN +} // namespace physx +#endif + +#define PX_SIGN_BITMASK 0x80000000 // Type ranges -// These are here because we sometimes have non-IEEE compliant platforms to deal with. -// Removal is under consideration (issue GWSD-34) - #define PX_MAX_F32 3.4028234663852885981170418348452e+38F // maximum possible float value #define PX_MAX_F64 DBL_MAX // maximum possible double value @@ -109,4 +115,5 @@ typedef float PxReal; #define PX_MIN_U32 UINT32_MIN /** @} */ -#endif // #ifndef PXFOUNDATION_PXSIMPLETYPES_H +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxSocket.h b/Source/ThirdParty/PhysX/foundation/PxSocket.h new file mode 100644 index 000000000..eaa0485f4 --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxSocket.h @@ -0,0 +1,187 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_SOCKET_H +#define PX_SOCKET_H + +#include "foundation/PxUserAllocated.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif +/** +Socket abstraction API +*/ + +class PX_FOUNDATION_API PxSocket : public PxUserAllocated +{ + public: + static const uint32_t DEFAULT_BUFFER_SIZE; + + PxSocket(bool inEnableBuffering = true, bool blocking = true); + + virtual ~PxSocket(); + + /*! + Opens a network socket for input and/or output + + \param host + Name of the host to connect to. This can be an IP, URL, etc + + \param port + The port to connect to on the remote host + + \param timeout + Timeout in ms until the connection must be established. + + \return + True if the connection was successful, false otherwise + */ + bool connect(const char* host, uint16_t port, uint32_t timeout = 1000); + + /*! + Opens a network socket for input and/or output as a server. Put the connection in listening mode + + \param port + The port on which the socket listens + */ + bool listen(uint16_t port); + + /*! + Accept a connection on a socket that is in listening mode + + \note + This method only supports a single connection client. Additional clients + that connect to the listening port will overwrite the existing socket handle. + + \param block + whether or not the call should block + + \return whether a connection was established + */ + bool accept(bool block); + + /*! + Disconnects an open socket + */ + void disconnect(); + + /*! + Returns whether the socket is currently open (connected) or not. + + \return + True if the socket is connected, false otherwise + */ + bool isConnected() const; + + /*! + Returns the name of the connected host. This is the same as the string + that was supplied to the connect call. + + \return + The name of the connected host + */ + const char* getHost() const; + + /*! + Returns the port of the connected host. This is the same as the port + that was supplied to the connect call. + + \return + The port of the connected host + */ + uint16_t getPort() const; + + /*! + Flushes the output stream. Until the stream is flushed, there is no + guarantee that the written data has actually reached the destination + storage. Flush forces all buffered data to be sent to the output. + + \note flush always blocks. If the socket is in non-blocking mode, this will result + the thread spinning. + + \return + True if the flush was successful, false otherwise + */ + bool flush(); + + /*! + Writes data to the output stream. + + \param data + Pointer to a block of data to write to the stream + + \param length + Amount of data to write, in bytes + + \return + Number of bytes actually written. This could be lower than length if the socket is non-blocking. + */ + + uint32_t write(const uint8_t* data, uint32_t length); + + /*! + Reads data from the output stream. + + \param data + Pointer to a buffer where the read data will be stored. + + \param length + Amount of data to read, in bytes. + + \return + Number of bytes actually read. This could be lower than length if the stream end is + encountered or the socket is non-blocking. + */ + uint32_t read(uint8_t* data, uint32_t length); + + /*! + Sets blocking mode of the socket. + Socket must be connected, otherwise calling this method won't take any effect. + */ + void setBlocking(bool blocking); + + /*! + Returns whether read/write/flush calls to the socket are blocking. + + \return + True if the socket is blocking. + */ + bool isBlocking() const; + + private: + class SocketImpl* mImpl; +}; + +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxSort.h b/Source/ThirdParty/PhysX/foundation/PxSort.h new file mode 100644 index 000000000..24ad1bc34 --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxSort.h @@ -0,0 +1,131 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_SORT_H +#define PX_SORT_H + +/** \addtogroup foundation +@{ +*/ + +#include "foundation/PxSortInternals.h" +#include "foundation/PxAlloca.h" + +#define PX_SORT_PARANOIA PX_DEBUG + +/** +\brief Sorts an array of objects in ascending order, assuming +that the predicate implements the < operator: + +@see PxLess, PxGreater +*/ + +#if PX_VC +#pragma warning(push) +#pragma warning(disable : 4706) // disable the warning that we did an assignment within a conditional expression, as +// this was intentional. +#endif + +#if !PX_DOXYGEN +namespace physx +{ +#endif +template +void PxSort(T* elements, uint32_t count, const Predicate& compare, const PxAllocator& inAllocator, + const uint32_t initialStackSize = 32) +{ + static const uint32_t SMALL_SORT_CUTOFF = 5; // must be >= 3 since we need 3 for median + + PX_ALLOCA(stackMem, int32_t, initialStackSize); + PxStack stack(stackMem, initialStackSize, inAllocator); + + int32_t first = 0, last = int32_t(count - 1); + if(last > first) + { + for(;;) + { + while(last > first) + { + PX_ASSERT(first >= 0 && last < int32_t(count)); + if(uint32_t(last - first) < SMALL_SORT_CUTOFF) + { + PxSmallSort(elements, first, last, compare); + break; + } + else + { + const int32_t partIndex = PxPartition(elements, first, last, compare); + + // push smaller sublist to minimize stack usage + if((partIndex - first) < (last - partIndex)) + { + stack.push(first, partIndex - 1); + first = partIndex + 1; + } + else + { + stack.push(partIndex + 1, last); + last = partIndex - 1; + } + } + } + + if(stack.empty()) + break; + + stack.pop(first, last); + } + } +#if PX_SORT_PARANOIA + for(uint32_t i = 1; i < count; i++) + PX_ASSERT(!compare(elements[i], elements[i - 1])); +#endif +} + +template +void PxSort(T* elements, uint32_t count, const Predicate& compare) +{ + PxSort(elements, count, compare, typename PxAllocatorTraits::Type()); +} + +template +void PxSort(T* elements, uint32_t count) +{ + PxSort(elements, count, PxLess(), typename PxAllocatorTraits::Type()); +} + +#if !PX_DOXYGEN +} // namespace physx +#endif + +#if PX_VC +#pragma warning(pop) +#endif +/** @} */ +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxSortInternals.h b/Source/ThirdParty/PhysX/foundation/PxSortInternals.h new file mode 100644 index 000000000..b6702d133 --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxSortInternals.h @@ -0,0 +1,186 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_SORT_INTERNALS_H +#define PX_SORT_INTERNALS_H + +/** \addtogroup foundation +@{ +*/ + +#include "foundation/PxAssert.h" +#include "foundation/PxMathIntrinsics.h" +#include "foundation/PxBasicTemplates.h" +#include "foundation/PxUserAllocated.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif +template +PX_INLINE void PxMedian3(T* elements, int32_t first, int32_t last, Predicate& compare) +{ + /* + This creates sentinels because we know there is an element at the start minimum(or equal) + than the pivot and an element at the end greater(or equal) than the pivot. Plus the + median of 3 reduces the chance of degenerate behavour. + */ + + int32_t mid = (first + last) / 2; + + if(compare(elements[mid], elements[first])) + PxSwap(elements[first], elements[mid]); + + if(compare(elements[last], elements[first])) + PxSwap(elements[first], elements[last]); + + if(compare(elements[last], elements[mid])) + PxSwap(elements[mid], elements[last]); + + // keep the pivot at last-1 + PxSwap(elements[mid], elements[last - 1]); +} + +template +PX_INLINE int32_t PxPartition(T* elements, int32_t first, int32_t last, Predicate& compare) +{ + PxMedian3(elements, first, last, compare); + + /* + WARNING: using the line: + + T partValue = elements[last-1]; + + and changing the scan loops to: + + while(comparator.greater(partValue, elements[++i])); + while(comparator.greater(elements[--j], partValue); + + triggers a compiler optimizer bug on xenon where it stores a double to the stack for partValue + then loads it as a single...:-( + */ + + int32_t i = first; // we know first is less than pivot(but i gets pre incremented) + int32_t j = last - 1; // pivot is in last-1 (but j gets pre decremented) + + for(;;) + { + while(compare(elements[++i], elements[last - 1])) + ; + while(compare(elements[last - 1], elements[--j])) + ; + + if(i >= j) + break; + + PX_ASSERT(i <= last && j >= first); + PxSwap(elements[i], elements[j]); + } + // put the pivot in place + + PX_ASSERT(i <= last && first <= (last - 1)); + PxSwap(elements[i], elements[last - 1]); + + return i; +} + +template +PX_INLINE void PxSmallSort(T* elements, int32_t first, int32_t last, Predicate& compare) +{ + // selection sort - could reduce to fsel on 360 with floats. + + for(int32_t i = first; i < last; i++) + { + int32_t m = i; + for(int32_t j = i + 1; j <= last; j++) + if(compare(elements[j], elements[m])) + m = j; + + if(m != i) + PxSwap(elements[m], elements[i]); + } +} + +template +class PxStack +{ + PxAllocator mAllocator; + uint32_t mSize, mCapacity; + int32_t* mMemory; + bool mRealloc; + + public: + PxStack(int32_t* memory, uint32_t capacity, const PxAllocator& inAllocator) + : mAllocator(inAllocator), mSize(0), mCapacity(capacity), mMemory(memory), mRealloc(false) + { + } + ~PxStack() + { + if(mRealloc) + mAllocator.deallocate(mMemory); + } + + void grow() + { + mCapacity *= 2; + int32_t* newMem = + reinterpret_cast(mAllocator.allocate(sizeof(int32_t) * mCapacity, __FILE__, __LINE__)); + intrinsics::memCopy(newMem, mMemory, mSize * sizeof(int32_t)); + if(mRealloc) + mAllocator.deallocate(mMemory); + mRealloc = true; + mMemory = newMem; + } + + PX_INLINE void push(int32_t start, int32_t end) + { + if(mSize >= mCapacity - 1) + grow(); + mMemory[mSize++] = start; + mMemory[mSize++] = end; + } + + PX_INLINE void pop(int32_t& start, int32_t& end) + { + PX_ASSERT(!empty()); + end = mMemory[--mSize]; + start = mMemory[--mSize]; + } + + PX_INLINE bool empty() + { + return mSize == 0; + } +}; + +#if !PX_DOXYGEN +} // namespace physx +#endif + /** @} */ +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxStrideIterator.h b/Source/ThirdParty/PhysX/foundation/PxStrideIterator.h index dd6dd10ba..c1326fa18 100644 --- a/Source/ThirdParty/PhysX/foundation/PxStrideIterator.h +++ b/Source/ThirdParty/PhysX/foundation/PxStrideIterator.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,15 +22,15 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PXFOUNDATION_PXSTRIDEITERATOR_H -#define PXFOUNDATION_PXSTRIDEITERATOR_H +#ifndef PX_STRIDE_ITERATOR_H +#define PX_STRIDE_ITERATOR_H #include "foundation/Px.h" -#include "foundation/PxSharedAssert.h" +#include "foundation/PxAssert.h" /** \addtogroup foundation @{ @@ -106,7 +105,7 @@ class PxStrideIterator */ explicit PX_INLINE PxStrideIterator(T* ptr = NULL, PxU32 stride = sizeof(T)) : mPtr(ptr), mStride(stride) { - PX_SHARED_ASSERT(mStride == 0 || sizeof(T) <= mStride); + PX_ASSERT(mStride == 0 || sizeof(T) <= mStride); } /** @@ -117,7 +116,7 @@ class PxStrideIterator PX_INLINE PxStrideIterator(const PxStrideIterator::Type>& strideIterator) : mPtr(strideIterator.ptr()), mStride(strideIterator.stride()) { - PX_SHARED_ASSERT(mStride == 0 || sizeof(T) <= mStride); + PX_ASSERT(mStride == 0 || sizeof(T) <= mStride); } /** @@ -237,7 +236,7 @@ class PxStrideIterator */ PX_INLINE int operator-(const PxStrideIterator& other) const { - PX_SHARED_ASSERT(isCompatible(other)); + PX_ASSERT(isCompatible(other)); int byteDiff = static_cast(reinterpret_cast(mPtr) - reinterpret_cast(other.mPtr)); return byteDiff / static_cast(stride()); } @@ -247,7 +246,7 @@ class PxStrideIterator */ PX_INLINE bool operator==(const PxStrideIterator& other) const { - PX_SHARED_ASSERT(isCompatible(other)); + PX_ASSERT(isCompatible(other)); return mPtr == other.mPtr; } @@ -256,7 +255,7 @@ class PxStrideIterator */ PX_INLINE bool operator!=(const PxStrideIterator& other) const { - PX_SHARED_ASSERT(isCompatible(other)); + PX_ASSERT(isCompatible(other)); return mPtr != other.mPtr; } @@ -265,7 +264,7 @@ class PxStrideIterator */ PX_INLINE bool operator<(const PxStrideIterator& other) const { - PX_SHARED_ASSERT(isCompatible(other)); + PX_ASSERT(isCompatible(other)); return mPtr < other.mPtr; } @@ -274,7 +273,7 @@ class PxStrideIterator */ PX_INLINE bool operator>(const PxStrideIterator& other) const { - PX_SHARED_ASSERT(isCompatible(other)); + PX_ASSERT(isCompatible(other)); return mPtr > other.mPtr; } @@ -283,7 +282,7 @@ class PxStrideIterator */ PX_INLINE bool operator<=(const PxStrideIterator& other) const { - PX_SHARED_ASSERT(isCompatible(other)); + PX_ASSERT(isCompatible(other)); return mPtr <= other.mPtr; } @@ -292,7 +291,7 @@ class PxStrideIterator */ PX_INLINE bool operator>=(const PxStrideIterator& other) const { - PX_SHARED_ASSERT(isCompatible(other)); + PX_ASSERT(isCompatible(other)); return mPtr >= other.mPtr; } @@ -350,4 +349,5 @@ PX_INLINE PxStrideIterator PxMakeIterator(const T* ptr, PxU32 stride = #endif /** @} */ -#endif // PXFOUNDATION_PXSTRIDEITERATOR_H +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxString.h b/Source/ThirdParty/PhysX/foundation/PxString.h new file mode 100644 index 000000000..eb744bb2c --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxString.h @@ -0,0 +1,79 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_STRING_H +#define PX_STRING_H + +#include "foundation/PxPreprocessor.h" +#include "foundation/PxSimpleTypes.h" +#include "foundation/PxFoundationConfig.h" +#include + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +// the following functions have C99 semantics. Note that C99 requires for snprintf and vsnprintf: +// * the resulting string is always NULL-terminated regardless of truncation. +// * in the case of truncation the return value is the number of characters that would have been created. + +PX_FOUNDATION_API int32_t Pxsscanf(const char* buffer, const char* format, ...); +PX_FOUNDATION_API int32_t Pxstrcmp(const char* str1, const char* str2); +PX_FOUNDATION_API int32_t Pxstrncmp(const char* str1, const char* str2, size_t count); +PX_FOUNDATION_API int32_t Pxsnprintf(char* dst, size_t dstSize, const char* format, ...); +PX_FOUNDATION_API int32_t Pxvsnprintf(char* dst, size_t dstSize, const char* src, va_list arg); + +// strlcat and strlcpy have BSD semantics: +// * dstSize is always the size of the destination buffer +// * the resulting string is always NULL-terminated regardless of truncation +// * in the case of truncation the return value is the length of the string that would have been created + +PX_FOUNDATION_API size_t Pxstrlcat(char* dst, size_t dstSize, const char* src); +PX_FOUNDATION_API size_t Pxstrlcpy(char* dst, size_t dstSize, const char* src); + +// case-insensitive string comparison +PX_FOUNDATION_API int32_t Pxstricmp(const char* str1, const char* str2); +PX_FOUNDATION_API int32_t Pxstrnicmp(const char* str1, const char* str2, size_t count); + +// in-place string case conversion +PX_FOUNDATION_API void Pxstrlwr(char* str); +PX_FOUNDATION_API void Pxstrupr(char* str); + + +/** +\brief Prints the string literally (does not consume % specifier), trying to make sure it's visible to the app +programmer +*/ +PX_FOUNDATION_API void PxPrintString(const char*); + +#if !PX_DOXYGEN +} // namespace physx +#endif +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PsSync.h b/Source/ThirdParty/PhysX/foundation/PxSync.h similarity index 81% rename from Source/ThirdParty/PhysX/foundation/PsSync.h rename to Source/ThirdParty/PhysX/foundation/PxSync.h index 0fd87c2dc..46865d7e5 100644 --- a/Source/ThirdParty/PhysX/foundation/PsSync.h +++ b/Source/ThirdParty/PhysX/foundation/PxSync.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,19 +22,19 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PSFOUNDATION_PSSYNC_H -#define PSFOUNDATION_PSSYNC_H +#ifndef PX_SYNC_H +#define PX_SYNC_H -#include "PsAllocator.h" +#include "foundation/PxAllocator.h" +#if !PX_DOXYGEN namespace physx { -namespace shdfnd -{ +#endif /*! Implementation notes: * - Calling set() on an already signaled Sync does not change its state. @@ -45,14 +44,14 @@ Implementation notes: * - NOTE: be careful when pulsing an event with set() followed by reset(), because a * thread that is not waiting on the event will miss the signal. */ -class PX_FOUNDATION_API SyncImpl +class PX_FOUNDATION_API PxSyncImpl { public: static const uint32_t waitForever = 0xffffffff; - SyncImpl(); + PxSyncImpl(); - ~SyncImpl(); + ~PxSyncImpl(); /** Wait on the object for at most the given number of ms. Returns * true if the object is signaled. Sync::waitForever will block forever @@ -84,21 +83,21 @@ Implementation notes: * - NOTE: be careful when pulsing an event with set() followed by reset(), because a * thread that is not waiting on the event will miss the signal. */ -template > -class SyncT : protected Alloc +template > +class PxSyncT : protected Alloc { public: - static const uint32_t waitForever = SyncImpl::waitForever; + static const uint32_t waitForever = PxSyncImpl::waitForever; - SyncT(const Alloc& alloc = Alloc()) : Alloc(alloc) + PxSyncT(const Alloc& alloc = Alloc()) : Alloc(alloc) { - mImpl = reinterpret_cast(Alloc::allocate(SyncImpl::getSize(), __FILE__, __LINE__)); - PX_PLACEMENT_NEW(mImpl, SyncImpl)(); + mImpl = reinterpret_cast(Alloc::allocate(PxSyncImpl::getSize(), __FILE__, __LINE__)); + PX_PLACEMENT_NEW(mImpl, PxSyncImpl)(); } - ~SyncT() + ~PxSyncT() { - mImpl->~SyncImpl(); + mImpl->~PxSyncImpl(); Alloc::deallocate(mImpl); } @@ -107,7 +106,7 @@ class SyncT : protected Alloc * or until the object is signaled. */ - bool wait(uint32_t milliseconds = SyncImpl::waitForever) + bool wait(uint32_t milliseconds = PxSyncImpl::waitForever) { return mImpl->wait(milliseconds); } @@ -127,12 +126,14 @@ class SyncT : protected Alloc } private: - class SyncImpl* mImpl; + class PxSyncImpl* mImpl; }; -typedef SyncT<> Sync; +typedef PxSyncT<> PxSync; -} // namespace shdfnd +#if !PX_DOXYGEN } // namespace physx +#endif + +#endif -#endif // #ifndef PSFOUNDATION_PSSYNC_H diff --git a/Source/ThirdParty/PhysX/foundation/PxTempAllocator.h b/Source/ThirdParty/PhysX/foundation/PxTempAllocator.h new file mode 100644 index 000000000..395bce9a2 --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxTempAllocator.h @@ -0,0 +1,63 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_TEMP_ALLOCATOR_H +#define PX_TEMP_ALLOCATOR_H + +#include "foundation/PxAllocator.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif +union PxTempAllocatorChunk +{ + PxTempAllocatorChunk() : mNext(0) + { + } + PxTempAllocatorChunk* mNext; // while chunk is free + PxU32 mIndex; // while chunk is allocated + PxU8 mPad[16]; // 16 byte aligned allocations +}; + +class PxTempAllocator +{ + public: + PX_FORCE_INLINE PxTempAllocator(const char* = 0) + { + } + PX_FOUNDATION_API void* allocate(size_t size, const char* file, PxI32 line); + PX_FOUNDATION_API void deallocate(void* ptr); +}; + +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxThread.h b/Source/ThirdParty/PhysX/foundation/PxThread.h new file mode 100644 index 000000000..6f3b8ddb7 --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxThread.h @@ -0,0 +1,369 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_THREAD_H +#define PX_THREAD_H + +#include "foundation/PxUserAllocated.h" + +// todo: these need to go somewhere else +// PT: looks like this is still used on some platforms + +#if PX_WINDOWS_FAMILY +#define PxSpinLockPause() __asm pause +#elif PX_LINUX || PX_ANDROID || PX_PS4 || PX_PS5 || PX_APPLE_FAMILY || PX_SWITCH +#define PxSpinLockPause() asm("nop") +#else +#error "Platform not supported!" +#endif + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +struct PxThreadPriority +{ + enum Enum + { + eHIGH = 0, //!< High priority + eABOVE_NORMAL = 1, //!< Above Normal priority + eNORMAL = 2, //!< Normal/default priority + eBELOW_NORMAL = 3, //!< Below Normal priority + eLOW = 4, //!< Low priority. + eFORCE_DWORD = 0xffFFffFF + }; +}; + +class PxRunnable +{ + public: + PxRunnable() {} + virtual ~PxRunnable() {} + virtual void execute() {} +}; + +class PX_FOUNDATION_API PxThreadImpl +{ + public: + typedef size_t Id; // space for a pointer or an integer + typedef void* (*ExecuteFn)(void*); + + static PxU32 getDefaultStackSize(); + static Id getId(); + + /** + Construct (but do not start) the thread object. The OS thread object will not be created + until start() is called. Executes in the context + of the spawning thread. + */ + + PxThreadImpl(); + + /** + Construct and start the the thread, passing the given arg to the given fn. (pthread style) + */ + + PxThreadImpl(ExecuteFn fn, void* arg, const char* name); + + /** + Deallocate all resources associated with the thread. Should be called in the + context of the spawning thread. + */ + + ~PxThreadImpl(); + + /** + Create the OS thread and start it running. Called in the context of the spawning thread. + If an affinity mask has previously been set then it will be applied after the + thread has been created. + */ + + void start(PxU32 stackSize, PxRunnable* r); + + /** + Violently kill the current thread. Blunt instrument, not recommended since + it can leave all kinds of things unreleased (stack, memory, mutexes...) Should + be called in the context of the spawning thread. + */ + + void kill(); + + /** + Stop the thread. Signals the spawned thread that it should stop, so the + thread should check regularly + */ + + void signalQuit(); + + /** + Wait for a thread to stop. Should be called in the context of the spawning + thread. Returns false if the thread has not been started. + */ + + bool waitForQuit(); + + /** + check whether the thread is signalled to quit. Called in the context of the + spawned thread. + */ + + bool quitIsSignalled(); + + /** + Cleanly shut down this thread. Called in the context of the spawned thread. + */ + void quit(); + + /** + Change the affinity mask for this thread. The mask is a platform + specific value. + + On Windows, Linux, PS4, PS5, and Switch platforms, each set mask bit represents + the index of a logical processor that the OS may schedule thread execution on. + Bits outside the range of valid logical processors may be ignored or cause + the function to return an error. + + On Apple platforms, this function has no effect. + + If the thread has not yet been started then the mask is stored + and applied when the thread is started. + + If the thread has already been started then this method returns the + previous affinity mask on success, otherwise it returns zero. + */ + PxU32 setAffinityMask(PxU32 mask); + + static PxThreadPriority::Enum getPriority(Id threadId); + + /** Set thread priority. */ + void setPriority(PxThreadPriority::Enum prio); + + /** set the thread's name */ + void setName(const char* name); + + /** Put the current thread to sleep for the given number of milliseconds */ + static void sleep(PxU32 ms); + + /** Yield the current thread's slot on the CPU */ + static void yield(); + + /** Inform the processor that we're in a busy wait to give it a chance to do something clever. + yield() yields the thread, while yieldProcessor() aims to yield the processor */ + static void yieldProcessor(); + + /** Return the number of physical cores (does not include hyper-threaded cores), returns 0 on failure */ + static PxU32 getNbPhysicalCores(); + + /** + Size of this class. + */ + static PxU32 getSize(); +}; + +/** +Thread abstraction API +*/ +template > +class PxThreadT : protected Alloc, public PxUserAllocated, public PxRunnable +{ + public: + typedef PxThreadImpl::Id Id; // space for a pointer or an integer + + /** + Construct (but do not start) the thread object. Executes in the context + of the spawning thread + */ + PxThreadT(const Alloc& alloc = Alloc()) : Alloc(alloc) + { + mImpl = reinterpret_cast(Alloc::allocate(PxThreadImpl::getSize(), __FILE__, __LINE__)); + PX_PLACEMENT_NEW(mImpl, PxThreadImpl)(); + } + + /** + Construct and start the the thread, passing the given arg to the given fn. (pthread style) + */ + PxThreadT(PxThreadImpl::ExecuteFn fn, void* arg, const char* name, const Alloc& alloc = Alloc()) : Alloc(alloc) + { + mImpl = reinterpret_cast(Alloc::allocate(PxThreadImpl::getSize(), __FILE__, __LINE__)); + PX_PLACEMENT_NEW(mImpl, PxThreadImpl)(fn, arg, name); + } + + /** + Deallocate all resources associated with the thread. Should be called in the + context of the spawning thread. + */ + virtual ~PxThreadT() + { + mImpl->~PxThreadImpl(); + Alloc::deallocate(mImpl); + } + + /** + start the thread running. Called in the context of the spawning thread. + */ + + void start(PxU32 stackSize = PxThreadImpl::getDefaultStackSize()) + { + mImpl->start(stackSize, this); + } + + /** + Violently kill the current thread. Blunt instrument, not recommended since + it can leave all kinds of things unreleased (stack, memory, mutexes...) Should + be called in the context of the spawning thread. + */ + + void kill() + { + mImpl->kill(); + } + + /** + The virtual execute() method is the user defined function that will + run in the new thread. Called in the context of the spawned thread. + */ + + virtual void execute(void) + { + } + + /** + stop the thread. Signals the spawned thread that it should stop, so the + thread should check regularly + */ + + void signalQuit() + { + mImpl->signalQuit(); + } + + /** + Wait for a thread to stop. Should be called in the context of the spawning + thread. Returns false if the thread has not been started. + */ + + bool waitForQuit() + { + return mImpl->waitForQuit(); + } + + /** + check whether the thread is signalled to quit. Called in the context of the + spawned thread. + */ + + bool quitIsSignalled() + { + return mImpl->quitIsSignalled(); + } + + /** + Cleanly shut down this thread. Called in the context of the spawned thread. + */ + void quit() + { + mImpl->quit(); + } + + PxU32 setAffinityMask(PxU32 mask) + { + return mImpl->setAffinityMask(mask); + } + + static PxThreadPriority::Enum getPriority(PxThreadImpl::Id threadId) + { + return PxThreadImpl::getPriority(threadId); + } + + /** Set thread priority. */ + void setPriority(PxThreadPriority::Enum prio) + { + mImpl->setPriority(prio); + } + + /** set the thread's name */ + void setName(const char* name) + { + mImpl->setName(name); + } + + /** Put the current thread to sleep for the given number of milliseconds */ + static void sleep(PxU32 ms) + { + PxThreadImpl::sleep(ms); + } + + /** Yield the current thread's slot on the CPU */ + static void yield() + { + PxThreadImpl::yield(); + } + + /** Inform the processor that we're in a busy wait to give it a chance to do something clever + yield() yields the thread, while yieldProcessor() aims to yield the processor */ + static void yieldProcesor() + { + PxThreadImpl::yieldProcessor(); + } + + static PxU32 getDefaultStackSize() + { + return PxThreadImpl::getDefaultStackSize(); + } + + static PxThreadImpl::Id getId() + { + return PxThreadImpl::getId(); + } + + static PxU32 getNbPhysicalCores() + { + return PxThreadImpl::getNbPhysicalCores(); + } + + private: + class PxThreadImpl* mImpl; +}; + +typedef PxThreadT<> PxThread; + +PX_FOUNDATION_API PxU32 PxTlsAlloc(); +PX_FOUNDATION_API void PxTlsFree(PxU32 index); +PX_FOUNDATION_API void* PxTlsGet(PxU32 index); +PX_FOUNDATION_API size_t PxTlsGetValue(PxU32 index); +PX_FOUNDATION_API PxU32 PxTlsSet(PxU32 index, void* value); +PX_FOUNDATION_API PxU32 PxTlsSetValue(PxU32 index, size_t value); + + +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxTime.h b/Source/ThirdParty/PhysX/foundation/PxTime.h new file mode 100644 index 000000000..e21226fff --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxTime.h @@ -0,0 +1,97 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_TIME_H +#define PX_TIME_H + +#include "foundation/PxSimpleTypes.h" +#include "foundation/PxFoundationConfig.h" + +#if PX_LINUX || PX_ANDROID +#include +#endif + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +struct PxCounterFrequencyToTensOfNanos +{ + PxU64 mNumerator; + PxU64 mDenominator; + PxCounterFrequencyToTensOfNanos(PxU64 inNum, PxU64 inDenom) : mNumerator(inNum), mDenominator(inDenom) + { + } + + // quite slow. + PxU64 toTensOfNanos(PxU64 inCounter) const + { + return (inCounter * mNumerator) / mDenominator; + } +}; + +class PX_FOUNDATION_API PxTime +{ + public: + typedef PxF64 Second; + static const PxU64 sNumTensOfNanoSecondsInASecond = 100000000; + // This is supposedly guaranteed to not change after system boot + // regardless of processors, speedstep, etc. + static const PxCounterFrequencyToTensOfNanos& getBootCounterFrequency(); + + static PxCounterFrequencyToTensOfNanos getCounterFrequency(); + + static PxU64 getCurrentCounterValue(); + + // SLOW!! + // Thar be a 64 bit divide in thar! + static PxU64 getCurrentTimeInTensOfNanoSeconds() + { + PxU64 ticks = getCurrentCounterValue(); + return getBootCounterFrequency().toTensOfNanos(ticks); + } + + PxTime(); + Second getElapsedSeconds(); + Second peekElapsedSeconds(); + Second getLastTime() const; + + private: +#if PX_LINUX || PX_ANDROID || PX_APPLE_FAMILY || PX_PS4 || PX_PS5 + Second mLastTime; +#else + PxI64 mTickCount; +#endif +}; +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxTransform.h b/Source/ThirdParty/PhysX/foundation/PxTransform.h index f639903b6..bf877a6d6 100644 --- a/Source/ThirdParty/PhysX/foundation/PxTransform.h +++ b/Source/ThirdParty/PhysX/foundation/PxTransform.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,18 +22,17 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PXFOUNDATION_PXTRANSFORM_H -#define PXFOUNDATION_PXTRANSFORM_H +#ifndef PX_TRANSFORM_H +#define PX_TRANSFORM_H /** \addtogroup foundation @{ */ #include "foundation/PxQuat.h" -#include "foundation/PxPlane.h" #if !PX_DOXYGEN namespace physx @@ -45,106 +43,117 @@ namespace physx \brief class representing a rigid euclidean transform as a quaternion and a vector */ -class PxTransform +template +class PxTransformT { public: - PxQuat q; - PxVec3 p; + PxQuatT q; + PxVec3T p; - PX_CUDA_CALLABLE PX_FORCE_INLINE PxTransform() + PX_CUDA_CALLABLE PX_FORCE_INLINE PxTransformT() { } - PX_CUDA_CALLABLE PX_FORCE_INLINE explicit PxTransform(const PxVec3& position) : q(PxIdentity), p(position) + PX_CUDA_CALLABLE PX_FORCE_INLINE explicit PxTransformT(const PxVec3T& position) : q(PxIdentity), p(position) { } - PX_CUDA_CALLABLE PX_FORCE_INLINE explicit PxTransform(PxIDENTITY r) : q(PxIdentity), p(PxZero) - { - PX_UNUSED(r); - } - - PX_CUDA_CALLABLE PX_FORCE_INLINE explicit PxTransform(const PxQuat& orientation) : q(orientation), p(0) - { - PX_SHARED_ASSERT(orientation.isSane()); - } - - PX_CUDA_CALLABLE PX_FORCE_INLINE PxTransform(float x, float y, float z, PxQuat aQ = PxQuat(PxIdentity)) - : q(aQ), p(x, y, z) + PX_CUDA_CALLABLE PX_FORCE_INLINE explicit PxTransformT(PxIDENTITY) : q(PxIdentity), p(PxZero) { } - PX_CUDA_CALLABLE PX_FORCE_INLINE PxTransform(const PxVec3& p0, const PxQuat& q0) : q(q0), p(p0) + PX_CUDA_CALLABLE PX_FORCE_INLINE explicit PxTransformT(const PxQuatT& orientation) : q(orientation), p(Type(0)) { - PX_SHARED_ASSERT(q0.isSane()); + PX_ASSERT(orientation.isSane()); } - PX_CUDA_CALLABLE PX_FORCE_INLINE explicit PxTransform(const PxMat44& m); // defined in PxMat44.h + PX_CUDA_CALLABLE PX_FORCE_INLINE PxTransformT(Type x, Type y, Type z, PxQuatT aQ = PxQuatT(PxIdentity)) : + q(aQ), p(x, y, z) + { + } + + PX_CUDA_CALLABLE PX_FORCE_INLINE PxTransformT(const PxVec3T& p0, const PxQuatT& q0) : q(q0), p(p0) + { + PX_ASSERT(q0.isSane()); + } + + PX_CUDA_CALLABLE PX_FORCE_INLINE explicit PxTransformT(const PxMat44T& m); // defined in PxMat44.h + + PX_CUDA_CALLABLE PX_FORCE_INLINE void operator=(const PxTransformT& other) + { + p = other.p; + q = other.q; + } + + PX_CUDA_CALLABLE PX_FORCE_INLINE PxTransformT(const PxTransformT& other) + { + p = other.p; + q = other.q; + } /** \brief returns true if the two transforms are exactly equal */ - PX_CUDA_CALLABLE PX_INLINE bool operator==(const PxTransform& t) const + PX_CUDA_CALLABLE PX_INLINE bool operator==(const PxTransformT& t) const { return p == t.p && q == t.q; } - PX_CUDA_CALLABLE PX_FORCE_INLINE PxTransform operator*(const PxTransform& x) const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxTransformT operator*(const PxTransformT& x) const { - PX_SHARED_ASSERT(x.isSane()); + PX_ASSERT(x.isSane()); return transform(x); } //! Equals matrix multiplication - PX_CUDA_CALLABLE PX_INLINE PxTransform& operator*=(PxTransform& other) + PX_CUDA_CALLABLE PX_INLINE PxTransformT& operator*=(const PxTransformT& other) { *this = *this * other; return *this; } - PX_CUDA_CALLABLE PX_FORCE_INLINE PxTransform getInverse() const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxTransformT getInverse() const { - PX_SHARED_ASSERT(isFinite()); - return PxTransform(q.rotateInv(-p), q.getConjugate()); + PX_ASSERT(isFinite()); + return PxTransformT(q.rotateInv(-p), q.getConjugate()); } - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 transform(const PxVec3& input) const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T transform(const PxVec3T& input) const { - PX_SHARED_ASSERT(isFinite()); + PX_ASSERT(isFinite()); return q.rotate(input) + p; } - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 transformInv(const PxVec3& input) const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T transformInv(const PxVec3T& input) const { - PX_SHARED_ASSERT(isFinite()); + PX_ASSERT(isFinite()); return q.rotateInv(input - p); } - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 rotate(const PxVec3& input) const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T rotate(const PxVec3T& input) const { - PX_SHARED_ASSERT(isFinite()); + PX_ASSERT(isFinite()); return q.rotate(input); } - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 rotateInv(const PxVec3& input) const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T rotateInv(const PxVec3T& input) const { - PX_SHARED_ASSERT(isFinite()); + PX_ASSERT(isFinite()); return q.rotateInv(input); } //! Transform transform to parent (returns compound transform: first src, then *this) - PX_CUDA_CALLABLE PX_FORCE_INLINE PxTransform transform(const PxTransform& src) const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxTransformT transform(const PxTransformT& src) const { - PX_SHARED_ASSERT(src.isSane()); - PX_SHARED_ASSERT(isSane()); + PX_ASSERT(src.isSane()); + PX_ASSERT(isSane()); // src = [srct, srcr] -> [r*srct + t, r*srcr] - return PxTransform(q.rotate(src.p) + p, q * src.q); + return PxTransformT(q.rotate(src.p) + p, q * src.q); } /** \brief returns true if finite and q is a unit quaternion */ - PX_CUDA_CALLABLE bool isValid() const { return p.isFinite() && q.isFinite() && q.isUnit(); @@ -154,7 +163,6 @@ class PxTransform \brief returns true if finite and quat magnitude is reasonably close to unit to allow for some accumulation of error vs isValid */ - PX_CUDA_CALLABLE bool isSane() const { return isFinite() && q.isSane(); @@ -169,47 +177,48 @@ class PxTransform } //! Transform transform from parent (returns compound transform: first src, then this->inverse) - PX_CUDA_CALLABLE PX_FORCE_INLINE PxTransform transformInv(const PxTransform& src) const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxTransformT transformInv(const PxTransformT& src) const { - PX_SHARED_ASSERT(src.isSane()); - PX_SHARED_ASSERT(isFinite()); + PX_ASSERT(src.isSane()); + PX_ASSERT(isFinite()); // src = [srct, srcr] -> [r^-1*(srct-t), r^-1*srcr] - PxQuat qinv = q.getConjugate(); - return PxTransform(qinv.rotate(src.p - p), qinv * src.q); - } - - /** - \brief transform plane - */ - - PX_CUDA_CALLABLE PX_FORCE_INLINE PxPlane transform(const PxPlane& plane) const - { - PxVec3 transformedNormal = rotate(plane.n); - return PxPlane(transformedNormal, plane.d - p.dot(transformedNormal)); - } - - /** - \brief inverse-transform plane - */ - - PX_CUDA_CALLABLE PX_FORCE_INLINE PxPlane inverseTransform(const PxPlane& plane) const - { - PxVec3 transformedNormal = rotateInv(plane.n); - return PxPlane(transformedNormal, plane.d + p.dot(plane.n)); + const PxQuatT qinv = q.getConjugate(); + return PxTransformT(qinv.rotate(src.p - p), qinv * src.q); } /** \brief return a normalized transform (i.e. one in which the quaternion has unit magnitude) */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxTransform getNormalized() const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxTransformT getNormalized() const { - return PxTransform(p, q.getNormalized()); + return PxTransformT(p, q.getNormalized()); } }; +typedef PxTransformT PxTransform; +typedef PxTransformT PxTransformd; + +/*! +\brief A generic padded & aligned transform class. + +This can be used for safe faster loads & stores, and faster address computations +(the default PxTransformT often generating imuls for this otherwise). Padding bytes +can be reused to store useful data if needed. +*/ +struct PX_ALIGN_PREFIX(16) PxTransformPadded +{ + PxTransform transform; + PxU32 padding; +} +PX_ALIGN_SUFFIX(16); +PX_COMPILE_TIME_ASSERT(sizeof(PxTransformPadded)==32); + +typedef PxTransformPadded PxTransform32; + #if !PX_DOXYGEN } // namespace physx #endif /** @} */ -#endif // #ifndef PXFOUNDATION_PXTRANSFORM_H +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxUnionCast.h b/Source/ThirdParty/PhysX/foundation/PxUnionCast.h index 007493cba..95d7d1d25 100644 --- a/Source/ThirdParty/PhysX/foundation/PxUnionCast.h +++ b/Source/ThirdParty/PhysX/foundation/PxUnionCast.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PXFOUNDATION_PXUNIONCAST_H -#define PXFOUNDATION_PXUNIONCAST_H +#ifndef PX_UNION_CAST_H +#define PX_UNION_CAST_H #include "foundation/Px.h" @@ -70,4 +69,5 @@ PX_FORCE_INLINE A PxUnionCast(B b) /** @} */ -#endif // PXFOUNDATION_PXUNIONCAST_H +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxUserAllocated.h b/Source/ThirdParty/PhysX/foundation/PxUserAllocated.h new file mode 100644 index 000000000..d5be1724c --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxUserAllocated.h @@ -0,0 +1,116 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_USER_ALLOCATED_H +#define PX_USER_ALLOCATED_H + +#include "PxAllocator.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + /** + Provides new and delete using a UserAllocator. + Guarantees that 'delete x;' uses the UserAllocator too. + */ + class PxUserAllocated + { + public: + // PX_SERIALIZATION + PX_INLINE void* operator new(size_t, void* address) + { + return address; + } + + //~PX_SERIALIZATION + // Matching operator delete to the above operator new. Don't ask me + // how this makes any sense - Nuernberger. + PX_INLINE void operator delete(void*, void*) + { + } + + template + PX_INLINE void* operator new(size_t size, Alloc alloc, const char* fileName, int line) + { + return alloc.allocate(size, fileName, line); + } + + template + PX_INLINE void* operator new(size_t size, size_t /*align*/, Alloc alloc, const char* fileName, int line) + { + // align is not respected, we have 16bit aligned allocator + return alloc.allocate(size, fileName, line); + } + + template + PX_INLINE void* operator new [](size_t size, Alloc alloc, const char* fileName, int line) + { + return alloc.allocate(size, fileName, line); + } + + template + PX_INLINE void* operator new [](size_t size, size_t /*align*/, Alloc alloc, const char* fileName, int line) + { + // align is not respected, we have 16bit aligned allocator + return alloc.allocate(size, fileName, line); + } + + // placement delete + template + PX_INLINE void operator delete(void* ptr, Alloc alloc, const char* fileName, int line) + { + PX_UNUSED(fileName); + PX_UNUSED(line); + alloc.deallocate(ptr); + } + + template + PX_INLINE void operator delete [](void* ptr, Alloc alloc, const char* fileName, int line) + { + PX_UNUSED(fileName); + PX_UNUSED(line); + alloc.deallocate(ptr); + } + + PX_INLINE void operator delete(void* ptr) + { + PxAllocator().deallocate(ptr); + } + + PX_INLINE void operator delete [](void* ptr) + { + PxAllocator().deallocate(ptr); + } + }; +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxUtilities.h b/Source/ThirdParty/PhysX/foundation/PxUtilities.h new file mode 100644 index 000000000..39dc5c590 --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxUtilities.h @@ -0,0 +1,148 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_UTILITIES_H +#define PX_UTILITIES_H + +#include "foundation/PxVec3.h" +#include "foundation/PxAssert.h" +#include "foundation/PxIntrinsics.h" +#include "foundation/PxBasicTemplates.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif +PX_INLINE char PxLittleEndian() +{ + int i = 1; + return *(reinterpret_cast(&i)); +} + +// PT: checked casts +PX_CUDA_CALLABLE PX_FORCE_INLINE PxU32 PxTo32(PxU64 value) +{ + PX_ASSERT(value <= 0xffffffff); + return PxU32(value); +} +PX_CUDA_CALLABLE PX_FORCE_INLINE PxU16 PxTo16(PxU32 value) +{ + PX_ASSERT(value <= 0xffff); + return PxU16(value); +} +PX_CUDA_CALLABLE PX_FORCE_INLINE PxU8 PxTo8(PxU16 value) +{ + PX_ASSERT(value <= 0xff); + return PxU8(value); +} +PX_CUDA_CALLABLE PX_FORCE_INLINE PxU8 PxTo8(PxU32 value) +{ + PX_ASSERT(value <= 0xff); + return PxU8(value); +} +PX_CUDA_CALLABLE PX_FORCE_INLINE PxU8 PxTo8(PxI32 value) +{ + PX_ASSERT(value <= 0xff); + PX_ASSERT(value >= 0); + return PxU8(value); +} +PX_CUDA_CALLABLE PX_FORCE_INLINE PxI8 PxToI8(PxU32 value) +{ + PX_ASSERT(value <= 0x7f); + return PxI8(value); +} + +//! @cond +/*! +Get number of elements in array +*/ +template +char (&PxArraySizeHelper(T (&array)[N]))[N]; +#define PX_ARRAY_SIZE(_array) (sizeof(physx::PxArraySizeHelper(_array))) +//! @endcond + +/*! +Sort two elements using operator< + +On return x will be the smaller of the two +*/ +template +PX_CUDA_CALLABLE PX_FORCE_INLINE void PxOrder(T& x, T& y) +{ + if(y < x) + PxSwap(x, y); +} + +// most architectures can do predication on real comparisons, and on VMX, it matters + +PX_CUDA_CALLABLE PX_FORCE_INLINE void PxOrder(PxReal& x, PxReal& y) +{ + PxReal newX = PxMin(x, y); + PxReal newY = PxMax(x, y); + x = newX; + y = newY; +} + +/*! +Sort two elements using operator< and also keep order +of any extra data +*/ +template +PX_CUDA_CALLABLE PX_FORCE_INLINE void PxOrder(T& x, T& y, E1& xe1, E1& ye1) +{ + if(y < x) + { + swap(x, y); + swap(xe1, ye1); + } +} + +#if PX_GCC_FAMILY && !PX_EMSCRIPTEN && !PX_ANDROID +__attribute__((noreturn)) +#endif + PX_INLINE void PxDebugBreak() +{ +#if PX_WINDOWS + __debugbreak(); +#elif PX_ANDROID + raise(SIGTRAP); // works better than __builtin_trap. Proper call stack and can be continued. +#elif PX_LINUX + __builtin_trap(); +#elif PX_GCC_FAMILY + __builtin_trap(); +#else + PX_ASSERT(false); +#endif +} + +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxVec2.h b/Source/ThirdParty/PhysX/foundation/PxVec2.h index 11281115b..12c2f51be 100644 --- a/Source/ThirdParty/PhysX/foundation/PxVec2.h +++ b/Source/ThirdParty/PhysX/foundation/PxVec2.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PXFOUNDATION_PXVEC2_H -#define PXFOUNDATION_PXVEC2_H +#ifndef PX_VEC2_H +#define PX_VEC2_H /** \addtogroup foundation @{ @@ -46,22 +45,22 @@ namespace physx This is a 2-dimensional vector class with public data members. */ -class PxVec2 +template +class PxVec2T { public: /** \brief default constructor leaves data uninitialized. */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2() + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2T() { } /** \brief zero constructor. */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2(PxZERO r) : x(0.0f), y(0.0f) + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2T(PxZERO) : x(Type(0.0)), y(Type(0.0)) { - PX_UNUSED(r); } /** @@ -71,7 +70,7 @@ class PxVec2 \param[in] a Value to assign to elements. */ - explicit PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2(float a) : x(a), y(a) + explicit PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2T(Type a) : x(a), y(a) { } @@ -81,14 +80,14 @@ class PxVec2 \param[in] nx Value to initialize X component. \param[in] ny Value to initialize Y component. */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2(float nx, float ny) : x(nx), y(ny) + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2T(Type nx, Type ny) : x(nx), y(ny) { } /** \brief Copy ctor. */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2(const PxVec2& v) : x(v.x), y(v.y) + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2T(const PxVec2T& v) : x(v.x), y(v.y) { } @@ -97,7 +96,7 @@ class PxVec2 /** \brief Assignment operator */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2& operator=(const PxVec2& p) + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2T& operator=(const PxVec2T& p) { x = p.x; y = p.y; @@ -107,27 +106,25 @@ class PxVec2 /** \brief element access */ - PX_CUDA_CALLABLE PX_FORCE_INLINE float& operator[](int index) + PX_CUDA_CALLABLE PX_FORCE_INLINE Type& operator[](unsigned int index) { - PX_SHARED_ASSERT(index >= 0 && index <= 1); - - return reinterpret_cast(this)[index]; + PX_ASSERT(index <= 1); + return reinterpret_cast(this)[index]; } /** \brief element access */ - PX_CUDA_CALLABLE PX_FORCE_INLINE const float& operator[](int index) const + PX_CUDA_CALLABLE PX_FORCE_INLINE const Type& operator[](unsigned int index) const { - PX_SHARED_ASSERT(index >= 0 && index <= 1); - - return reinterpret_cast(this)[index]; + PX_ASSERT(index <= 1); + return reinterpret_cast(this)[index]; } /** \brief returns true if the two vectors are exactly equal. */ - PX_CUDA_CALLABLE PX_FORCE_INLINE bool operator==(const PxVec2& v) const + PX_CUDA_CALLABLE PX_FORCE_INLINE bool operator==(const PxVec2T& v) const { return x == v.x && y == v.y; } @@ -135,7 +132,7 @@ class PxVec2 /** \brief returns true if the two vectors are not exactly equal. */ - PX_CUDA_CALLABLE PX_FORCE_INLINE bool operator!=(const PxVec2& v) const + PX_CUDA_CALLABLE PX_FORCE_INLINE bool operator!=(const PxVec2T& v) const { return x != v.x || y != v.y; } @@ -145,7 +142,7 @@ class PxVec2 */ PX_CUDA_CALLABLE PX_FORCE_INLINE bool isZero() const { - return x == 0.0f && y == 0.0f; + return x == Type(0.0) && y == Type(0.0); } /** @@ -161,8 +158,8 @@ class PxVec2 */ PX_CUDA_CALLABLE PX_FORCE_INLINE bool isNormalized() const { - const float unitTolerance = 1e-4f; - return isFinite() && PxAbs(magnitude() - 1) < unitTolerance; + const Type unitTolerance = Type(1e-4); + return isFinite() && PxAbs(magnitude() - Type(1.0)) < unitTolerance; } /** @@ -170,7 +167,7 @@ class PxVec2 Avoids calling PxSqrt()! */ - PX_CUDA_CALLABLE PX_FORCE_INLINE float magnitudeSquared() const + PX_CUDA_CALLABLE PX_FORCE_INLINE Type magnitudeSquared() const { return x * x + y * y; } @@ -178,7 +175,7 @@ class PxVec2 /** \brief returns the magnitude */ - PX_CUDA_CALLABLE PX_FORCE_INLINE float magnitude() const + PX_CUDA_CALLABLE PX_FORCE_INLINE Type magnitude() const { return PxSqrt(magnitudeSquared()); } @@ -186,48 +183,48 @@ class PxVec2 /** \brief negation */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2 operator-() const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2T operator-() const { - return PxVec2(-x, -y); + return PxVec2T(-x, -y); } /** \brief vector addition */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2 operator+(const PxVec2& v) const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2T operator+(const PxVec2T& v) const { - return PxVec2(x + v.x, y + v.y); + return PxVec2T(x + v.x, y + v.y); } /** \brief vector difference */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2 operator-(const PxVec2& v) const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2T operator-(const PxVec2T& v) const { - return PxVec2(x - v.x, y - v.y); + return PxVec2T(x - v.x, y - v.y); } /** \brief scalar post-multiplication */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2 operator*(float f) const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2T operator*(Type f) const { - return PxVec2(x * f, y * f); + return PxVec2T(x * f, y * f); } /** \brief scalar division */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2 operator/(float f) const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2T operator/(Type f) const { - f = 1.0f / f; // PT: inconsistent notation with operator /= - return PxVec2(x * f, y * f); + f = Type(1.0) / f; + return PxVec2T(x * f, y * f); } /** \brief vector addition */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2& operator+=(const PxVec2& v) + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2T& operator+=(const PxVec2T& v) { x += v.x; y += v.y; @@ -237,7 +234,7 @@ class PxVec2 /** \brief vector difference */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2& operator-=(const PxVec2& v) + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2T& operator-=(const PxVec2T& v) { x -= v.x; y -= v.y; @@ -247,18 +244,19 @@ class PxVec2 /** \brief scalar multiplication */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2& operator*=(float f) + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2T& operator*=(Type f) { x *= f; y *= f; return *this; } + /** \brief scalar division */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2& operator/=(float f) + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2T& operator/=(Type f) { - f = 1.0f / f; // PT: inconsistent notation with operator / + f = Type(1.0) / f; x *= f; y *= f; return *this; @@ -267,26 +265,25 @@ class PxVec2 /** \brief returns the scalar product of this and other. */ - PX_CUDA_CALLABLE PX_FORCE_INLINE float dot(const PxVec2& v) const + PX_CUDA_CALLABLE PX_FORCE_INLINE Type dot(const PxVec2T& v) const { return x * v.x + y * v.y; } - /** return a unit vector */ - - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2 getNormalized() const + /** returns a unit vector */ + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2T getNormalized() const { - const float m = magnitudeSquared(); - return m > 0.0f ? *this * PxRecipSqrt(m) : PxVec2(0, 0); + const Type m = magnitudeSquared(); + return m > Type(0.0) ? *this * PxRecipSqrt(m) : PxVec2T(Type(0)); } /** \brief normalizes the vector in place */ - PX_CUDA_CALLABLE PX_FORCE_INLINE float normalize() + PX_CUDA_CALLABLE PX_FORCE_INLINE Type normalize() { - const float m = magnitude(); - if(m > 0.0f) + const Type m = magnitude(); + if(m > Type(0.0)) *this /= m; return m; } @@ -294,23 +291,23 @@ class PxVec2 /** \brief a[i] * b[i], for all i. */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2 multiply(const PxVec2& a) const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2T multiply(const PxVec2T& a) const { - return PxVec2(x * a.x, y * a.y); + return PxVec2T(x * a.x, y * a.y); } /** \brief element-wise minimum */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2 minimum(const PxVec2& v) const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2T minimum(const PxVec2T& v) const { - return PxVec2(PxMin(x, v.x), PxMin(y, v.y)); + return PxVec2T(PxMin(x, v.x), PxMin(y, v.y)); } /** \brief returns MIN(x, y); */ - PX_CUDA_CALLABLE PX_FORCE_INLINE float minElement() const + PX_CUDA_CALLABLE PX_FORCE_INLINE Type minElement() const { return PxMin(x, y); } @@ -318,30 +315,35 @@ class PxVec2 /** \brief element-wise maximum */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2 maximum(const PxVec2& v) const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec2T maximum(const PxVec2T& v) const { - return PxVec2(PxMax(x, v.x), PxMax(y, v.y)); + return PxVec2T(PxMax(x, v.x), PxMax(y, v.y)); } /** \brief returns MAX(x, y); */ - PX_CUDA_CALLABLE PX_FORCE_INLINE float maxElement() const + PX_CUDA_CALLABLE PX_FORCE_INLINE Type maxElement() const { return PxMax(x, y); } - float x, y; + Type x, y; }; -PX_CUDA_CALLABLE static PX_FORCE_INLINE PxVec2 operator*(float f, const PxVec2& v) +template +PX_CUDA_CALLABLE static PX_FORCE_INLINE PxVec2T operator*(Type f, const PxVec2T& v) { - return PxVec2(f * v.x, f * v.y); + return PxVec2T(f * v.x, f * v.y); } +typedef PxVec2T PxVec2; +typedef PxVec2T PxVec2d; + #if !PX_DOXYGEN } // namespace physx #endif /** @} */ -#endif // #ifndef PXFOUNDATION_PXVEC2_H +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxVec3.h b/Source/ThirdParty/PhysX/foundation/PxVec3.h index d3baead98..af51e8c4c 100644 --- a/Source/ThirdParty/PhysX/foundation/PxVec3.h +++ b/Source/ThirdParty/PhysX/foundation/PxVec3.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PXFOUNDATION_PXVEC3_H -#define PXFOUNDATION_PXVEC3_H +#ifndef PX_VEC3_H +#define PX_VEC3_H /** \addtogroup foundation @{ @@ -46,22 +45,23 @@ namespace physx This is a 3-dimensional vector class with public data members. */ -class PxVec3 +template +class PxVec3T { public: + /** \brief default constructor leaves data uninitialized. */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3() + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T() { } /** \brief zero constructor. */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3(PxZERO r) : x(0.0f), y(0.0f), z(0.0f) + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T(PxZERO) : x(Type(0.0)), y(Type(0.0)), z(Type(0.0)) { - PX_UNUSED(r); } /** @@ -71,7 +71,7 @@ class PxVec3 \param[in] a Value to assign to elements. */ - explicit PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3(float a) : x(a), y(a), z(a) + explicit PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T(Type a) : x(a), y(a), z(a) { } @@ -82,14 +82,14 @@ class PxVec3 \param[in] ny Value to initialize Y component. \param[in] nz Value to initialize Z component. */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3(float nx, float ny, float nz) : x(nx), y(ny), z(nz) + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T(Type nx, Type ny, Type nz) : x(nx), y(ny), z(nz) { } /** \brief Copy ctor. */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3(const PxVec3& v) : x(v.x), y(v.y), z(v.z) + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T(const PxVec3T& v) : x(v.x), y(v.y), z(v.z) { } @@ -98,7 +98,7 @@ class PxVec3 /** \brief Assignment operator */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3& operator=(const PxVec3& p) + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T& operator=(const PxVec3T& p) { x = p.x; y = p.y; @@ -109,27 +109,25 @@ class PxVec3 /** \brief element access */ - PX_CUDA_CALLABLE PX_FORCE_INLINE float& operator[](unsigned int index) + PX_CUDA_CALLABLE PX_FORCE_INLINE Type& operator[](unsigned int index) { - PX_SHARED_ASSERT(index <= 2); - - return reinterpret_cast(this)[index]; + PX_ASSERT(index <= 2); + return reinterpret_cast(this)[index]; } /** \brief element access */ - PX_CUDA_CALLABLE PX_FORCE_INLINE const float& operator[](unsigned int index) const + PX_CUDA_CALLABLE PX_FORCE_INLINE const Type& operator[](unsigned int index) const { - PX_SHARED_ASSERT(index <= 2); - - return reinterpret_cast(this)[index]; + PX_ASSERT(index <= 2); + return reinterpret_cast(this)[index]; } /** \brief returns true if the two vectors are exactly equal. */ - PX_CUDA_CALLABLE PX_FORCE_INLINE bool operator==(const PxVec3& v) const + PX_CUDA_CALLABLE PX_FORCE_INLINE bool operator==(const PxVec3T& v) const { return x == v.x && y == v.y && z == v.z; } @@ -137,7 +135,7 @@ class PxVec3 /** \brief returns true if the two vectors are not exactly equal. */ - PX_CUDA_CALLABLE PX_FORCE_INLINE bool operator!=(const PxVec3& v) const + PX_CUDA_CALLABLE PX_FORCE_INLINE bool operator!=(const PxVec3T& v) const { return x != v.x || y != v.y || z != v.z; } @@ -147,7 +145,7 @@ class PxVec3 */ PX_CUDA_CALLABLE PX_FORCE_INLINE bool isZero() const { - return x == 0.0f && y == 0.0f && z == 0.0f; + return x == Type(0.0) && y == Type(0.0) && z == Type(0.0); } /** @@ -163,8 +161,8 @@ class PxVec3 */ PX_CUDA_CALLABLE PX_FORCE_INLINE bool isNormalized() const { - const float unitTolerance = 1e-4f; - return isFinite() && PxAbs(magnitude() - 1) < unitTolerance; + const float unitTolerance = Type(1e-4); // PT: do we need a different epsilon for float & double? + return isFinite() && PxAbs(magnitude() - Type(1.0)) < unitTolerance; } /** @@ -172,7 +170,7 @@ class PxVec3 Avoids calling PxSqrt()! */ - PX_CUDA_CALLABLE PX_FORCE_INLINE float magnitudeSquared() const + PX_CUDA_CALLABLE PX_FORCE_INLINE Type magnitudeSquared() const { return x * x + y * y + z * z; } @@ -180,7 +178,7 @@ class PxVec3 /** \brief returns the magnitude */ - PX_CUDA_CALLABLE PX_FORCE_INLINE float magnitude() const + PX_CUDA_CALLABLE PX_FORCE_INLINE Type magnitude() const { return PxSqrt(magnitudeSquared()); } @@ -188,48 +186,48 @@ class PxVec3 /** \brief negation */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 operator-() const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T operator-() const { - return PxVec3(-x, -y, -z); + return PxVec3T(-x, -y, -z); } /** \brief vector addition */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 operator+(const PxVec3& v) const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T operator+(const PxVec3T& v) const { - return PxVec3(x + v.x, y + v.y, z + v.z); + return PxVec3T(x + v.x, y + v.y, z + v.z); } /** \brief vector difference */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 operator-(const PxVec3& v) const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T operator-(const PxVec3T& v) const { - return PxVec3(x - v.x, y - v.y, z - v.z); + return PxVec3T(x - v.x, y - v.y, z - v.z); } /** \brief scalar post-multiplication */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 operator*(float f) const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T operator*(Type f) const { - return PxVec3(x * f, y * f, z * f); + return PxVec3T(x * f, y * f, z * f); } /** \brief scalar division */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 operator/(float f) const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T operator/(Type f) const { - f = 1.0f / f; - return PxVec3(x * f, y * f, z * f); + f = Type(1.0) / f; + return PxVec3T(x * f, y * f, z * f); } /** \brief vector addition */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3& operator+=(const PxVec3& v) + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T& operator+=(const PxVec3T& v) { x += v.x; y += v.y; @@ -240,7 +238,7 @@ class PxVec3 /** \brief vector difference */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3& operator-=(const PxVec3& v) + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T& operator-=(const PxVec3T& v) { x -= v.x; y -= v.y; @@ -251,7 +249,7 @@ class PxVec3 /** \brief scalar multiplication */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3& operator*=(float f) + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T& operator*=(Type f) { x *= f; y *= f; @@ -261,9 +259,9 @@ class PxVec3 /** \brief scalar division */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3& operator/=(float f) + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T& operator/=(Type f) { - f = 1.0f / f; + f = Type(1.0) / f; x *= f; y *= f; z *= f; @@ -273,7 +271,7 @@ class PxVec3 /** \brief returns the scalar product of this and other. */ - PX_CUDA_CALLABLE PX_FORCE_INLINE float dot(const PxVec3& v) const + PX_CUDA_CALLABLE PX_FORCE_INLINE Type dot(const PxVec3T& v) const { return x * v.x + y * v.y + z * v.z; } @@ -281,26 +279,25 @@ class PxVec3 /** \brief cross product */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 cross(const PxVec3& v) const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T cross(const PxVec3T& v) const { - return PxVec3(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x); + return PxVec3T(y * v.z - z * v.y, z * v.x - x * v.z, x * v.y - y * v.x); } - /** return a unit vector */ - - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 getNormalized() const + /** returns a unit vector */ + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T getNormalized() const { - const float m = magnitudeSquared(); - return m > 0.0f ? *this * PxRecipSqrt(m) : PxVec3(0, 0, 0); + const Type m = magnitudeSquared(); + return m > Type(0.0) ? *this * PxRecipSqrt(m) : PxVec3T(Type(0)); } /** \brief normalizes the vector in place */ - PX_CUDA_CALLABLE PX_FORCE_INLINE float normalize() + PX_CUDA_CALLABLE PX_FORCE_INLINE Type normalize() { - const float m = magnitude(); - if(m > 0.0f) + const Type m = magnitude(); + if(m > Type(0.0)) *this /= m; return m; } @@ -309,12 +306,12 @@ class PxVec3 \brief normalizes the vector in place. Does nothing if vector magnitude is under PX_NORMALIZATION_EPSILON. Returns vector magnitude if >= PX_NORMALIZATION_EPSILON and 0.0f otherwise. */ - PX_CUDA_CALLABLE PX_FORCE_INLINE float normalizeSafe() + PX_CUDA_CALLABLE PX_FORCE_INLINE Type normalizeSafe() { - const float mag = magnitude(); - if(mag < PX_NORMALIZATION_EPSILON) - return 0.0f; - *this *= 1.0f / mag; + const Type mag = magnitude(); + if(mag < PX_NORMALIZATION_EPSILON) // PT: do we need a different epsilon for float & double? + return Type(0.0); + *this *= Type(1.0) / mag; return mag; } @@ -322,34 +319,34 @@ class PxVec3 \brief normalizes the vector in place. Asserts if vector magnitude is under PX_NORMALIZATION_EPSILON. returns vector magnitude. */ - PX_CUDA_CALLABLE PX_FORCE_INLINE float normalizeFast() + PX_CUDA_CALLABLE PX_FORCE_INLINE Type normalizeFast() { - const float mag = magnitude(); - PX_SHARED_ASSERT(mag >= PX_NORMALIZATION_EPSILON); - *this *= 1.0f / mag; + const Type mag = magnitude(); + PX_ASSERT(mag >= PX_NORMALIZATION_EPSILON); // PT: do we need a different epsilon for float & double? + *this *= Type(1.0) / mag; return mag; } /** \brief a[i] * b[i], for all i. */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 multiply(const PxVec3& a) const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T multiply(const PxVec3T& a) const { - return PxVec3(x * a.x, y * a.y, z * a.z); + return PxVec3T(x * a.x, y * a.y, z * a.z); } /** \brief element-wise minimum */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 minimum(const PxVec3& v) const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T minimum(const PxVec3T& v) const { - return PxVec3(PxMin(x, v.x), PxMin(y, v.y), PxMin(z, v.z)); + return PxVec3T(PxMin(x, v.x), PxMin(y, v.y), PxMin(z, v.z)); } /** \brief returns MIN(x, y, z); */ - PX_CUDA_CALLABLE PX_FORCE_INLINE float minElement() const + PX_CUDA_CALLABLE PX_FORCE_INLINE Type minElement() const { return PxMin(x, PxMin(y, z)); } @@ -357,15 +354,15 @@ class PxVec3 /** \brief element-wise maximum */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 maximum(const PxVec3& v) const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T maximum(const PxVec3T& v) const { - return PxVec3(PxMax(x, v.x), PxMax(y, v.y), PxMax(z, v.z)); + return PxVec3T(PxMax(x, v.x), PxMax(y, v.y), PxMax(z, v.z)); } /** \brief returns MAX(x, y, z); */ - PX_CUDA_CALLABLE PX_FORCE_INLINE float maxElement() const + PX_CUDA_CALLABLE PX_FORCE_INLINE Type maxElement() const { return PxMax(x, PxMax(y, z)); } @@ -373,22 +370,54 @@ class PxVec3 /** \brief returns absolute values of components; */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3 abs() const + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3T abs() const { - return PxVec3(PxAbs(x), PxAbs(y), PxAbs(z)); + return PxVec3T(PxAbs(x), PxAbs(y), PxAbs(z)); } - float x, y, z; + Type x, y, z; }; -PX_CUDA_CALLABLE static PX_FORCE_INLINE PxVec3 operator*(float f, const PxVec3& v) +template +PX_CUDA_CALLABLE static PX_FORCE_INLINE PxVec3T operator*(Type f, const PxVec3T& v) { - return PxVec3(f * v.x, f * v.y, f * v.z); + return PxVec3T(f * v.x, f * v.y, f * v.z); } +typedef PxVec3T PxVec3; +typedef PxVec3T PxVec3d; + +//! A padded version of PxVec3, to safely load its data using SIMD +class PxVec3Padded : public PxVec3 +{ + public: + PX_FORCE_INLINE PxVec3Padded() {} + PX_FORCE_INLINE ~PxVec3Padded() {} + PX_FORCE_INLINE PxVec3Padded(const PxVec3& p) : PxVec3(p) {} + PX_FORCE_INLINE PxVec3Padded(float f) : PxVec3(f) {} + + /** + \brief Assignment operator. + To fix this: + error: definition of implicit copy assignment operator for 'PxVec3Padded' is deprecated because it has a user-declared destructor [-Werror,-Wdeprecated] + */ + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec3Padded& operator=(const PxVec3Padded& p) + { + x = p.x; + y = p.y; + z = p.z; + return *this; + } + + PxU32 padding; +}; +PX_COMPILE_TIME_ASSERT(sizeof(PxVec3Padded) == 16); + +typedef PxVec3Padded PxVec3p; + #if !PX_DOXYGEN } // namespace physx #endif /** @} */ -#endif // #ifndef PXFOUNDATION_PXVEC3_H +#endif diff --git a/Source/ThirdParty/PhysX/foundation/PxVec4.h b/Source/ThirdParty/PhysX/foundation/PxVec4.h index 711e5310e..f467a2f44 100644 --- a/Source/ThirdParty/PhysX/foundation/PxVec4.h +++ b/Source/ThirdParty/PhysX/foundation/PxVec4.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,18 +22,18 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PXFOUNDATION_PXVEC4_H -#define PXFOUNDATION_PXVEC4_H +#ifndef PX_VEC4_H +#define PX_VEC4_H + /** \addtogroup foundation @{ */ #include "foundation/PxMath.h" #include "foundation/PxVec3.h" -#include "foundation/PxSharedAssert.h" /** \brief 4 Element vector class. @@ -46,22 +45,22 @@ namespace physx { #endif -class PxVec4 +template +class PxVec4T { public: /** \brief default constructor leaves data uninitialized. */ - PX_CUDA_CALLABLE PX_INLINE PxVec4() + PX_CUDA_CALLABLE PX_INLINE PxVec4T() { } /** \brief zero constructor. */ - PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec4(PxZERO r) : x(0.0f), y(0.0f), z(0.0f), w(0.0f) + PX_CUDA_CALLABLE PX_FORCE_INLINE PxVec4T(PxZERO) : x(Type(0.0)), y(Type(0.0)), z(Type(0.0)), w(Type(0.0)) { - PX_UNUSED(r); } /** @@ -71,7 +70,7 @@ class PxVec4 \param[in] a Value to assign to elements. */ - explicit PX_CUDA_CALLABLE PX_INLINE PxVec4(float a) : x(a), y(a), z(a), w(a) + explicit PX_CUDA_CALLABLE PX_INLINE PxVec4T(Type a) : x(a), y(a), z(a), w(a) { } @@ -83,7 +82,7 @@ class PxVec4 \param[in] nz Value to initialize Z component. \param[in] nw Value to initialize W component. */ - PX_CUDA_CALLABLE PX_INLINE PxVec4(float nx, float ny, float nz, float nw) : x(nx), y(ny), z(nz), w(nw) + PX_CUDA_CALLABLE PX_INLINE PxVec4T(Type nx, Type ny, Type nz, Type nw) : x(nx), y(ny), z(nz), w(nw) { } @@ -93,7 +92,7 @@ class PxVec4 \param[in] v Value to initialize the X, Y, and Z components. \param[in] nw Value to initialize W component. */ - PX_CUDA_CALLABLE PX_INLINE PxVec4(const PxVec3& v, float nw) : x(v.x), y(v.y), z(v.z), w(nw) + PX_CUDA_CALLABLE PX_INLINE PxVec4T(const PxVec3T& v, Type nw) : x(v.x), y(v.y), z(v.z), w(nw) { } @@ -102,14 +101,14 @@ class PxVec4 \param[in] v Value to initialize with. */ - explicit PX_CUDA_CALLABLE PX_INLINE PxVec4(const float v[]) : x(v[0]), y(v[1]), z(v[2]), w(v[3]) + explicit PX_CUDA_CALLABLE PX_INLINE PxVec4T(const Type v[]) : x(v[0]), y(v[1]), z(v[2]), w(v[3]) { } /** \brief Copy ctor. */ - PX_CUDA_CALLABLE PX_INLINE PxVec4(const PxVec4& v) : x(v.x), y(v.y), z(v.z), w(v.w) + PX_CUDA_CALLABLE PX_INLINE PxVec4T(const PxVec4T& v) : x(v.x), y(v.y), z(v.z), w(v.w) { } @@ -118,7 +117,7 @@ class PxVec4 /** \brief Assignment operator */ - PX_CUDA_CALLABLE PX_INLINE PxVec4& operator=(const PxVec4& p) + PX_CUDA_CALLABLE PX_INLINE PxVec4T& operator=(const PxVec4T& p) { x = p.x; y = p.y; @@ -130,27 +129,25 @@ class PxVec4 /** \brief element access */ - PX_CUDA_CALLABLE PX_INLINE float& operator[](unsigned int index) + PX_CUDA_CALLABLE PX_INLINE Type& operator[](unsigned int index) { - PX_SHARED_ASSERT(index <= 3); - - return reinterpret_cast(this)[index]; + PX_ASSERT(index <= 3); + return reinterpret_cast(this)[index]; } /** \brief element access */ - PX_CUDA_CALLABLE PX_INLINE const float& operator[](unsigned int index) const + PX_CUDA_CALLABLE PX_INLINE const Type& operator[](unsigned int index) const { - PX_SHARED_ASSERT(index <= 3); - - return reinterpret_cast(this)[index]; + PX_ASSERT(index <= 3); + return reinterpret_cast(this)[index]; } /** \brief returns true if the two vectors are exactly equal. */ - PX_CUDA_CALLABLE PX_INLINE bool operator==(const PxVec4& v) const + PX_CUDA_CALLABLE PX_INLINE bool operator==(const PxVec4T& v) const { return x == v.x && y == v.y && z == v.z && w == v.w; } @@ -158,7 +155,7 @@ class PxVec4 /** \brief returns true if the two vectors are not exactly equal. */ - PX_CUDA_CALLABLE PX_INLINE bool operator!=(const PxVec4& v) const + PX_CUDA_CALLABLE PX_INLINE bool operator!=(const PxVec4T& v) const { return x != v.x || y != v.y || z != v.z || w != v.w; } @@ -168,7 +165,7 @@ class PxVec4 */ PX_CUDA_CALLABLE PX_INLINE bool isZero() const { - return x == 0 && y == 0 && z == 0 && w == 0; + return x == Type(0) && y == Type(0) && z == Type(0) && w == Type(0); } /** @@ -184,8 +181,8 @@ class PxVec4 */ PX_CUDA_CALLABLE PX_INLINE bool isNormalized() const { - const float unitTolerance = 1e-4f; - return isFinite() && PxAbs(magnitude() - 1) < unitTolerance; + const Type unitTolerance = Type(1e-4); + return isFinite() && PxAbs(magnitude() - Type(1.0)) < unitTolerance; } /** @@ -193,7 +190,7 @@ class PxVec4 Avoids calling PxSqrt()! */ - PX_CUDA_CALLABLE PX_INLINE float magnitudeSquared() const + PX_CUDA_CALLABLE PX_INLINE Type magnitudeSquared() const { return x * x + y * y + z * z + w * w; } @@ -201,7 +198,7 @@ class PxVec4 /** \brief returns the magnitude */ - PX_CUDA_CALLABLE PX_INLINE float magnitude() const + PX_CUDA_CALLABLE PX_INLINE Type magnitude() const { return PxSqrt(magnitudeSquared()); } @@ -209,49 +206,48 @@ class PxVec4 /** \brief negation */ - PX_CUDA_CALLABLE PX_INLINE PxVec4 operator-() const + PX_CUDA_CALLABLE PX_INLINE PxVec4T operator-() const { - return PxVec4(-x, -y, -z, -w); + return PxVec4T(-x, -y, -z, -w); } /** \brief vector addition */ - PX_CUDA_CALLABLE PX_INLINE PxVec4 operator+(const PxVec4& v) const + PX_CUDA_CALLABLE PX_INLINE PxVec4T operator+(const PxVec4T& v) const { - return PxVec4(x + v.x, y + v.y, z + v.z, w + v.w); + return PxVec4T(x + v.x, y + v.y, z + v.z, w + v.w); } /** \brief vector difference */ - PX_CUDA_CALLABLE PX_INLINE PxVec4 operator-(const PxVec4& v) const + PX_CUDA_CALLABLE PX_INLINE PxVec4T operator-(const PxVec4T& v) const { - return PxVec4(x - v.x, y - v.y, z - v.z, w - v.w); + return PxVec4T(x - v.x, y - v.y, z - v.z, w - v.w); } /** \brief scalar post-multiplication */ - - PX_CUDA_CALLABLE PX_INLINE PxVec4 operator*(float f) const + PX_CUDA_CALLABLE PX_INLINE PxVec4T operator*(Type f) const { - return PxVec4(x * f, y * f, z * f, w * f); + return PxVec4T(x * f, y * f, z * f, w * f); } /** \brief scalar division */ - PX_CUDA_CALLABLE PX_INLINE PxVec4 operator/(float f) const + PX_CUDA_CALLABLE PX_INLINE PxVec4T operator/(Type f) const { - f = 1.0f / f; - return PxVec4(x * f, y * f, z * f, w * f); + f = Type(1.0) / f; + return PxVec4T(x * f, y * f, z * f, w * f); } /** \brief vector addition */ - PX_CUDA_CALLABLE PX_INLINE PxVec4& operator+=(const PxVec4& v) + PX_CUDA_CALLABLE PX_INLINE PxVec4T& operator+=(const PxVec4T& v) { x += v.x; y += v.y; @@ -263,7 +259,7 @@ class PxVec4 /** \brief vector difference */ - PX_CUDA_CALLABLE PX_INLINE PxVec4& operator-=(const PxVec4& v) + PX_CUDA_CALLABLE PX_INLINE PxVec4T& operator-=(const PxVec4T& v) { x -= v.x; y -= v.y; @@ -275,7 +271,7 @@ class PxVec4 /** \brief scalar multiplication */ - PX_CUDA_CALLABLE PX_INLINE PxVec4& operator*=(float f) + PX_CUDA_CALLABLE PX_INLINE PxVec4T& operator*=(Type f) { x *= f; y *= f; @@ -286,9 +282,9 @@ class PxVec4 /** \brief scalar division */ - PX_CUDA_CALLABLE PX_INLINE PxVec4& operator/=(float f) + PX_CUDA_CALLABLE PX_INLINE PxVec4T& operator/=(Type f) { - f = 1.0f / f; + f = Type(1.0) / f; x *= f; y *= f; z *= f; @@ -299,26 +295,25 @@ class PxVec4 /** \brief returns the scalar product of this and other. */ - PX_CUDA_CALLABLE PX_INLINE float dot(const PxVec4& v) const + PX_CUDA_CALLABLE PX_INLINE Type dot(const PxVec4T& v) const { return x * v.x + y * v.y + z * v.z + w * v.w; } - /** return a unit vector */ - - PX_CUDA_CALLABLE PX_INLINE PxVec4 getNormalized() const + /** returns a unit vector */ + PX_CUDA_CALLABLE PX_INLINE PxVec4T getNormalized() const { - float m = magnitudeSquared(); - return m > 0.0f ? *this * PxRecipSqrt(m) : PxVec4(0, 0, 0, 0); + const Type m = magnitudeSquared(); + return m > Type(0.0) ? *this * PxRecipSqrt(m) : PxVec4T(Type(0)); } /** \brief normalizes the vector in place */ - PX_CUDA_CALLABLE PX_INLINE float normalize() + PX_CUDA_CALLABLE PX_INLINE Type normalize() { - float m = magnitude(); - if(m > 0.0f) + const Type m = magnitude(); + if(m > Type(0.0)) *this /= m; return m; } @@ -326,15 +321,15 @@ class PxVec4 /** \brief a[i] * b[i], for all i. */ - PX_CUDA_CALLABLE PX_INLINE PxVec4 multiply(const PxVec4& a) const + PX_CUDA_CALLABLE PX_INLINE PxVec4T multiply(const PxVec4T& a) const { - return PxVec4(x * a.x, y * a.y, z * a.z, w * a.w); + return PxVec4T(x * a.x, y * a.y, z * a.z, w * a.w); } /** \brief element-wise minimum */ - PX_CUDA_CALLABLE PX_INLINE PxVec4 minimum(const PxVec4& v) const + PX_CUDA_CALLABLE PX_INLINE PxVec4T minimum(const PxVec4T& v) const { return PxVec4(PxMin(x, v.x), PxMin(y, v.y), PxMin(z, v.z), PxMin(w, v.w)); } @@ -342,35 +337,32 @@ class PxVec4 /** \brief element-wise maximum */ - PX_CUDA_CALLABLE PX_INLINE PxVec4 maximum(const PxVec4& v) const + PX_CUDA_CALLABLE PX_INLINE PxVec4T maximum(const PxVec4T& v) const { - return PxVec4(PxMax(x, v.x), PxMax(y, v.y), PxMax(z, v.z), PxMax(w, v.w)); + return PxVec4T(PxMax(x, v.x), PxMax(y, v.y), PxMax(z, v.z), PxMax(w, v.w)); } - PX_CUDA_CALLABLE PX_INLINE PxVec3 getXYZ() const + PX_CUDA_CALLABLE PX_INLINE PxVec3T getXYZ() const { - return PxVec3(x, y, z); + return PxVec3T(x, y, z); } - /** - \brief set vector elements to zero - */ - PX_CUDA_CALLABLE PX_INLINE void setZero() - { - x = y = z = w = 0.0f; - } - - float x, y, z, w; + Type x, y, z, w; }; -PX_CUDA_CALLABLE static PX_INLINE PxVec4 operator*(float f, const PxVec4& v) +template +PX_CUDA_CALLABLE static PX_INLINE PxVec4T operator*(Type f, const PxVec4T& v) { - return PxVec4(f * v.x, f * v.y, f * v.z, f * v.w); + return PxVec4T(f * v.x, f * v.y, f * v.z, f * v.w); } +typedef PxVec4T PxVec4; +typedef PxVec4T PxVec4d; + #if !PX_DOXYGEN } // namespace physx #endif /** @} */ -#endif // #ifndef PXFOUNDATION_PXVEC4_H +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxVecMath.h b/Source/ThirdParty/PhysX/foundation/PxVecMath.h new file mode 100644 index 000000000..729729e6b --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxVecMath.h @@ -0,0 +1,1340 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_VEC_MATH_H +#define PX_VEC_MATH_H + +#include "foundation/Px.h" +#include "foundation/PxIntrinsics.h" +#include "foundation/PxVec3.h" +#include "foundation/PxVec4.h" +#include "foundation/PxMat33.h" +#include "foundation/PxUnionCast.h" + +// We can opt to use the scalar version of vectorised functions. +// This can catch type safety issues and might even work out more optimal on pc. +// It will also be useful for benchmarking and testing. +// NEVER submit with vector intrinsics deactivated without good reason. +// AM: deactivating SIMD for debug win64 just so autobuild will also exercise +// non-SIMD path, until a dedicated non-SIMD platform sich as Arm comes online. +// TODO: dima: reference all platforms with SIMD support here, +// all unknown/experimental cases should better default to NO SIMD. + +// enable/disable SIMD +#if !defined(PX_SIMD_DISABLED) +#if PX_INTEL_FAMILY && (!defined(__EMSCRIPTEN__) || defined(__SSE2__)) + #define COMPILE_VECTOR_INTRINSICS 1 +#elif PX_ANDROID && PX_NEON + #define COMPILE_VECTOR_INTRINSICS 1 +#elif PX_IOS && PX_NEON + #define COMPILE_VECTOR_INTRINSICS 1 +#elif PX_OSX && PX_NEON + #define COMPILE_VECTOR_INTRINSICS 1 +#elif PX_SWITCH + #define COMPILE_VECTOR_INTRINSICS 1 +#else + #define COMPILE_VECTOR_INTRINSICS 0 +#endif +#else + #define COMPILE_VECTOR_INTRINSICS 0 +#endif + +#if COMPILE_VECTOR_INTRINSICS && PX_INTEL_FAMILY && (PX_UNIX_FAMILY || PX_PS4 || PX_PS5) +// only SSE2 compatible platforms should reach this +#if PX_EMSCRIPTEN + #include +#endif + #include +#endif + +#if COMPILE_VECTOR_INTRINSICS + #include "PxAoS.h" +#else + #include "PxVecMathAoSScalar.h" +#endif + +#if !PX_DOXYGEN +namespace physx +{ +#endif +namespace aos +{ + +// Basic AoS types are +// FloatV - 16-byte aligned representation of float. +// Vec3V - 16-byte aligned representation of PxVec3 stored as (x y z 0). +// Vec4V - 16-byte aligned representation of vector of 4 floats stored as (x y z w). +// BoolV - 16-byte aligned representation of vector of 4 bools stored as (x y z w). +// VecU32V - 16-byte aligned representation of 4 unsigned ints stored as (x y z w). +// VecI32V - 16-byte aligned representation of 4 signed ints stored as (x y z w). +// Mat33V - 16-byte aligned representation of any 3x3 matrix. +// Mat34V - 16-byte aligned representation of transformation matrix (rotation in col1,col2,col3 and translation in +// col4). +// Mat44V - 16-byte aligned representation of any 4x4 matrix. + +////////////////////////////////////////// +// Construct a simd type from a scalar type +////////////////////////////////////////// + +// FloatV +//(f,f,f,f) +PX_FORCE_INLINE FloatV FLoad(const PxF32 f); + +// Vec3V +//(f,f,f,0) +PX_FORCE_INLINE Vec3V V3Load(const PxF32 f); +//(f.x,f.y,f.z,0) +PX_FORCE_INLINE Vec3V V3LoadU(const PxVec3& f); +//(f.x,f.y,f.z,0), f must be 16-byte aligned +PX_FORCE_INLINE Vec3V V3LoadA(const PxVec3& f); +//(f.x,f.y,f.z,w_undefined), f must be 16-byte aligned +PX_FORCE_INLINE Vec3V V3LoadUnsafeA(const PxVec3& f); +//(f.x,f.y,f.z,0) +PX_FORCE_INLINE Vec3V V3LoadU(const PxF32* f); +//(f.x,f.y,f.z,0), f must be 16-byte aligned +PX_FORCE_INLINE Vec3V V3LoadA(const PxF32* f); + +// Vec4V +//(f,f,f,f) +PX_FORCE_INLINE Vec4V V4Load(const PxF32 f); +//(f[0],f[1],f[2],f[3]) +PX_FORCE_INLINE Vec4V V4LoadU(const PxF32* const f); +//(f[0],f[1],f[2],f[3]), f must be 16-byte aligned +PX_FORCE_INLINE Vec4V V4LoadA(const PxF32* const f); +//(x,y,z,w) +PX_FORCE_INLINE Vec4V V4LoadXYZW(const PxF32& x, const PxF32& y, const PxF32& z, const PxF32& w); + +// BoolV +//(f,f,f,f) +PX_FORCE_INLINE BoolV BLoad(const bool f); +//(f[0],f[1],f[2],f[3]) +PX_FORCE_INLINE BoolV BLoad(const bool* const f); + +// VecU32V +//(f,f,f,f) +PX_FORCE_INLINE VecU32V U4Load(const PxU32 f); +//(f[0],f[1],f[2],f[3]) +PX_FORCE_INLINE VecU32V U4LoadU(const PxU32* f); +//(f[0],f[1],f[2],f[3]), f must be 16-byte aligned +PX_FORCE_INLINE VecU32V U4LoadA(const PxU32* f); +//((U32)x, (U32)y, (U32)z, (U32)w) +PX_FORCE_INLINE VecU32V U4LoadXYZW(PxU32 x, PxU32 y, PxU32 z, PxU32 w); + +// VecI32V +//(i,i,i,i) +PX_FORCE_INLINE VecI32V I4Load(const PxI32 i); +//(i,i,i,i) +PX_FORCE_INLINE VecI32V I4LoadU(const PxI32* i); +//(i,i,i,i) +PX_FORCE_INLINE VecI32V I4LoadA(const PxI32* i); + +// QuatV +//(x = v[0], y=v[1], z=v[2], w=v3[3]) and array don't need to aligned +PX_FORCE_INLINE QuatV QuatVLoadU(const PxF32* v); +//(x = v[0], y=v[1], z=v[2], w=v3[3]) and array need to aligned, fast load +PX_FORCE_INLINE QuatV QuatVLoadA(const PxF32* v); +//(x, y, z, w) +PX_FORCE_INLINE QuatV QuatVLoadXYZW(const PxF32 x, const PxF32 y, const PxF32 z, const PxF32 w); + +// not added to public api +Vec4V Vec4V_From_PxVec3_WUndefined(const PxVec3& v); + +/////////////////////////////////////////////////// +// Construct a simd type from a different simd type +/////////////////////////////////////////////////// + +// Vec3V +//(v.x,v.y,v.z,0) +PX_FORCE_INLINE Vec3V Vec3V_From_Vec4V(Vec4V v); +//(v.x,v.y,v.z,undefined) - be very careful with w!=0 because many functions require w==0 for correct operation eg V3Dot, V3Length, V3Cross etc etc. +PX_FORCE_INLINE Vec3V Vec3V_From_Vec4V_WUndefined(const Vec4V v); + +// Vec4V +//(f.x,f.y,f.z,f.w) +PX_FORCE_INLINE Vec4V Vec4V_From_Vec3V(Vec3V f); +//((PxF32)f.x, (PxF32)f.y, (PxF32)f.z, (PxF32)f.w) +PX_FORCE_INLINE Vec4V Vec4V_From_VecU32V(VecU32V a); +//((PxF32)f.x, (PxF32)f.y, (PxF32)f.z, (PxF32)f.w) +PX_FORCE_INLINE Vec4V Vec4V_From_VecI32V(VecI32V a); +//(*(reinterpret_cast(&f.x), (reinterpret_cast(&f.y), (reinterpret_cast(&f.z), +//(reinterpret_cast(&f.w)) +PX_FORCE_INLINE Vec4V Vec4V_ReinterpretFrom_VecU32V(VecU32V a); +//(*(reinterpret_cast(&f.x), (reinterpret_cast(&f.y), (reinterpret_cast(&f.z), +//(reinterpret_cast(&f.w)) +PX_FORCE_INLINE Vec4V Vec4V_ReinterpretFrom_VecI32V(VecI32V a); + +// VecU32V +//(*(reinterpret_cast(&f.x), (reinterpret_cast(&f.y), (reinterpret_cast(&f.z), +//(reinterpret_cast(&f.w)) +PX_FORCE_INLINE VecU32V VecU32V_ReinterpretFrom_Vec4V(Vec4V a); +//(b[0], b[1], b[2], b[3]) +PX_FORCE_INLINE VecU32V VecU32V_From_BoolV(const BoolVArg b); + +// VecI32V +//(*(reinterpret_cast(&f.x), (reinterpret_cast(&f.y), (reinterpret_cast(&f.z), +//(reinterpret_cast(&f.w)) +PX_FORCE_INLINE VecI32V VecI32V_ReinterpretFrom_Vec4V(Vec4V a); +//((I32)a.x, (I32)a.y, (I32)a.z, (I32)a.w) +PX_FORCE_INLINE VecI32V VecI32V_From_Vec4V(Vec4V a); +//((I32)b.x, (I32)b.y, (I32)b.z, (I32)b.w) +PX_FORCE_INLINE VecI32V VecI32V_From_BoolV(const BoolVArg b); + +/////////////////////////////////////////////////// +// Convert from a simd type back to a scalar type +/////////////////////////////////////////////////// + +// FloatV +// a.x +PX_FORCE_INLINE void FStore(const FloatV a, PxF32* PX_RESTRICT f); + +// Vec3V +//(a.x,a.y,a.z) +PX_FORCE_INLINE void V3StoreA(const Vec3V a, PxVec3& f); +//(a.x,a.y,a.z) +PX_FORCE_INLINE void V3StoreU(const Vec3V a, PxVec3& f); + +// Vec4V +PX_FORCE_INLINE void V4StoreA(const Vec4V a, PxF32* f); +PX_FORCE_INLINE void V4StoreU(const Vec4V a, PxF32* f); + +// BoolV +PX_FORCE_INLINE void BStoreA(const BoolV b, PxU32* f); + +// VecU32V +PX_FORCE_INLINE void U4StoreA(const VecU32V uv, PxU32* u); + +// VecI32V +PX_FORCE_INLINE void I4StoreA(const VecI32V iv, PxI32* i); + +////////////////////////////////////////////////////////////////// +// Test that simd types have elements in the floating point range +////////////////////////////////////////////////////////////////// + +// check for each component is valid ie in floating point range +PX_FORCE_INLINE bool isFiniteFloatV(const FloatV a); +// check for each component is valid ie in floating point range +PX_FORCE_INLINE bool isFiniteVec3V(const Vec3V a); +// check for each component is valid ie in floating point range +PX_FORCE_INLINE bool isFiniteVec4V(const Vec4V a); + +// Check that w-component is zero. +PX_FORCE_INLINE bool isValidVec3V(const Vec3V a); + +////////////////////////////////////////////////////////////////// +// Tests that all elements of two 16-byte types are completely equivalent. +// Use these tests for unit testing and asserts only. +////////////////////////////////////////////////////////////////// + +namespace vecMathTests +{ +PX_FORCE_INLINE Vec3V getInvalidVec3V(); +PX_FORCE_INLINE bool allElementsEqualFloatV(const FloatV a, const FloatV b); +PX_FORCE_INLINE bool allElementsEqualVec3V(const Vec3V a, const Vec3V b); +PX_FORCE_INLINE bool allElementsEqualVec4V(const Vec4V a, const Vec4V b); +PX_FORCE_INLINE bool allElementsEqualBoolV(const BoolV a, const BoolV b); +PX_FORCE_INLINE bool allElementsEqualVecU32V(const VecU32V a, const VecU32V b); +PX_FORCE_INLINE bool allElementsEqualVecI32V(const VecI32V a, const VecI32V b); + +PX_FORCE_INLINE bool allElementsEqualMat33V(const Mat33V& a, const Mat33V& b) +{ + return (allElementsEqualVec3V(a.col0, b.col0) && allElementsEqualVec3V(a.col1, b.col1) && + allElementsEqualVec3V(a.col2, b.col2)); +} +PX_FORCE_INLINE bool allElementsEqualMat34V(const Mat34V& a, const Mat34V& b) +{ + return (allElementsEqualVec3V(a.col0, b.col0) && allElementsEqualVec3V(a.col1, b.col1) && + allElementsEqualVec3V(a.col2, b.col2) && allElementsEqualVec3V(a.col3, b.col3)); +} +PX_FORCE_INLINE bool allElementsEqualMat44V(const Mat44V& a, const Mat44V& b) +{ + return (allElementsEqualVec4V(a.col0, b.col0) && allElementsEqualVec4V(a.col1, b.col1) && + allElementsEqualVec4V(a.col2, b.col2) && allElementsEqualVec4V(a.col3, b.col3)); +} + +PX_FORCE_INLINE bool allElementsNearEqualFloatV(const FloatV a, const FloatV b); +PX_FORCE_INLINE bool allElementsNearEqualVec3V(const Vec3V a, const Vec3V b); +PX_FORCE_INLINE bool allElementsNearEqualVec4V(const Vec4V a, const Vec4V b); +PX_FORCE_INLINE bool allElementsNearEqualMat33V(const Mat33V& a, const Mat33V& b) +{ + return (allElementsNearEqualVec3V(a.col0, b.col0) && allElementsNearEqualVec3V(a.col1, b.col1) && + allElementsNearEqualVec3V(a.col2, b.col2)); +} +PX_FORCE_INLINE bool allElementsNearEqualMat34V(const Mat34V& a, const Mat34V& b) +{ + return (allElementsNearEqualVec3V(a.col0, b.col0) && allElementsNearEqualVec3V(a.col1, b.col1) && + allElementsNearEqualVec3V(a.col2, b.col2) && allElementsNearEqualVec3V(a.col3, b.col3)); +} +PX_FORCE_INLINE bool allElementsNearEqualMat44V(const Mat44V& a, const Mat44V& b) +{ + return (allElementsNearEqualVec4V(a.col0, b.col0) && allElementsNearEqualVec4V(a.col1, b.col1) && + allElementsNearEqualVec4V(a.col2, b.col2) && allElementsNearEqualVec4V(a.col3, b.col3)); +} +} + +////////////////////////////////////////////////////////////////// +// Math operations on FloatV +////////////////////////////////////////////////////////////////// + +//(0,0,0,0) +PX_FORCE_INLINE FloatV FZero(); +//(1,1,1,1) +PX_FORCE_INLINE FloatV FOne(); +//(0.5,0.5,0.5,0.5) +PX_FORCE_INLINE FloatV FHalf(); +//(PX_EPS_REAL,PX_EPS_REAL,PX_EPS_REAL,PX_EPS_REAL) +PX_FORCE_INLINE FloatV FEps(); +//! @cond +//(PX_MAX_REAL, PX_MAX_REAL, PX_MAX_REAL PX_MAX_REAL) +PX_FORCE_INLINE FloatV FMax(); +//! @endcond +//(-PX_MAX_REAL, -PX_MAX_REAL, -PX_MAX_REAL -PX_MAX_REAL) +PX_FORCE_INLINE FloatV FNegMax(); +//(1e-6f, 1e-6f, 1e-6f, 1e-6f) +PX_FORCE_INLINE FloatV FEps6(); +//((PxF32*)&1, (PxF32*)&1, (PxF32*)&1, (PxF32*)&1) + +//-f (per component) +PX_FORCE_INLINE FloatV FNeg(const FloatV f); +// a+b (per component) +PX_FORCE_INLINE FloatV FAdd(const FloatV a, const FloatV b); +// a-b (per component) +PX_FORCE_INLINE FloatV FSub(const FloatV a, const FloatV b); +// a*b (per component) +PX_FORCE_INLINE FloatV FMul(const FloatV a, const FloatV b); +// a/b (per component) +PX_FORCE_INLINE FloatV FDiv(const FloatV a, const FloatV b); +// a/b (per component) +PX_FORCE_INLINE FloatV FDivFast(const FloatV a, const FloatV b); +// 1.0f/a +PX_FORCE_INLINE FloatV FRecip(const FloatV a); +// 1.0f/a +PX_FORCE_INLINE FloatV FRecipFast(const FloatV a); +// 1.0f/sqrt(a) +PX_FORCE_INLINE FloatV FRsqrt(const FloatV a); +// 1.0f/sqrt(a) +PX_FORCE_INLINE FloatV FRsqrtFast(const FloatV a); +// sqrt(a) +PX_FORCE_INLINE FloatV FSqrt(const FloatV a); +// a*b+c +PX_FORCE_INLINE FloatV FScaleAdd(const FloatV a, const FloatV b, const FloatV c); +// c-a*b +PX_FORCE_INLINE FloatV FNegScaleSub(const FloatV a, const FloatV b, const FloatV c); +// fabs(a) +PX_FORCE_INLINE FloatV FAbs(const FloatV a); +// c ? a : b (per component) +PX_FORCE_INLINE FloatV FSel(const BoolV c, const FloatV a, const FloatV b); +// a>b (per component) +PX_FORCE_INLINE BoolV FIsGrtr(const FloatV a, const FloatV b); +// a>=b (per component) +PX_FORCE_INLINE BoolV FIsGrtrOrEq(const FloatV a, const FloatV b); +// a==b (per component) +PX_FORCE_INLINE BoolV FIsEq(const FloatV a, const FloatV b); +// Max(a,b) (per component) +PX_FORCE_INLINE FloatV FMax(const FloatV a, const FloatV b); +// Min(a,b) (per component) +PX_FORCE_INLINE FloatV FMin(const FloatV a, const FloatV b); +// Clamp(a,b) (per component) +PX_FORCE_INLINE FloatV FClamp(const FloatV a, const FloatV minV, const FloatV maxV); + +// a.x>b.x +PX_FORCE_INLINE PxU32 FAllGrtr(const FloatV a, const FloatV b); +// a.x>=b.x +PX_FORCE_INLINE PxU32 FAllGrtrOrEq(const FloatV a, const FloatV b); +// a.x==b.x +PX_FORCE_INLINE PxU32 FAllEq(const FloatV a, const FloatV b); +// amax +PX_FORCE_INLINE PxU32 FOutOfBounds(const FloatV a, const FloatV min, const FloatV max); +// a>=min && a<=max +PX_FORCE_INLINE PxU32 FInBounds(const FloatV a, const FloatV min, const FloatV max); +// a<-bounds || a>bounds +PX_FORCE_INLINE PxU32 FOutOfBounds(const FloatV a, const FloatV bounds); +// a>=-bounds && a<=bounds +PX_FORCE_INLINE PxU32 FInBounds(const FloatV a, const FloatV bounds); + +// round float a to the near int +PX_FORCE_INLINE FloatV FRound(const FloatV a); +// calculate the sin of float a +PX_FORCE_INLINE FloatV FSin(const FloatV a); +// calculate the cos of float b +PX_FORCE_INLINE FloatV FCos(const FloatV a); + +////////////////////////////////////////////////////////////////// +// Math operations on Vec3V +////////////////////////////////////////////////////////////////// + +//(f,f,f,f) +PX_FORCE_INLINE Vec3V V3Splat(const FloatV f); + +//(x,y,z) +PX_FORCE_INLINE Vec3V V3Merge(const FloatVArg x, const FloatVArg y, const FloatVArg z); + +//(1,0,0,0) +PX_FORCE_INLINE Vec3V V3UnitX(); +//(0,1,0,0) +PX_FORCE_INLINE Vec3V V3UnitY(); +//(0,0,1,0) +PX_FORCE_INLINE Vec3V V3UnitZ(); + +//(f.x,f.x,f.x,f.x) +PX_FORCE_INLINE FloatV V3GetX(const Vec3V f); +//(f.y,f.y,f.y,f.y) +PX_FORCE_INLINE FloatV V3GetY(const Vec3V f); +//(f.z,f.z,f.z,f.z) +PX_FORCE_INLINE FloatV V3GetZ(const Vec3V f); + +//(f,v.y,v.z,v.w) +PX_FORCE_INLINE Vec3V V3SetX(const Vec3V v, const FloatV f); +//(v.x,f,v.z,v.w) +PX_FORCE_INLINE Vec3V V3SetY(const Vec3V v, const FloatV f); +//(v.x,v.y,f,v.w) +PX_FORCE_INLINE Vec3V V3SetZ(const Vec3V v, const FloatV f); + +// v.x=f +PX_FORCE_INLINE void V3WriteX(Vec3V& v, const PxF32 f); +// v.y=f +PX_FORCE_INLINE void V3WriteY(Vec3V& v, const PxF32 f); +// v.z=f +PX_FORCE_INLINE void V3WriteZ(Vec3V& v, const PxF32 f); +// v.x=f.x, v.y=f.y, v.z=f.z +PX_FORCE_INLINE void V3WriteXYZ(Vec3V& v, const PxVec3& f); +// return v.x +PX_FORCE_INLINE PxF32 V3ReadX(const Vec3V& v); +// return v.y +PX_FORCE_INLINE PxF32 V3ReadY(const Vec3V& v); +// return v.y +PX_FORCE_INLINE PxF32 V3ReadZ(const Vec3V& v); +// return (v.x,v.y,v.z) +PX_FORCE_INLINE const PxVec3& V3ReadXYZ(const Vec3V& v); + +//(a.x, b.x, c.x) +PX_FORCE_INLINE Vec3V V3ColX(const Vec3V a, const Vec3V b, const Vec3V c); +//(a.y, b.y, c.y) +PX_FORCE_INLINE Vec3V V3ColY(const Vec3V a, const Vec3V b, const Vec3V c); +//(a.z, b.z, c.z) +PX_FORCE_INLINE Vec3V V3ColZ(const Vec3V a, const Vec3V b, const Vec3V c); + +//(0,0,0,0) +PX_FORCE_INLINE Vec3V V3Zero(); +//(1,1,1,1) +PX_FORCE_INLINE Vec3V V3One(); +//(PX_EPS_REAL,PX_EPS_REAL,PX_EPS_REAL,PX_EPS_REAL) +PX_FORCE_INLINE Vec3V V3Eps(); +//-c (per component) +PX_FORCE_INLINE Vec3V V3Neg(const Vec3V c); +// a+b (per component) +PX_FORCE_INLINE Vec3V V3Add(const Vec3V a, const Vec3V b); +// a-b (per component) +PX_FORCE_INLINE Vec3V V3Sub(const Vec3V a, const Vec3V b); +// a*b (per component) +PX_FORCE_INLINE Vec3V V3Scale(const Vec3V a, const FloatV b); +// a*b (per component) +PX_FORCE_INLINE Vec3V V3Mul(const Vec3V a, const Vec3V b); +// a/b (per component) +PX_FORCE_INLINE Vec3V V3ScaleInv(const Vec3V a, const FloatV b); +// a/b (per component) +PX_FORCE_INLINE Vec3V V3Div(const Vec3V a, const Vec3V b); +// a/b (per component) +PX_FORCE_INLINE Vec3V V3ScaleInvFast(const Vec3V a, const FloatV b); +// a/b (per component) +PX_FORCE_INLINE Vec3V V3DivFast(const Vec3V a, const Vec3V b); +// 1.0f/a +PX_FORCE_INLINE Vec3V V3Recip(const Vec3V a); +// 1.0f/a +PX_FORCE_INLINE Vec3V V3RecipFast(const Vec3V a); +// 1.0f/sqrt(a) +PX_FORCE_INLINE Vec3V V3Rsqrt(const Vec3V a); +// 1.0f/sqrt(a) +PX_FORCE_INLINE Vec3V V3RsqrtFast(const Vec3V a); +// a*b+c +PX_FORCE_INLINE Vec3V V3ScaleAdd(const Vec3V a, const FloatV b, const Vec3V c); +// c-a*b +PX_FORCE_INLINE Vec3V V3NegScaleSub(const Vec3V a, const FloatV b, const Vec3V c); +// a*b+c +PX_FORCE_INLINE Vec3V V3MulAdd(const Vec3V a, const Vec3V b, const Vec3V c); +// c-a*b +PX_FORCE_INLINE Vec3V V3NegMulSub(const Vec3V a, const Vec3V b, const Vec3V c); +// fabs(a) +PX_FORCE_INLINE Vec3V V3Abs(const Vec3V a); + +// a.b +// Note: a.w and b.w must have value zero +PX_FORCE_INLINE FloatV V3Dot(const Vec3V a, const Vec3V b); +// aXb +// Note: a.w and b.w must have value zero +PX_FORCE_INLINE Vec3V V3Cross(const Vec3V a, const Vec3V b); +// |a.a|^1/2 +// Note: a.w must have value zero +PX_FORCE_INLINE FloatV V3Length(const Vec3V a); +// a.a +// Note: a.w must have value zero +PX_FORCE_INLINE FloatV V3LengthSq(const Vec3V a); +// a*|a.a|^-1/2 +// Note: a.w must have value zero +PX_FORCE_INLINE Vec3V V3Normalize(const Vec3V a); +// a.a>0 ? a*|a.a|^-1/2 : (0,0,0,0) +// Note: a.w must have value zero +PX_FORCE_INLINE FloatV V3Length(const Vec3V a); +// a.a>0 ? a*|a.a|^-1/2 : unsafeReturnValue +// Note: a.w must have value zero +PX_FORCE_INLINE Vec3V V3NormalizeSafe(const Vec3V a, const Vec3V unsafeReturnValue); +// a.x + a.y + a.z +// Note: a.w must have value zero +PX_FORCE_INLINE FloatV V3SumElems(const Vec3V a); + +// c ? a : b (per component) +PX_FORCE_INLINE Vec3V V3Sel(const BoolV c, const Vec3V a, const Vec3V b); +// a>b (per component) +PX_FORCE_INLINE BoolV V3IsGrtr(const Vec3V a, const Vec3V b); +// a>=b (per component) +PX_FORCE_INLINE BoolV V3IsGrtrOrEq(const Vec3V a, const Vec3V b); +// a==b (per component) +PX_FORCE_INLINE BoolV V3IsEq(const Vec3V a, const Vec3V b); +// Max(a,b) (per component) +PX_FORCE_INLINE Vec3V V3Max(const Vec3V a, const Vec3V b); +// Min(a,b) (per component) +PX_FORCE_INLINE Vec3V V3Min(const Vec3V a, const Vec3V b); + +// Extract the maximum value from a +// Note: a.w must have value zero +PX_FORCE_INLINE FloatV V3ExtractMax(const Vec3V a); + +// Extract the minimum value from a +// Note: a.w must have value zero +PX_FORCE_INLINE FloatV V3ExtractMin(const Vec3V a); + +// Clamp(a,b) (per component) +PX_FORCE_INLINE Vec3V V3Clamp(const Vec3V a, const Vec3V minV, const Vec3V maxV); + +// Extract the sign for each component +PX_FORCE_INLINE Vec3V V3Sign(const Vec3V a); + +// Test all components. +// (a.x>b.x && a.y>b.y && a.z>b.z) +// Note: a.w and b.w must have value zero +PX_FORCE_INLINE PxU32 V3AllGrtr(const Vec3V a, const Vec3V b); +// (a.x>=b.x && a.y>=b.y && a.z>=b.z) +// Note: a.w and b.w must have value zero +PX_FORCE_INLINE PxU32 V3AllGrtrOrEq(const Vec3V a, const Vec3V b); +// (a.x==b.x && a.y==b.y && a.z==b.z) +// Note: a.w and b.w must have value zero +PX_FORCE_INLINE PxU32 V3AllEq(const Vec3V a, const Vec3V b); +// a.xmax.x || a.y>max.y || a.z>max.z +// Note: a.w and min.w and max.w must have value zero +PX_FORCE_INLINE PxU32 V3OutOfBounds(const Vec3V a, const Vec3V min, const Vec3V max); +// a.x>=min.x && a.y>=min.y && a.z>=min.z && a.x<=max.x && a.y<=max.y && a.z<=max.z +// Note: a.w and min.w and max.w must have value zero +PX_FORCE_INLINE PxU32 V3InBounds(const Vec3V a, const Vec3V min, const Vec3V max); +// a.x<-bounds.x || a.y<=-bounds.y || a.zbounds.x || a.y>bounds.y || a.z>bounds.z +// Note: a.w and bounds.w must have value zero +PX_FORCE_INLINE PxU32 V3OutOfBounds(const Vec3V a, const Vec3V bounds); +// a.x>=-bounds.x && a.y>=-bounds.y && a.z>=-bounds.z && a.x<=bounds.x && a.y<=bounds.y && a.z<=bounds.z +// Note: a.w and bounds.w must have value zero +PX_FORCE_INLINE PxU32 V3InBounds(const Vec3V a, const Vec3V bounds); + +//(floor(a.x + 0.5f), floor(a.y + 0.5f), floor(a.z + 0.5f)) +PX_FORCE_INLINE Vec3V V3Round(const Vec3V a); + +//(sinf(a.x), sinf(a.y), sinf(a.z)) +PX_FORCE_INLINE Vec3V V3Sin(const Vec3V a); +//(cosf(a.x), cosf(a.y), cosf(a.z)) +PX_FORCE_INLINE Vec3V V3Cos(const Vec3V a); + +//(a.y,a.z,a.z) +PX_FORCE_INLINE Vec3V V3PermYZZ(const Vec3V a); +//(a.x,a.y,a.x) +PX_FORCE_INLINE Vec3V V3PermXYX(const Vec3V a); +//(a.y,a.z,a.x) +PX_FORCE_INLINE Vec3V V3PermYZX(const Vec3V a); +//(a.z, a.x, a.y) +PX_FORCE_INLINE Vec3V V3PermZXY(const Vec3V a); +//(a.z,a.z,a.y) +PX_FORCE_INLINE Vec3V V3PermZZY(const Vec3V a); +//(a.y,a.x,a.x) +PX_FORCE_INLINE Vec3V V3PermYXX(const Vec3V a); +//(0, v1.z, v0.y) +PX_FORCE_INLINE Vec3V V3Perm_Zero_1Z_0Y(const Vec3V v0, const Vec3V v1); +//(v0.z, 0, v1.x) +PX_FORCE_INLINE Vec3V V3Perm_0Z_Zero_1X(const Vec3V v0, const Vec3V v1); +//(v1.y, v0.x, 0) +PX_FORCE_INLINE Vec3V V3Perm_1Y_0X_Zero(const Vec3V v0, const Vec3V v1); + +// Transpose 3 Vec3Vs inplace. Sets the w component to zero +// [ x0, y0, z0, w0] [ x1, y1, z1, w1] [ x2, y2, z2, w2] -> [x0 x1 x2 0] [y0 y1 y2 0] [z0 z1 z2 0] +PX_FORCE_INLINE void V3Transpose(Vec3V& col0, Vec3V& col1, Vec3V& col2); + +////////////////////////////////////////////////////////////////// +// Math operations on Vec4V +////////////////////////////////////////////////////////////////// + +//(f,f,f,f) +PX_FORCE_INLINE Vec4V V4Splat(const FloatV f); + +//(f[0],f[1],f[2],f[3]) +PX_FORCE_INLINE Vec4V V4Merge(const FloatV* const f); +//(x,y,z,w) +PX_FORCE_INLINE Vec4V V4Merge(const FloatVArg x, const FloatVArg y, const FloatVArg z, const FloatVArg w); +//(x.w, y.w, z.w, w.w) +PX_FORCE_INLINE Vec4V V4MergeW(const Vec4VArg x, const Vec4VArg y, const Vec4VArg z, const Vec4VArg w); +//(x.z, y.z, z.z, w.z) +PX_FORCE_INLINE Vec4V V4MergeZ(const Vec4VArg x, const Vec4VArg y, const Vec4VArg z, const Vec4VArg w); +//(x.y, y.y, z.y, w.y) +PX_FORCE_INLINE Vec4V V4MergeY(const Vec4VArg x, const Vec4VArg y, const Vec4VArg z, const Vec4VArg w); +//(x.x, y.x, z.x, w.x) +PX_FORCE_INLINE Vec4V V4MergeX(const Vec4VArg x, const Vec4VArg y, const Vec4VArg z, const Vec4VArg w); + +//(a.x, b.x, a.y, b.y) +PX_FORCE_INLINE Vec4V V4UnpackXY(const Vec4VArg a, const Vec4VArg b); +//(a.z, b.z, a.w, b.w) +PX_FORCE_INLINE Vec4V V4UnpackZW(const Vec4VArg a, const Vec4VArg b); + +//(1,0,0,0) +PX_FORCE_INLINE Vec4V V4UnitW(); +//(0,1,0,0) +PX_FORCE_INLINE Vec4V V4UnitY(); +//(0,0,1,0) +PX_FORCE_INLINE Vec4V V4UnitZ(); +//(0,0,0,1) +PX_FORCE_INLINE Vec4V V4UnitW(); + +//(f.x,f.x,f.x,f.x) +PX_FORCE_INLINE FloatV V4GetX(const Vec4V f); +//(f.y,f.y,f.y,f.y) +PX_FORCE_INLINE FloatV V4GetY(const Vec4V f); +//(f.z,f.z,f.z,f.z) +PX_FORCE_INLINE FloatV V4GetZ(const Vec4V f); +//(f.w,f.w,f.w,f.w) +PX_FORCE_INLINE FloatV V4GetW(const Vec4V f); + +//(f,v.y,v.z,v.w) +PX_FORCE_INLINE Vec4V V4SetX(const Vec4V v, const FloatV f); +//(v.x,f,v.z,v.w) +PX_FORCE_INLINE Vec4V V4SetY(const Vec4V v, const FloatV f); +//(v.x,v.y,f,v.w) +PX_FORCE_INLINE Vec4V V4SetZ(const Vec4V v, const FloatV f); +//(v.x,v.y,v.z,f) +PX_FORCE_INLINE Vec4V V4SetW(const Vec4V v, const FloatV f); + +//(v.x,v.y,v.z,0) +PX_FORCE_INLINE Vec4V V4ClearW(const Vec4V v); + +//(a[elementIndex], a[elementIndex], a[elementIndex], a[elementIndex]) +template +PX_FORCE_INLINE Vec4V V4SplatElement(Vec4V a); + +// v.x=f +PX_FORCE_INLINE void V4WriteX(Vec4V& v, const PxF32 f); +// v.y=f +PX_FORCE_INLINE void V4WriteY(Vec4V& v, const PxF32 f); +// v.z=f +PX_FORCE_INLINE void V4WriteZ(Vec4V& v, const PxF32 f); +// v.w=f +PX_FORCE_INLINE void V4WriteW(Vec4V& v, const PxF32 f); +// v.x=f.x, v.y=f.y, v.z=f.z +PX_FORCE_INLINE void V4WriteXYZ(Vec4V& v, const PxVec3& f); +// return v.x +PX_FORCE_INLINE PxF32 V4ReadX(const Vec4V& v); +// return v.y +PX_FORCE_INLINE PxF32 V4ReadY(const Vec4V& v); +// return v.z +PX_FORCE_INLINE PxF32 V4ReadZ(const Vec4V& v); +// return v.w +PX_FORCE_INLINE PxF32 V4ReadW(const Vec4V& v); +// return (v.x,v.y,v.z) +PX_FORCE_INLINE const PxVec3& V4ReadXYZ(const Vec4V& v); + +//(0,0,0,0) +PX_FORCE_INLINE Vec4V V4Zero(); +//(1,1,1,1) +PX_FORCE_INLINE Vec4V V4One(); +//(PX_EPS_REAL,PX_EPS_REAL,PX_EPS_REAL,PX_EPS_REAL) +PX_FORCE_INLINE Vec4V V4Eps(); + +//-c (per component) +PX_FORCE_INLINE Vec4V V4Neg(const Vec4V c); +// a+b (per component) +PX_FORCE_INLINE Vec4V V4Add(const Vec4V a, const Vec4V b); +// a-b (per component) +PX_FORCE_INLINE Vec4V V4Sub(const Vec4V a, const Vec4V b); +// a*b (per component) +PX_FORCE_INLINE Vec4V V4Scale(const Vec4V a, const FloatV b); +// a*b (per component) +PX_FORCE_INLINE Vec4V V4Mul(const Vec4V a, const Vec4V b); +// a/b (per component) +PX_FORCE_INLINE Vec4V V4ScaleInv(const Vec4V a, const FloatV b); +// a/b (per component) +PX_FORCE_INLINE Vec4V V4Div(const Vec4V a, const Vec4V b); +// a/b (per component) +PX_FORCE_INLINE Vec4V V4ScaleInvFast(const Vec4V a, const FloatV b); +// a/b (per component) +PX_FORCE_INLINE Vec4V V4DivFast(const Vec4V a, const Vec4V b); +// 1.0f/a +PX_FORCE_INLINE Vec4V V4Recip(const Vec4V a); +// 1.0f/a +PX_FORCE_INLINE Vec4V V4RecipFast(const Vec4V a); +// 1.0f/sqrt(a) +PX_FORCE_INLINE Vec4V V4Rsqrt(const Vec4V a); +// 1.0f/sqrt(a) +PX_FORCE_INLINE Vec4V V4RsqrtFast(const Vec4V a); +// a*b+c +PX_FORCE_INLINE Vec4V V4ScaleAdd(const Vec4V a, const FloatV b, const Vec4V c); +// c-a*b +PX_FORCE_INLINE Vec4V V4NegScaleSub(const Vec4V a, const FloatV b, const Vec4V c); +// a*b+c +PX_FORCE_INLINE Vec4V V4MulAdd(const Vec4V a, const Vec4V b, const Vec4V c); +// c-a*b +PX_FORCE_INLINE Vec4V V4NegMulSub(const Vec4V a, const Vec4V b, const Vec4V c); + +// fabs(a) +PX_FORCE_INLINE Vec4V V4Abs(const Vec4V a); +// bitwise a & ~b +PX_FORCE_INLINE Vec4V V4Andc(const Vec4V a, const VecU32V b); + +// a.b (W is taken into account) +PX_FORCE_INLINE FloatV V4Dot(const Vec4V a, const Vec4V b); +// a.b (same computation as V3Dot. W is ignored in input) +PX_FORCE_INLINE FloatV V4Dot3(const Vec4V a, const Vec4V b); +// aXb (same computation as V3Cross. W is ignored in input and undefined in output) +PX_FORCE_INLINE Vec4V V4Cross(const Vec4V a, const Vec4V b); + +//|a.a|^1/2 +PX_FORCE_INLINE FloatV V4Length(const Vec4V a); +// a.a +PX_FORCE_INLINE FloatV V4LengthSq(const Vec4V a); + +// a*|a.a|^-1/2 +PX_FORCE_INLINE Vec4V V4Normalize(const Vec4V a); +// a.a>0 ? a*|a.a|^-1/2 : unsafeReturnValue +PX_FORCE_INLINE Vec4V V4NormalizeSafe(const Vec4V a, const Vec4V unsafeReturnValue); +// a*|a.a|^-1/2 +PX_FORCE_INLINE Vec4V V4NormalizeFast(const Vec4V a); + +// c ? a : b (per component) +PX_FORCE_INLINE Vec4V V4Sel(const BoolV c, const Vec4V a, const Vec4V b); +// a>b (per component) +PX_FORCE_INLINE BoolV V4IsGrtr(const Vec4V a, const Vec4V b); +// a>=b (per component) +PX_FORCE_INLINE BoolV V4IsGrtrOrEq(const Vec4V a, const Vec4V b); +// a==b (per component) +PX_FORCE_INLINE BoolV V4IsEq(const Vec4V a, const Vec4V b); +// Max(a,b) (per component) +PX_FORCE_INLINE Vec4V V4Max(const Vec4V a, const Vec4V b); +// Min(a,b) (per component) +PX_FORCE_INLINE Vec4V V4Min(const Vec4V a, const Vec4V b); +// Get the maximum component from a +PX_FORCE_INLINE FloatV V4ExtractMax(const Vec4V a); +// Get the minimum component from a +PX_FORCE_INLINE FloatV V4ExtractMin(const Vec4V a); + +// Clamp(a,b) (per component) +PX_FORCE_INLINE Vec4V V4Clamp(const Vec4V a, const Vec4V minV, const Vec4V maxV); + +// return 1 if all components of a are greater than all components of b. +PX_FORCE_INLINE PxU32 V4AllGrtr(const Vec4V a, const Vec4V b); +// return 1 if all components of a are greater than or equal to all components of b +PX_FORCE_INLINE PxU32 V4AllGrtrOrEq(const Vec4V a, const Vec4V b); +// return 1 if XYZ components of a are greater than or equal to XYZ components of b. W is ignored. +PX_FORCE_INLINE PxU32 V4AllGrtrOrEq3(const Vec4V a, const Vec4V b); +// return 1 if all components of a are equal to all components of b +PX_FORCE_INLINE PxU32 V4AllEq(const Vec4V a, const Vec4V b); +// return 1 if any XYZ component of a is greater than the corresponding component of b. W is ignored. +PX_FORCE_INLINE PxU32 V4AnyGrtr3(const Vec4V a, const Vec4V b); + +// round(a)(per component) +PX_FORCE_INLINE Vec4V V4Round(const Vec4V a); +// sin(a) (per component) +PX_FORCE_INLINE Vec4V V4Sin(const Vec4V a); +// cos(a) (per component) +PX_FORCE_INLINE Vec4V V4Cos(const Vec4V a); + +// Permute v into a new vec4v with YXWZ format +PX_FORCE_INLINE Vec4V V4PermYXWZ(const Vec4V v); +// Permute v into a new vec4v with XZXZ format +PX_FORCE_INLINE Vec4V V4PermXZXZ(const Vec4V v); +// Permute v into a new vec4v with YWYW format +PX_FORCE_INLINE Vec4V V4PermYWYW(const Vec4V v); +// Permute v into a new vec4v with YZXW format +PX_FORCE_INLINE Vec4V V4PermYZXW(const Vec4V v); +// Permute v into a new vec4v with ZWXY format - equivalent to a swap of the two 64bit parts of the vector +PX_FORCE_INLINE Vec4V V4PermZWXY(const Vec4V a); + +// Permute v into a new vec4v with format {a[x], a[y], a[z], a[w]} +// V4Perm<1,3,1,3> is equal to V4PermYWYW +// V4Perm<0,2,0,2> is equal to V4PermXZXZ +// V3Perm<1,0,3,2> is equal to V4PermYXWZ +template +PX_FORCE_INLINE Vec4V V4Perm(const Vec4V a); + +// Transpose 4 Vec4Vs inplace. +// [ x0, y0, z0, w0] [ x1, y1, z1, w1] [ x2, y2, z2, w2] [ x3, y3, z3, w3] -> +// [ x0, x1, x2, x3] [ y0, y1, y2, y3] [ z0, z1, z2, z3] [ w0, w1, w2, w3] +PX_FORCE_INLINE void V3Transpose(Vec3V& col0, Vec3V& col1, Vec3V& col2); + +// q = cos(a/2) + u*sin(a/2) +PX_FORCE_INLINE QuatV QuatV_From_RotationAxisAngle(const Vec3V u, const FloatV a); +// convert q to a unit quaternion +PX_FORCE_INLINE QuatV QuatNormalize(const QuatV q); +//|q.q|^1/2 +PX_FORCE_INLINE FloatV QuatLength(const QuatV q); +// q.q +PX_FORCE_INLINE FloatV QuatLengthSq(const QuatV q); +// a.b +PX_FORCE_INLINE FloatV QuatDot(const QuatV a, const QuatV b); +//(-q.x, -q.y, -q.z, q.w) +PX_FORCE_INLINE QuatV QuatConjugate(const QuatV q); +//(q.x, q.y, q.z) +PX_FORCE_INLINE Vec3V QuatGetImaginaryPart(const QuatV q); +// convert quaternion to matrix 33 +PX_FORCE_INLINE Mat33V QuatGetMat33V(const QuatVArg q); +// convert quaternion to matrix 33 +PX_FORCE_INLINE void QuatGetMat33V(const QuatVArg q, Vec3V& column0, Vec3V& column1, Vec3V& column2); +// convert matrix 33 to quaternion +PX_FORCE_INLINE QuatV Mat33GetQuatV(const Mat33V& a); +// brief computes rotation of x-axis +PX_FORCE_INLINE Vec3V QuatGetBasisVector0(const QuatV q); +// brief computes rotation of y-axis +PX_FORCE_INLINE Vec3V QuatGetBasisVector1(const QuatV q); +// brief computes rotation of z-axis +PX_FORCE_INLINE Vec3V QuatGetBasisVector2(const QuatV q); +// calculate the rotation vector from q and v +PX_FORCE_INLINE Vec3V QuatRotate(const QuatV q, const Vec3V v); +// calculate the rotation vector from the conjugate quaternion and v +PX_FORCE_INLINE Vec3V QuatRotateInv(const QuatV q, const Vec3V v); +// quaternion multiplication +PX_FORCE_INLINE QuatV QuatMul(const QuatV a, const QuatV b); +// quaternion add +PX_FORCE_INLINE QuatV QuatAdd(const QuatV a, const QuatV b); +// (-q.x, -q.y, -q.z, -q.w) +PX_FORCE_INLINE QuatV QuatNeg(const QuatV q); +// (a.x - b.x, a.y-b.y, a.z-b.z, a.w-b.w ) +PX_FORCE_INLINE QuatV QuatSub(const QuatV a, const QuatV b); +// (a.x*b, a.y*b, a.z*b, a.w*b) +PX_FORCE_INLINE QuatV QuatScale(const QuatV a, const FloatV b); +// (x = v[0], y = v[1], z = v[2], w =v[3]) +PX_FORCE_INLINE QuatV QuatMerge(const FloatV* const v); +// (x = v[0], y = v[1], z = v[2], w =v[3]) +PX_FORCE_INLINE QuatV QuatMerge(const FloatVArg x, const FloatVArg y, const FloatVArg z, const FloatVArg w); +// (x = 0.f, y = 0.f, z = 0.f, w = 1.f) +PX_FORCE_INLINE QuatV QuatIdentity(); +// check for each component is valid +PX_FORCE_INLINE bool isFiniteQuatV(const QuatV q); +// check for each component is valid +PX_FORCE_INLINE bool isValidQuatV(const QuatV q); +// check for each component is valid +PX_FORCE_INLINE bool isSaneQuatV(const QuatV q); + +// Math operations on 16-byte aligned booleans. +// x=false y=false z=false w=false +PX_FORCE_INLINE BoolV BFFFF(); +// x=false y=false z=false w=true +PX_FORCE_INLINE BoolV BFFFT(); +// x=false y=false z=true w=false +PX_FORCE_INLINE BoolV BFFTF(); +// x=false y=false z=true w=true +PX_FORCE_INLINE BoolV BFFTT(); +// x=false y=true z=false w=false +PX_FORCE_INLINE BoolV BFTFF(); +// x=false y=true z=false w=true +PX_FORCE_INLINE BoolV BFTFT(); +// x=false y=true z=true w=false +PX_FORCE_INLINE BoolV BFTTF(); +// x=false y=true z=true w=true +PX_FORCE_INLINE BoolV BFTTT(); +// x=true y=false z=false w=false +PX_FORCE_INLINE BoolV BTFFF(); +// x=true y=false z=false w=true +PX_FORCE_INLINE BoolV BTFFT(); +// x=true y=false z=true w=false +PX_FORCE_INLINE BoolV BTFTF(); +// x=true y=false z=true w=true +PX_FORCE_INLINE BoolV BTFTT(); +// x=true y=true z=false w=false +PX_FORCE_INLINE BoolV BTTFF(); +// x=true y=true z=false w=true +PX_FORCE_INLINE BoolV BTTFT(); +// x=true y=true z=true w=false +PX_FORCE_INLINE BoolV BTTTF(); +// x=true y=true z=true w=true +PX_FORCE_INLINE BoolV BTTTT(); + +// x=false y=false z=false w=true +PX_FORCE_INLINE BoolV BWMask(); +// x=true y=false z=false w=false +PX_FORCE_INLINE BoolV BXMask(); +// x=false y=true z=false w=false +PX_FORCE_INLINE BoolV BYMask(); +// x=false y=false z=true w=false +PX_FORCE_INLINE BoolV BZMask(); + +// get x component +PX_FORCE_INLINE BoolV BGetX(const BoolV f); +// get y component +PX_FORCE_INLINE BoolV BGetY(const BoolV f); +// get z component +PX_FORCE_INLINE BoolV BGetZ(const BoolV f); +// get w component +PX_FORCE_INLINE BoolV BGetW(const BoolV f); + +// Use elementIndex to splat xxxx or yyyy or zzzz or wwww +template +PX_FORCE_INLINE BoolV BSplatElement(Vec4V a); + +// component-wise && (AND) +PX_FORCE_INLINE BoolV BAnd(const BoolV a, const BoolV b); +// component-wise || (OR) +PX_FORCE_INLINE BoolV BOr(const BoolV a, const BoolV b); +// component-wise not +PX_FORCE_INLINE BoolV BNot(const BoolV a); + +// if all four components are true, return true, otherwise return false +PX_FORCE_INLINE BoolV BAllTrue4(const BoolV a); + +// if any four components is true, return true, otherwise return false +PX_FORCE_INLINE BoolV BAnyTrue4(const BoolV a); + +// if all three(0, 1, 2) components are true, return true, otherwise return false +PX_FORCE_INLINE BoolV BAllTrue3(const BoolV a); + +// if any three (0, 1, 2) components is true, return true, otherwise return false +PX_FORCE_INLINE BoolV BAnyTrue3(const BoolV a); + +// Return 1 if all components equal, zero otherwise. +PX_FORCE_INLINE PxU32 BAllEq(const BoolV a, const BoolV b); + +// Specialized/faster BAllEq function for b==TTTT +PX_FORCE_INLINE PxU32 BAllEqTTTT(const BoolV a); +// Specialized/faster BAllEq function for b==FFFF +PX_FORCE_INLINE PxU32 BAllEqFFFF(const BoolV a); + +/// Get BoolV as bits set in an PxU32. A bit in the output is set if the element is 'true' in the input. +/// There is a bit for each element in a, with element 0s value held in bit0, element 1 in bit 1s and so forth. +/// If nothing is true in the input it will return 0, and if all are true if will return 0xf. +/// NOTE! That performance of the function varies considerably by platform, thus it is recommended to use +/// where your algorithm really needs a BoolV in an integer variable. +PX_FORCE_INLINE PxU32 BGetBitMask(const BoolV a); + +// VecI32V stuff + +PX_FORCE_INLINE VecI32V VecI32V_Zero(); + +PX_FORCE_INLINE VecI32V VecI32V_One(); + +PX_FORCE_INLINE VecI32V VecI32V_Two(); + +PX_FORCE_INLINE VecI32V VecI32V_MinusOne(); + +// Compute a shift parameter for VecI32V_LeftShift and VecI32V_RightShift +// Each element of shift must be identical ie the vector must have form {count, count, count, count} with count>=0 +PX_FORCE_INLINE VecShiftV VecI32V_PrepareShift(const VecI32VArg shift); + +// Shift each element of a leftwards by the same amount +// Compute shift with VecI32V_PrepareShift +//{a.x<>shift[0], a.y>>shift[0], a.z>>shift[0], a.w>>shift[0]} +PX_FORCE_INLINE VecI32V VecI32V_RightShift(const VecI32VArg a, const VecShiftVArg shift); + +PX_FORCE_INLINE VecI32V VecI32V_Add(const VecI32VArg a, const VecI32VArg b); + +PX_FORCE_INLINE VecI32V VecI32V_Or(const VecI32VArg a, const VecI32VArg b); + +PX_FORCE_INLINE VecI32V VecI32V_GetX(const VecI32VArg a); + +PX_FORCE_INLINE VecI32V VecI32V_GetY(const VecI32VArg a); + +PX_FORCE_INLINE VecI32V VecI32V_GetZ(const VecI32VArg a); + +PX_FORCE_INLINE VecI32V VecI32V_GetW(const VecI32VArg a); + +PX_FORCE_INLINE VecI32V VecI32V_Sub(const VecI32VArg a, const VecI32VArg b); + +PX_FORCE_INLINE BoolV VecI32V_IsGrtr(const VecI32VArg a, const VecI32VArg b); + +PX_FORCE_INLINE BoolV VecI32V_IsEq(const VecI32VArg a, const VecI32VArg b); + +PX_FORCE_INLINE VecI32V V4I32Sel(const BoolV c, const VecI32V a, const VecI32V b); + +// VecU32V stuff + +PX_FORCE_INLINE VecU32V U4Zero(); + +PX_FORCE_INLINE VecU32V U4One(); + +PX_FORCE_INLINE VecU32V U4Two(); + +PX_FORCE_INLINE BoolV V4IsEqU32(const VecU32V a, const VecU32V b); + +PX_FORCE_INLINE VecU32V V4U32Sel(const BoolV c, const VecU32V a, const VecU32V b); + +PX_FORCE_INLINE VecU32V V4U32or(VecU32V a, VecU32V b); + +PX_FORCE_INLINE VecU32V V4U32xor(VecU32V a, VecU32V b); + +PX_FORCE_INLINE VecU32V V4U32and(VecU32V a, VecU32V b); + +PX_FORCE_INLINE VecU32V V4U32Andc(VecU32V a, VecU32V b); + +// VecU32 - why does this not return a bool? +PX_FORCE_INLINE VecU32V V4IsGrtrV32u(const Vec4V a, const Vec4V b); + +// Math operations on 16-byte aligned Mat33s (represents any 3x3 matrix) +PX_FORCE_INLINE Mat33V M33Load(const PxMat33& m) +{ + return Mat33V(Vec3V_From_Vec4V(V4LoadU(&m.column0.x)), + Vec3V_From_Vec4V(V4LoadU(&m.column1.x)), V3LoadU(m.column2)); +} +// a*b +PX_FORCE_INLINE Vec3V M33MulV3(const Mat33V& a, const Vec3V b); +// A*x + b +PX_FORCE_INLINE Vec3V M33MulV3AddV3(const Mat33V& A, const Vec3V b, const Vec3V c); +// transpose(a) * b +PX_FORCE_INLINE Vec3V M33TrnspsMulV3(const Mat33V& a, const Vec3V b); +// a*b +PX_FORCE_INLINE Mat33V M33MulM33(const Mat33V& a, const Mat33V& b); +// a+b +PX_FORCE_INLINE Mat33V M33Add(const Mat33V& a, const Mat33V& b); +// a+b +PX_FORCE_INLINE Mat33V M33Sub(const Mat33V& a, const Mat33V& b); +//-a +PX_FORCE_INLINE Mat33V M33Neg(const Mat33V& a); +// absolute value of the matrix +PX_FORCE_INLINE Mat33V M33Abs(const Mat33V& a); +// inverse mat +PX_FORCE_INLINE Mat33V M33Inverse(const Mat33V& a); +// transpose(a) +PX_FORCE_INLINE Mat33V M33Trnsps(const Mat33V& a); +// create an identity matrix +PX_FORCE_INLINE Mat33V M33Identity(); + +// create a vec3 to store the diagonal element of the M33 +PX_FORCE_INLINE Mat33V M33Diagonal(const Vec3VArg); + +// Not implemented +// return 1 if all components of a are equal to all components of b +// PX_FORCE_INLINE PxU32 V4U32AllEq(const VecU32V a, const VecU32V b); +// v.w=f +// PX_FORCE_INLINE void V3WriteW(Vec3V& v, const PxF32 f); +// PX_FORCE_INLINE PxF32 V3ReadW(const Vec3V& v); + +// Not used +// PX_FORCE_INLINE Vec4V V4LoadAligned(Vec4V* addr); +// PX_FORCE_INLINE Vec4V V4LoadUnaligned(Vec4V* addr); +// floor(a)(per component) +// PX_FORCE_INLINE Vec4V V4Floor(Vec4V a); +// ceil(a) (per component) +// PX_FORCE_INLINE Vec4V V4Ceil(Vec4V a); +// PX_FORCE_INLINE VecU32V V4ConvertToU32VSaturate(const Vec4V a, PxU32 power); + +// Math operations on 16-byte aligned Mat34s (represents transformation matrix - rotation and translation). +// namespace _Mat34V +//{ +// //a*b +// PX_FORCE_INLINE Vec3V multiplyV(const Mat34V& a, const Vec3V b); +// //a_rotation * b +// PX_FORCE_INLINE Vec3V multiply3X3V(const Mat34V& a, const Vec3V b); +// //transpose(a_rotation)*b +// PX_FORCE_INLINE Vec3V multiplyTranspose3X3V(const Mat34V& a, const Vec3V b); +// //a*b +// PX_FORCE_INLINE Mat34V multiplyV(const Mat34V& a, const Mat34V& b); +// //a_rotation*b +// PX_FORCE_INLINE Mat33V multiply3X3V(const Mat34V& a, const Mat33V& b); +// //a_rotation*b_rotation +// PX_FORCE_INLINE Mat33V multiply3X3V(const Mat34V& a, const Mat34V& b); +// //a+b +// PX_FORCE_INLINE Mat34V addV(const Mat34V& a, const Mat34V& b); +// //a^-1 +// PX_FORCE_INLINE Mat34V getInverseV(const Mat34V& a); +// //transpose(a_rotation) +// PX_FORCE_INLINE Mat33V getTranspose3X3(const Mat34V& a); +//}; //namespace _Mat34V + +// a*b +//#define M34MulV3(a,b) (M34MulV3(a,b)) +////a_rotation * b +//#define M34Mul33V3(a,b) (M34Mul33V3(a,b)) +////transpose(a_rotation)*b +//#define M34TrnspsMul33V3(a,b) (M34TrnspsMul33V3(a,b)) +////a*b +//#define M34MulM34(a,b) (_Mat34V::multiplyV(a,b)) +// a_rotation*b +//#define M34MulM33(a,b) (M34MulM33(a,b)) +// a_rotation*b_rotation +//#define M34Mul33MM34(a,b) (M34MulM33(a,b)) +// a+b +//#define M34Add(a,b) (M34Add(a,b)) +////a^-1 +//#define M34Inverse(a,b) (M34Inverse(a)) +// transpose(a_rotation) +//#define M34Trnsps33(a) (M33Trnsps3X3(a)) + +// Math operations on 16-byte aligned Mat44s (represents any 4x4 matrix) +// namespace _Mat44V +//{ +// //a*b +// PX_FORCE_INLINE Vec4V multiplyV(const Mat44V& a, const Vec4V b); +// //transpose(a)*b +// PX_FORCE_INLINE Vec4V multiplyTransposeV(const Mat44V& a, const Vec4V b); +// //a*b +// PX_FORCE_INLINE Mat44V multiplyV(const Mat44V& a, const Mat44V& b); +// //a+b +// PX_FORCE_INLINE Mat44V addV(const Mat44V& a, const Mat44V& b); +// //a&-1 +// PX_FORCE_INLINE Mat44V getInverseV(const Mat44V& a); +// //transpose(a) +// PX_FORCE_INLINE Mat44V getTransposeV(const Mat44V& a); +//}; //namespace _Mat44V + +// namespace _VecU32V +//{ +// // pack 8 U32s to 8 U16s with saturation +// PX_FORCE_INLINE VecU16V pack2U32VToU16VSaturate(VecU32V a, VecU32V b); +// PX_FORCE_INLINE VecU32V orV(VecU32V a, VecU32V b); +// PX_FORCE_INLINE VecU32V andV(VecU32V a, VecU32V b); +// PX_FORCE_INLINE VecU32V andcV(VecU32V a, VecU32V b); +// // conversion from integer to float +// PX_FORCE_INLINE Vec4V convertToVec4V(VecU32V a); +// // splat a[elementIndex] into all fields of a +// template +// PX_FORCE_INLINE VecU32V splatElement(VecU32V a); +// PX_FORCE_INLINE void storeAligned(VecU32V a, VecU32V* address); +//}; + +// namespace _VecI32V +//{ +// template PX_FORCE_INLINE VecI32V splatI32(); +//}; +// +// namespace _VecU16V +//{ +// PX_FORCE_INLINE VecU16V orV(VecU16V a, VecU16V b); +// PX_FORCE_INLINE VecU16V andV(VecU16V a, VecU16V b); +// PX_FORCE_INLINE VecU16V andcV(VecU16V a, VecU16V b); +// PX_FORCE_INLINE void storeAligned(VecU16V val, VecU16V *address); +// PX_FORCE_INLINE VecU16V loadAligned(VecU16V* addr); +// PX_FORCE_INLINE VecU16V loadUnaligned(VecU16V* addr); +// PX_FORCE_INLINE VecU16V compareGt(VecU16V a, VecU16V b); +// template +// PX_FORCE_INLINE VecU16V splatElement(VecU16V a); +// PX_FORCE_INLINE VecU16V subtractModulo(VecU16V a, VecU16V b); +// PX_FORCE_INLINE VecU16V addModulo(VecU16V a, VecU16V b); +// PX_FORCE_INLINE VecU32V getLo16(VecU16V a); // [0,2,4,6] 16-bit values to [0,1,2,3] 32-bit vector +// PX_FORCE_INLINE VecU32V getHi16(VecU16V a); // [1,3,5,7] 16-bit values to [0,1,2,3] 32-bit vector +//}; +// +// namespace _VecI16V +//{ +// template PX_FORCE_INLINE VecI16V splatImmediate(); +//}; +// +// namespace _VecU8V +//{ +//}; + +// a*b +//#define M44MulV4(a,b) (M44MulV4(a,b)) +////transpose(a)*b +//#define M44TrnspsMulV4(a,b) (M44TrnspsMulV4(a,b)) +////a*b +//#define M44MulM44(a,b) (M44MulM44(a,b)) +////a+b +//#define M44Add(a,b) (M44Add(a,b)) +////a&-1 +//#define M44Inverse(a) (M44Inverse(a)) +////transpose(a) +//#define M44Trnsps(a) (M44Trnsps(a)) + +// dsequeira: these used to be assert'd out in SIMD builds, but they're necessary if +// we want to be able to write some scalar functions which run using SIMD data structures + +PX_FORCE_INLINE void V3WriteX(Vec3V& v, const PxF32 f) +{ + reinterpret_cast(v).x = f; +} + +PX_FORCE_INLINE void V3WriteY(Vec3V& v, const PxF32 f) +{ + reinterpret_cast(v).y = f; +} + +PX_FORCE_INLINE void V3WriteZ(Vec3V& v, const PxF32 f) +{ + reinterpret_cast(v).z = f; +} + +PX_FORCE_INLINE void V3WriteXYZ(Vec3V& v, const PxVec3& f) +{ + reinterpret_cast(v) = f; +} + +PX_FORCE_INLINE PxF32 V3ReadX(const Vec3V& v) +{ + return reinterpret_cast(v).x; +} + +PX_FORCE_INLINE PxF32 V3ReadY(const Vec3V& v) +{ + return reinterpret_cast(v).y; +} + +PX_FORCE_INLINE PxF32 V3ReadZ(const Vec3V& v) +{ + return reinterpret_cast(v).z; +} + +PX_FORCE_INLINE const PxVec3& V3ReadXYZ(const Vec3V& v) +{ + return reinterpret_cast(v); +} + +PX_FORCE_INLINE void V4WriteX(Vec4V& v, const PxF32 f) +{ + reinterpret_cast(v).x = f; +} + +PX_FORCE_INLINE void V4WriteY(Vec4V& v, const PxF32 f) +{ + reinterpret_cast(v).y = f; +} + +PX_FORCE_INLINE void V4WriteZ(Vec4V& v, const PxF32 f) +{ + reinterpret_cast(v).z = f; +} + +PX_FORCE_INLINE void V4WriteW(Vec4V& v, const PxF32 f) +{ + reinterpret_cast(v).w = f; +} + +PX_FORCE_INLINE void V4WriteXYZ(Vec4V& v, const PxVec3& f) +{ + reinterpret_cast(v) = f; +} + +PX_FORCE_INLINE PxF32 V4ReadX(const Vec4V& v) +{ + return reinterpret_cast(v).x; +} + +PX_FORCE_INLINE PxF32 V4ReadY(const Vec4V& v) +{ + return reinterpret_cast(v).y; +} + +PX_FORCE_INLINE PxF32 V4ReadZ(const Vec4V& v) +{ + return reinterpret_cast(v).z; +} + +PX_FORCE_INLINE PxF32 V4ReadW(const Vec4V& v) +{ + return reinterpret_cast(v).w; +} + +PX_FORCE_INLINE const PxVec3& V4ReadXYZ(const Vec4V& v) +{ + return reinterpret_cast(v); +} + +// this macro transposes 4 Vec4V into 3 Vec4V (assuming that the W component can be ignored +#define PX_TRANSPOSE_44_34(inA, inB, inC, inD, outA, outB, outC) \ +outA = V4UnpackXY(inA, inC); \ +inA = V4UnpackZW(inA, inC); \ +inC = V4UnpackXY(inB, inD); \ +inB = V4UnpackZW(inB, inD); \ +outB = V4UnpackZW(outA, inC); \ +outA = V4UnpackXY(outA, inC); \ +outC = V4UnpackXY(inA, inB); + +// this macro transposes 3 Vec4V into 4 Vec4V (with W components as garbage!) +#define PX_TRANSPOSE_34_44(inA, inB, inC, outA, outB, outC, outD) \ + outA = V4UnpackXY(inA, inC); \ + inA = V4UnpackZW(inA, inC); \ + outC = V4UnpackXY(inB, inB); \ + inC = V4UnpackZW(inB, inB); \ + outB = V4UnpackZW(outA, outC); \ + outA = V4UnpackXY(outA, outC); \ + outC = V4UnpackXY(inA, inC); \ + outD = V4UnpackZW(inA, inC); + +#define PX_TRANSPOSE_44(inA, inB, inC, inD, outA, outB, outC, outD) \ + outA = V4UnpackXY(inA, inC); \ + inA = V4UnpackZW(inA, inC); \ + inC = V4UnpackXY(inB, inD); \ + inB = V4UnpackZW(inB, inD); \ + outB = V4UnpackZW(outA, inC); \ + outA = V4UnpackXY(outA, inC); \ + outC = V4UnpackXY(inA, inB); \ + outD = V4UnpackZW(inA, inB); + +// This function returns a Vec4V, where each element is the dot product of one pair of Vec3Vs. On PC, each element in +// the result should be identical to the results if V3Dot was performed +// for each pair of Vec3V. +// However, on other platforms, the result might diverge by some small margin due to differences in FP rounding, e.g. if +// _mm_dp_ps was used or some other approximate dot product or fused madd operations +// were used. +// Where there does not exist a hw-accelerated dot-product operation, this approach should be the fastest way to compute +// the dot product of 4 vectors. +PX_FORCE_INLINE Vec4V V3Dot4(const Vec3VArg a0, const Vec3VArg b0, const Vec3VArg a1, const Vec3VArg b1, + const Vec3VArg a2, const Vec3VArg b2, const Vec3VArg a3, const Vec3VArg b3) +{ + Vec4V a0b0 = Vec4V_From_Vec3V(V3Mul(a0, b0)); + Vec4V a1b1 = Vec4V_From_Vec3V(V3Mul(a1, b1)); + Vec4V a2b2 = Vec4V_From_Vec3V(V3Mul(a2, b2)); + Vec4V a3b3 = Vec4V_From_Vec3V(V3Mul(a3, b3)); + + Vec4V aTrnsps, bTrnsps, cTrnsps; + + PX_TRANSPOSE_44_34(a0b0, a1b1, a2b2, a3b3, aTrnsps, bTrnsps, cTrnsps); + + return V4Add(V4Add(aTrnsps, bTrnsps), cTrnsps); +} + +//(f.x,f.y,f.z,0) - Alternative/faster V3LoadU implementation when it is safe to read "W", i.e. the 32bits after the PxVec3. +PX_FORCE_INLINE Vec3V V3LoadU_SafeReadW(const PxVec3& f) +{ + return Vec3V_From_Vec4V(V4LoadU(&f.x)); +} + +} // namespace aos +#if !PX_DOXYGEN +} // namespace physx +#endif + +// Now for the cross-platform implementations of the 16-byte aligned maths functions (win32/360/ppu/spu etc). +#if COMPILE_VECTOR_INTRINSICS +#include "PxInlineAoS.h" +#else // #if COMPILE_VECTOR_INTRINSICS +#include "PxVecMathAoSScalarInline.h" +#endif // #if !COMPILE_VECTOR_INTRINSICS +#include "PxVecQuat.h" + +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxVecMathAoSScalar.h b/Source/ThirdParty/PhysX/foundation/PxVecMathAoSScalar.h new file mode 100644 index 000000000..11243cd13 --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxVecMathAoSScalar.h @@ -0,0 +1,251 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_VEC_MATH_AOS_SCALAR_H +#define PX_VEC_MATH_AOS_SCALAR_H + +#if COMPILE_VECTOR_INTRINSICS +#error Scalar version should not be included when using vector intrinsics. +#endif + +#if !PX_DOXYGEN +namespace physx +{ +#endif +namespace aos +{ + +struct VecI16V; +struct VecU16V; +struct VecI32V; +struct VecU32V; +struct Vec4V; +typedef Vec4V QuatV; + +PX_ALIGN_PREFIX(16) +struct FloatV +{ + PxF32 x; + PxF32 pad[3]; + FloatV() + { + } + FloatV(const PxF32 _x) : x(_x) + { + } +} PX_ALIGN_SUFFIX(16); + +PX_ALIGN_PREFIX(16) +struct Vec4V +{ + PxF32 x, y, z, w; + Vec4V() + { + } + Vec4V(const PxF32 _x, const PxF32 _y, const PxF32 _z, const PxF32 _w) : x(_x), y(_y), z(_z), w(_w) + { + } +} PX_ALIGN_SUFFIX(16); + +PX_ALIGN_PREFIX(16) +struct Vec3V +{ + PxF32 x, y, z; + PxF32 pad; + Vec3V() + { + } + Vec3V(const PxF32 _x, const PxF32 _y, const PxF32 _z) : x(_x), y(_y), z(_z), pad(0.0f) + { + } +} PX_ALIGN_SUFFIX(16); + +PX_ALIGN_PREFIX(16) +struct BoolV +{ + PxU32 ux, uy, uz, uw; + BoolV() + { + } + BoolV(const PxU32 _x, const PxU32 _y, const PxU32 _z, const PxU32 _w) : ux(_x), uy(_y), uz(_z), uw(_w) + { + } +} PX_ALIGN_SUFFIX(16); + +struct Mat33V +{ + Mat33V() + { + } + Mat33V(const Vec3V& c0, const Vec3V& c1, const Vec3V& c2) : col0(c0), col1(c1), col2(c2) + { + } + Vec3V col0; + Vec3V col1; + Vec3V col2; +}; + +struct Mat34V +{ + Mat34V() + { + } + Mat34V(const Vec3V& c0, const Vec3V& c1, const Vec3V& c2, const Vec3V& c3) : col0(c0), col1(c1), col2(c2), col3(c3) + { + } + Vec3V col0; + Vec3V col1; + Vec3V col2; + Vec3V col3; +}; + +struct Mat43V +{ + Mat43V() + { + } + Mat43V(const Vec4V& c0, const Vec4V& c1, const Vec4V& c2) : col0(c0), col1(c1), col2(c2) + { + } + Vec4V col0; + Vec4V col1; + Vec4V col2; +}; + +struct Mat44V +{ + Mat44V() + { + } + Mat44V(const Vec4V& c0, const Vec4V& c1, const Vec4V& c2, const Vec4V& c3) : col0(c0), col1(c1), col2(c2), col3(c3) + { + } + Vec4V col0; + Vec4V col1; + Vec4V col2; + Vec4V col3; +}; + +PX_ALIGN_PREFIX(16) +struct VecU32V +{ + PxU32 u32[4]; + PX_FORCE_INLINE VecU32V() + { + } + PX_FORCE_INLINE VecU32V(PxU32 a, PxU32 b, PxU32 c, PxU32 d) + { + u32[0] = a; + u32[1] = b; + u32[2] = c; + u32[3] = d; + } +} PX_ALIGN_SUFFIX(16); + +PX_ALIGN_PREFIX(16) +struct VecI32V +{ + PxI32 i32[4]; + PX_FORCE_INLINE VecI32V() + { + } + PX_FORCE_INLINE VecI32V(PxI32 a, PxI32 b, PxI32 c, PxI32 d) + { + i32[0] = a; + i32[1] = b; + i32[2] = c; + i32[3] = d; + } +} PX_ALIGN_SUFFIX(16); + +PX_ALIGN_PREFIX(16) +struct VecI16V +{ + PxI16 i16[8]; + PX_FORCE_INLINE VecI16V() + { + } + PX_FORCE_INLINE VecI16V(PxI16 a, PxI16 b, PxI16 c, PxI16 d, PxI16 e, PxI16 f, PxI16 g, PxI16 h) + { + i16[0] = a; + i16[1] = b; + i16[2] = c; + i16[3] = d; + i16[4] = e; + i16[5] = f; + i16[6] = g; + i16[7] = h; + } +} PX_ALIGN_SUFFIX(16); + +PX_ALIGN_PREFIX(16) +struct VecU16V +{ + union + { + PxU16 u16[8]; + PxI16 i16[8]; + }; + PX_FORCE_INLINE VecU16V() + { + } + PX_FORCE_INLINE VecU16V(PxU16 a, PxU16 b, PxU16 c, PxU16 d, PxU16 e, PxU16 f, PxU16 g, PxU16 h) + { + u16[0] = a; + u16[1] = b; + u16[2] = c; + u16[3] = d; + u16[4] = e; + u16[5] = f; + u16[6] = g; + u16[7] = h; + } +} PX_ALIGN_SUFFIX(16); + +#define FloatVArg FloatV & +#define Vec3VArg Vec3V & +#define Vec4VArg Vec4V & +#define BoolVArg BoolV & +#define VecU32VArg VecU32V & +#define VecI32VArg VecI32V & +#define VecU16VArg VecU16V & +#define VecI16VArg VecI16V & +#define QuatVArg QuatV & + +#define VecCrossV Vec3V + +typedef VecI32V VecShiftV; +#define VecShiftVArg VecShiftV & + +} // namespace aos +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxVecMathAoSScalarInline.h b/Source/ThirdParty/PhysX/foundation/PxVecMathAoSScalarInline.h new file mode 100644 index 000000000..b328ebb79 --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxVecMathAoSScalarInline.h @@ -0,0 +1,2293 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_VEC_MATH_AOS_SCALAR_INLINE_H +#define PX_VEC_MATH_AOS_SCALAR_INLINE_H + +#if COMPILE_VECTOR_INTRINSICS +#error Scalar version should not be included when using vector intrinsics. +#endif + +#if !PX_DOXYGEN +namespace physx +{ +#endif +namespace aos +{ + +#define BOOL_TO_U32(b) PxU32(- PxI32(b)) +#define TRUE_TO_U32 PxU32(-1) +#define FALSE_TO_U32 PxU32(0) + +#define BOOL_TO_U16(b) PxU16(- PxI32(b)) + +#define PX_VECMATH_ASSERT_ENABLED 0 + +#if PX_VECMATH_ASSERT_ENABLED +#define VECMATHAOS_ASSERT(x) { PX_ASSERT(x); } +#else +#define VECMATHAOS_ASSERT(x) +#endif + +///////////////////////////////////////////////////////////////////// +////INTERNAL USE ONLY AND TESTS +///////////////////////////////////////////////////////////////////// + +namespace internalScalarSimd +{ +PX_FORCE_INLINE PxF32 FStore(const FloatV a) +{ + return a.x; +} + +PX_FORCE_INLINE bool hasZeroElementInFloatV(const FloatV a) +{ + return (0 == a.x); +} + +PX_FORCE_INLINE bool hasZeroElementInVec3V(const Vec3V a) +{ + return (0 == a.x || 0 == a.y || 0 == a.z); +} + +PX_FORCE_INLINE bool hasZeroElementInVec4V(const Vec4V a) +{ + return (0 == a.x || 0 == a.y || 0 == a.z || 0 == a.w); +} +} + +namespace vecMathTests +{ +// PT: this function returns an invalid Vec3V (W!=0.0f) just for unit-testing 'isValidVec3V' +PX_FORCE_INLINE Vec3V getInvalidVec3V() +{ + Vec3V tmp; + tmp.x = tmp.y = tmp.z = 0.0f; + tmp.pad = 1.0f; + return tmp; +} + +PX_FORCE_INLINE bool allElementsEqualFloatV(const FloatV a, const FloatV b) +{ + return (a.x == b.x); +} + +PX_FORCE_INLINE bool allElementsEqualVec3V(const Vec3V a, const Vec3V b) +{ + return (a.x == b.x && a.y == b.y && a.z == b.z); +} + +PX_FORCE_INLINE bool allElementsEqualVec4V(const Vec4V a, const Vec4V b) +{ + return (a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w); +} + +PX_FORCE_INLINE bool allElementsEqualBoolV(const BoolV a, const BoolV b) +{ + return (a.ux == b.ux && a.uy == b.uy && a.uz == b.uz && a.uw == b.uw); +} + +PX_FORCE_INLINE bool allElementsEqualVecU32V(const VecU32V a, const VecU32V b) +{ + return (a.u32[0] == b.u32[0] && a.u32[1] == b.u32[1] && a.u32[2] == b.u32[2] && a.u32[3] == b.u32[3]); +} + +PX_FORCE_INLINE bool allElementsEqualVecI32V(const VecI32V a, const VecI32V b) +{ + return (a.i32[0] == b.i32[0] && a.i32[1] == b.i32[1] && a.i32[2] == b.i32[2] && a.i32[3] == b.i32[3]); +} + +#define VECMATH_AOS_EPSILON (1e-3f) + +PX_FORCE_INLINE bool allElementsNearEqualFloatV(const FloatV a, const FloatV b) +{ + const PxF32 cx = a.x - b.x; + return (cx > -VECMATH_AOS_EPSILON && cx < VECMATH_AOS_EPSILON); +} + +PX_FORCE_INLINE bool allElementsNearEqualVec3V(const Vec3V a, const Vec3V b) +{ + const PxF32 cx = a.x - b.x; + const PxF32 cy = a.y - b.y; + const PxF32 cz = a.z - b.z; + return (cx > -VECMATH_AOS_EPSILON && cx < VECMATH_AOS_EPSILON && cy > -VECMATH_AOS_EPSILON && + cy < VECMATH_AOS_EPSILON && cz > -VECMATH_AOS_EPSILON && cz < VECMATH_AOS_EPSILON); +} + +PX_FORCE_INLINE bool allElementsNearEqualVec4V(const Vec4V a, const Vec4V b) +{ + const PxF32 cx = a.x - b.x; + const PxF32 cy = a.y - b.y; + const PxF32 cz = a.z - b.z; + const PxF32 cw = a.w - b.w; + return (cx > -VECMATH_AOS_EPSILON && cx < VECMATH_AOS_EPSILON && cy > -VECMATH_AOS_EPSILON && + cy < VECMATH_AOS_EPSILON && cz > -VECMATH_AOS_EPSILON && cz < VECMATH_AOS_EPSILON && + cw > -VECMATH_AOS_EPSILON && cw < VECMATH_AOS_EPSILON); +} +} + +/////////////////////////////////////////////////////// + +PX_FORCE_INLINE bool isValidVec3V(const Vec3V a) +{ + return a.pad == 0.f; +} + +PX_FORCE_INLINE bool isFiniteFloatV(const FloatV a) +{ + return PxIsFinite(a.x); +} + +PX_FORCE_INLINE bool isFiniteVec3V(const Vec3V a) +{ + return PxIsFinite(a.x) && PxIsFinite(a.y) && PxIsFinite(a.z); +} + +PX_FORCE_INLINE bool isFiniteVec4V(const Vec4V a) +{ + return PxIsFinite(a.x) && PxIsFinite(a.y) && PxIsFinite(a.z) && PxIsFinite(a.w); +} + +///////////////////////////////////////////////////////////////////// +////VECTORISED FUNCTION IMPLEMENTATIONS +///////////////////////////////////////////////////////////////////// + +PX_FORCE_INLINE FloatV FLoad(const PxF32 f) +{ + return FloatV(f); +} + +PX_FORCE_INLINE Vec3V V3Load(const PxF32 f) +{ + return Vec3V(f, f, f); +} + +PX_FORCE_INLINE Vec4V V4Load(const PxF32 f) +{ + return Vec4V(f, f, f, f); +} + +PX_FORCE_INLINE BoolV BLoad(const bool f) +{ +#if PX_ARM + // SD: Android ARM builds fail if this is done with a cast. + // Might also fail because of something else but the select + // operator here seems to fix everything that failed in release builds. + return f ? BTTTT() : BFFFF(); +#else + return BoolV(BOOL_TO_U32(f), BOOL_TO_U32(f), BOOL_TO_U32(f), BOOL_TO_U32(f)); +#endif +} + +PX_FORCE_INLINE Vec3V V3LoadA(const PxVec3& f) +{ + return Vec3V(f.x, f.y, f.z); +} + +PX_FORCE_INLINE Vec3V V3LoadU(const PxVec3& f) +{ + return Vec3V(f.x, f.y, f.z); +} + +PX_FORCE_INLINE Vec3V V3LoadUnsafeA(const PxVec3& f) +{ + return Vec3V(f.x, f.y, f.z); +} + +PX_FORCE_INLINE Vec3V V3LoadA(const PxF32* const f) +{ + return Vec3V(f[0], f[1], f[2]); +} + +PX_FORCE_INLINE Vec3V V3LoadU(const PxF32* const f) +{ + return Vec3V(f[0], f[1], f[2]); +} + +PX_FORCE_INLINE Vec3V Vec3V_From_Vec4V(Vec4V f) +{ + return Vec3V(f.x, f.y, f.z); +} + +PX_FORCE_INLINE Vec3V Vec3V_From_Vec4V_WUndefined(const Vec4V v) +{ + return Vec3V(v.x, v.y, v.z); +} + +PX_FORCE_INLINE Vec4V Vec4V_From_Vec3V(Vec3V f) +{ + return Vec4V(f.x, f.y, f.z, 0.0f); +} + +PX_FORCE_INLINE Vec4V Vec4V_From_FloatV(FloatV f) +{ + return Vec4V(f.x, f.x, f.x, f.x); +} + +PX_FORCE_INLINE Vec3V Vec3V_From_FloatV(FloatV f) +{ + return Vec3V(f.x, f.x, f.x); +} + +PX_FORCE_INLINE Vec3V Vec3V_From_FloatV_WUndefined(FloatV f) +{ + return Vec3V(f.x, f.x, f.x); +} + +PX_FORCE_INLINE Vec4V V4LoadA(const PxF32* const f) +{ + return Vec4V(f[0], f[1], f[2], f[3]); +} + +PX_FORCE_INLINE void V4StoreA(const Vec4V a, PxF32* f) +{ + *reinterpret_cast(f) = a; +} + +PX_FORCE_INLINE void V4StoreU(const Vec4V a, PxF32* f) +{ + *reinterpret_cast(f) = *reinterpret_cast(&a.x); +} + +PX_FORCE_INLINE void BStoreA(const BoolV a, PxU32* f) +{ + *reinterpret_cast(f) = a; +} + +PX_FORCE_INLINE void U4StoreA(const VecU32V uv, PxU32* u) +{ + *reinterpret_cast(u) = uv; +} + +PX_FORCE_INLINE void I4StoreA(const VecI32V iv, PxI32* i) +{ + *reinterpret_cast(i) = iv; +} + +PX_FORCE_INLINE Vec4V V4LoadU(const PxF32* const f) +{ + return Vec4V(f[0], f[1], f[2], f[3]); +} + +PX_FORCE_INLINE Vec4V Vec4V_From_PxVec3_WUndefined(const PxVec3& f) +{ + return Vec4V(f[0], f[1], f[2], 0.0f); +} + +PX_FORCE_INLINE BoolV BLoad(const bool* const f) +{ + return BoolV(BOOL_TO_U32(f[0]), BOOL_TO_U32(f[1]), BOOL_TO_U32(f[2]), BOOL_TO_U32(f[3])); +} + +PX_FORCE_INLINE void FStore(const FloatV a, PxF32* PX_RESTRICT f) +{ + *f = a.x; +} + +PX_FORCE_INLINE void V3StoreA(const Vec3V a, PxVec3& f) +{ + f = PxVec3(a.x, a.y, a.z); +} + +PX_FORCE_INLINE void V3StoreU(const Vec3V a, PxVec3& f) +{ + f = PxVec3(a.x, a.y, a.z); +} + +PX_FORCE_INLINE void Store_From_BoolV(const BoolV b, PxU32* b2) +{ + *b2 = b.ux; +} + +////////////////////////// +// FLOATV +////////////////////////// + +PX_FORCE_INLINE FloatV FZero() +{ + return FLoad(0.0f); +} + +PX_FORCE_INLINE FloatV FOne() +{ + return FLoad(1.0f); +} + +PX_FORCE_INLINE FloatV FHalf() +{ + return FLoad(0.5f); +} + +PX_FORCE_INLINE FloatV FEps() +{ + return FLoad(PX_EPS_REAL); +} + +PX_FORCE_INLINE FloatV FEps6() +{ + return FLoad(1e-6f); +} + +//! @cond +PX_FORCE_INLINE FloatV FMax() +{ + return FLoad(PX_MAX_REAL); +} +//! @endcond + +PX_FORCE_INLINE FloatV FNegMax() +{ + return FLoad(-PX_MAX_REAL); +} + +PX_FORCE_INLINE FloatV FNeg(const FloatV f) +{ + return FloatV(-f.x); +} + +PX_FORCE_INLINE FloatV FAdd(const FloatV a, const FloatV b) +{ + return FloatV(a.x + b.x); +} + +PX_FORCE_INLINE FloatV FSub(const FloatV a, const FloatV b) +{ + return FloatV(a.x - b.x); +} + +PX_FORCE_INLINE FloatV FMul(const FloatV a, const FloatV b) +{ + return FloatV(a.x * b.x); +} + +PX_FORCE_INLINE FloatV FDiv(const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(b.x != 0.0f); + return FloatV(a.x / b.x); +} + +PX_FORCE_INLINE FloatV FDivFast(const FloatV a, const FloatV b) +{ + VECMATHAOS_ASSERT(b.x != 0.0f); + return FloatV(a.x / b.x); +} + +PX_FORCE_INLINE FloatV FRecip(const FloatV a) +{ + VECMATHAOS_ASSERT(a.x != 0.0f); + return 1.0f / a.x; +} + +PX_FORCE_INLINE FloatV FRecipFast(const FloatV a) +{ + VECMATHAOS_ASSERT(a.x != 0.0f); + return 1.0f / a.x; +} + +PX_FORCE_INLINE FloatV FRsqrt(const FloatV a) +{ + VECMATHAOS_ASSERT(a.x != 0.0f); + return PxRecipSqrt(a.x); +} + +PX_FORCE_INLINE FloatV FSqrt(const FloatV a) +{ + return PxSqrt(a.x); +} + +PX_FORCE_INLINE FloatV FRsqrtFast(const FloatV a) +{ + VECMATHAOS_ASSERT(a.x != 0.0f); + return PxRecipSqrt(a.x); +} + +PX_FORCE_INLINE FloatV FScaleAdd(const FloatV a, const FloatV b, const FloatV c) +{ + return FAdd(FMul(a, b), c); +} + +PX_FORCE_INLINE FloatV FNegScaleSub(const FloatV a, const FloatV b, const FloatV c) +{ + return FSub(c, FMul(a, b)); +} + +PX_FORCE_INLINE FloatV FAbs(const FloatV a) +{ + return FloatV(PxAbs(a.x)); +} + +PX_FORCE_INLINE FloatV FSel(const BoolV c, const FloatV a, const FloatV b) +{ + return FloatV(c.ux ? a.x : b.x); +} + +PX_FORCE_INLINE BoolV FIsGrtr(const FloatV a, const FloatV b) +{ + return BLoad(a.x > b.x); +} + +PX_FORCE_INLINE BoolV FIsGrtrOrEq(const FloatV a, const FloatV b) +{ + return BLoad(a.x >= b.x); +} + +PX_FORCE_INLINE BoolV FIsEq(const FloatV a, const FloatV b) +{ + return BLoad(a.x == b.x); +} + +PX_FORCE_INLINE FloatV FMax(const FloatV a, const FloatV b) +{ + return (a.x > b.x ? FloatV(a.x) : FloatV(b.x)); +} + +PX_FORCE_INLINE FloatV FMin(const FloatV a, const FloatV b) +{ + return (a.x > b.x ? FloatV(b.x) : FloatV(a.x)); +} + +PX_FORCE_INLINE FloatV FClamp(const FloatV a, const FloatV minV, const FloatV maxV) +{ + return FMax(FMin(a, maxV), minV); +} + +PX_FORCE_INLINE PxU32 FAllGrtr(const FloatV a, const FloatV b) +{ + return BOOL_TO_U32(a.x > b.x); +} + +PX_FORCE_INLINE PxU32 FAllGrtrOrEq(const FloatV a, const FloatV b) +{ + return BOOL_TO_U32(a.x >= b.x); +} +PX_FORCE_INLINE PxU32 FAllEq(const FloatV a, const FloatV b) +{ + return BOOL_TO_U32(a.x == b.x); +} + +PX_FORCE_INLINE FloatV FRound(const FloatV a) +{ + return floorf(a.x + 0.5f); +} + +PX_FORCE_INLINE FloatV FSin(const FloatV a) +{ + return sinf(a.x); +} + +PX_FORCE_INLINE FloatV FCos(const FloatV a) +{ + return cosf(a.x); +} + +PX_FORCE_INLINE PxU32 FOutOfBounds(const FloatV a, const FloatV min, const FloatV max) +{ + return BOOL_TO_U32(a.x > max.x || a.x < min.x); +} + +PX_FORCE_INLINE PxU32 FInBounds(const FloatV a, const FloatV min, const FloatV max) +{ + return BOOL_TO_U32(a.x >= min.x && a.x <= max.x); +} + +PX_FORCE_INLINE PxU32 FOutOfBounds(const FloatV a, const FloatV bounds) +{ + return FOutOfBounds(a, FNeg(bounds), bounds); +} + +PX_FORCE_INLINE PxU32 FInBounds(const FloatV a, const FloatV bounds) +{ + return FInBounds(a, FNeg(bounds), bounds); +} + +///////////////////// +// VEC3V +///////////////////// + +PX_FORCE_INLINE Vec3V V3Splat(const FloatV f) +{ + return Vec3V(f.x, f.x, f.x); +} + +PX_FORCE_INLINE Vec3V V3Merge(const FloatVArg x, const FloatVArg y, const FloatVArg z) +{ + return Vec3V(x.x, y.x, z.x); +} + +PX_FORCE_INLINE Vec3V V3UnitX() +{ + return Vec3V(1.0f, 0.0f, 0.0f); +} + +PX_FORCE_INLINE Vec3V V3UnitY() +{ + return Vec3V(0.0f, 1.0f, 0.0f); +} + +PX_FORCE_INLINE Vec3V V3UnitZ() +{ + return Vec3V(0.0f, 0.0f, 1.0f); +} + +PX_FORCE_INLINE FloatV V3GetX(const Vec3V f) +{ + return FloatV(f.x); +} + +PX_FORCE_INLINE FloatV V3GetY(const Vec3V f) +{ + return FloatV(f.y); +} + +PX_FORCE_INLINE FloatV V3GetZ(const Vec3V f) +{ + return FloatV(f.z); +} + +PX_FORCE_INLINE Vec3V V3SetX(const Vec3V v, const FloatV f) +{ + return Vec3V(f.x, v.y, v.z); +} + +PX_FORCE_INLINE Vec3V V3SetY(const Vec3V v, const FloatV f) +{ + return Vec3V(v.x, f.x, v.z); +} + +PX_FORCE_INLINE Vec3V V3SetZ(const Vec3V v, const FloatV f) +{ + return Vec3V(v.x, v.y, f.x); +} + +PX_FORCE_INLINE Vec3V V3ColX(const Vec3V a, const Vec3V b, const Vec3V c) +{ + return Vec3V(a.x, b.x, c.x); +} + +PX_FORCE_INLINE Vec3V V3ColY(const Vec3V a, const Vec3V b, const Vec3V c) +{ + return Vec3V(a.y, b.y, c.y); +} + +PX_FORCE_INLINE Vec3V V3ColZ(const Vec3V a, const Vec3V b, const Vec3V c) +{ + return Vec3V(a.z, b.z, c.z); +} + +PX_FORCE_INLINE Vec3V V3Zero() +{ + return V3Load(0.0f); +} + +PX_FORCE_INLINE Vec3V V3One() +{ + return V3Load(1.0f); +} + +PX_FORCE_INLINE Vec3V V3Eps() +{ + return V3Load(PX_EPS_REAL); +} + +PX_FORCE_INLINE Vec3V V3Neg(const Vec3V c) +{ + return Vec3V(-c.x, -c.y, -c.z); +} + +PX_FORCE_INLINE Vec3V V3Add(const Vec3V a, const Vec3V b) +{ + return Vec3V(a.x + b.x, a.y + b.y, a.z + b.z); +} + +PX_FORCE_INLINE Vec3V V3Sub(const Vec3V a, const Vec3V b) +{ + return Vec3V(a.x - b.x, a.y - b.y, a.z - b.z); +} + +PX_FORCE_INLINE Vec3V V3Scale(const Vec3V a, const FloatV b) +{ + return Vec3V(a.x * b.x, a.y * b.x, a.z * b.x); +} + +PX_FORCE_INLINE Vec3V V3Mul(const Vec3V a, const Vec3V b) +{ + return Vec3V(a.x * b.x, a.y * b.y, a.z * b.z); +} + +PX_FORCE_INLINE Vec3V V3ScaleInv(const Vec3V a, const FloatV b) +{ + const PxF32 bInv = 1.0f / b.x; + return Vec3V(a.x * bInv, a.y * bInv, a.z * bInv); +} + +PX_FORCE_INLINE Vec3V V3Div(const Vec3V a, const Vec3V b) +{ + return Vec3V(a.x / b.x, a.y / b.y, a.z / b.z); +} + +PX_FORCE_INLINE Vec3V V3ScaleInvFast(const Vec3V a, const FloatV b) +{ + const PxF32 bInv = 1.0f / b.x; + return Vec3V(a.x * bInv, a.y * bInv, a.z * bInv); +} + +PX_FORCE_INLINE Vec3V V3DivFast(const Vec3V a, const Vec3V b) +{ + return Vec3V(a.x / b.x, a.y / b.y, a.z / b.z); +} + +PX_FORCE_INLINE Vec3V V3Recip(const Vec3V a) +{ + return Vec3V(1.0f / a.x, 1.0f / a.y, 1.0f / a.z); +} + +PX_FORCE_INLINE Vec3V V3RecipFast(const Vec3V a) +{ + return Vec3V(1.0f / a.x, 1.0f / a.y, 1.0f / a.z); +} + +PX_FORCE_INLINE Vec3V V3Rsqrt(const Vec3V a) +{ + return Vec3V(PxRecipSqrt(a.x), PxRecipSqrt(a.y), PxRecipSqrt(a.z)); +} + +PX_FORCE_INLINE Vec3V V3RsqrtFast(const Vec3V a) +{ + return Vec3V(PxRecipSqrt(a.x), PxRecipSqrt(a.y), PxRecipSqrt(a.z)); +} + +PX_FORCE_INLINE Vec3V V3ScaleAdd(const Vec3V a, const FloatV b, const Vec3V c) +{ + return V3Add(V3Scale(a, b), c); +} + +PX_FORCE_INLINE Vec3V V3NegScaleSub(const Vec3V a, const FloatV b, const Vec3V c) +{ + return V3Sub(c, V3Scale(a, b)); +} + +PX_FORCE_INLINE Vec3V V3MulAdd(const Vec3V a, const Vec3V b, const Vec3V c) +{ + return V3Add(V3Mul(a, b), c); +} + +PX_FORCE_INLINE Vec3V V3NegMulSub(const Vec3V a, const Vec3V b, const Vec3V c) +{ + return V3Sub(c, V3Mul(a, b)); +} + +PX_FORCE_INLINE FloatV V3Dot(const Vec3V a, const Vec3V b) +{ + return FloatV(a.x * b.x + a.y * b.y + a.z * b.z); +} + +PX_FORCE_INLINE VecCrossV V3PrepareCross(const Vec3VArg normal) +{ + return normal; +} + +PX_FORCE_INLINE Vec3V V3Cross(const Vec3V a, const Vec3V b) +{ + return Vec3V(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x); +} + +PX_FORCE_INLINE FloatV V3Length(const Vec3V a) +{ + return FloatV(PxSqrt(a.x * a.x + a.y * a.y + a.z * a.z)); +} + +PX_FORCE_INLINE FloatV V3LengthSq(const Vec3V a) +{ + return FloatV(a.x * a.x + a.y * a.y + a.z * a.z); +} + +PX_FORCE_INLINE Vec3V V3Normalize(const Vec3V a) +{ + VECMATHAOS_ASSERT(a.x != 0 || a.y != 0 || a.z != 0); + const PxF32 lengthInv = 1.0f / PxSqrt(a.x * a.x + a.y * a.y + a.z * a.z); + return Vec3V(a.x * lengthInv, a.y * lengthInv, a.z * lengthInv); +} + +PX_FORCE_INLINE Vec3V V3NormalizeSafe(const Vec3V a, const Vec3V unsafeReturnValue) +{ + const PxF32 length = PxSqrt(a.x * a.x + a.y * a.y + a.z * a.z); + if(PX_EPS_REAL >= length) + { + return unsafeReturnValue; + } + else + { + const PxF32 lengthInv = 1.0f / length; + return Vec3V(a.x * lengthInv, a.y * lengthInv, a.z * lengthInv); + } +} + +PX_FORCE_INLINE Vec3V V3NormalizeFast(const Vec3V a) +{ + VECMATHAOS_ASSERT(a.x != 0 || a.y != 0 || a.z != 0); + const PxF32 lengthInv = 1.0f / PxSqrt(a.x * a.x + a.y * a.y + a.z * a.z); + return Vec3V(a.x * lengthInv, a.y * lengthInv, a.z * lengthInv); +} + +PX_FORCE_INLINE Vec3V V3Sel(const BoolV c, const Vec3V a, const Vec3V b) +{ + return Vec3V(c.ux ? a.x : b.x, c.uy ? a.y : b.y, c.uz ? a.z : b.z); +} + +PX_FORCE_INLINE BoolV V3IsGrtr(const Vec3V a, const Vec3V b) +{ + return BoolV(BOOL_TO_U32(a.x > b.x), BOOL_TO_U32(a.y > b.y), BOOL_TO_U32(a.z > b.z), FALSE_TO_U32); +} + +PX_FORCE_INLINE BoolV V3IsGrtrOrEq(const Vec3V a, const Vec3V b) +{ + return BoolV(BOOL_TO_U32(a.x >= b.x), BOOL_TO_U32(a.y >= b.y), BOOL_TO_U32(a.z >= b.z), TRUE_TO_U32); +} + +PX_FORCE_INLINE BoolV V3IsEq(const Vec3V a, const Vec3V b) +{ + return BoolV(BOOL_TO_U32(a.x == b.x), BOOL_TO_U32(a.y == b.y), BOOL_TO_U32(a.z == b.z), TRUE_TO_U32); +} + +PX_FORCE_INLINE Vec3V V3Max(const Vec3V a, const Vec3V b) +{ + return Vec3V(a.x > b.x ? a.x : b.x, a.y > b.y ? a.y : b.y, a.z > b.z ? a.z : b.z); +} + +PX_FORCE_INLINE Vec3V V3Min(const Vec3V a, const Vec3V b) +{ + return Vec3V(a.x < b.x ? a.x : b.x, a.y < b.y ? a.y : b.y, a.z < b.z ? a.z : b.z); +} + +PX_FORCE_INLINE FloatV V3ExtractMax(const Vec3V a) +{ + const PxF32 t0 = (a.x >= a.y) ? a.x : a.y; + return t0 >= a.z ? t0 : a.z; +} + +PX_FORCE_INLINE FloatV V3ExtractMin(const Vec3V a) +{ + const PxF32 t0 = (a.x <= a.y) ? a.x : a.y; + return t0 <= a.z ? t0 : a.z; +} + +// return (a >= 0.0f) ? 1.0f : -1.0f; +PX_FORCE_INLINE Vec3V V3Sign(const Vec3V a) +{ + return Vec3V((a.x >= 0.f ? 1.f : -1.f), (a.y >= 0.f ? 1.f : -1.f), (a.z >= 0.f ? 1.f : -1.f)); +} + +PX_FORCE_INLINE Vec3V V3Clamp(const Vec3V a, const Vec3V minV, const Vec3V maxV) +{ + return V3Max(V3Min(a, maxV), minV); +} + +PX_FORCE_INLINE Vec3V V3Abs(const Vec3V a) +{ + return V3Max(a, V3Neg(a)); +} + +PX_FORCE_INLINE PxU32 V3AllGrtr(const Vec3V a, const Vec3V b) +{ + return BOOL_TO_U32((a.x > b.x) & (a.y > b.y) & (a.z > b.z)); +} + +PX_FORCE_INLINE PxU32 V3AllGrtrOrEq(const Vec3V a, const Vec3V b) +{ + return BOOL_TO_U32((a.x >= b.x) & (a.y >= b.y) & (a.z >= b.z)); +} + +PX_FORCE_INLINE PxU32 V3AllEq(const Vec3V a, const Vec3V b) +{ + return BOOL_TO_U32((a.x == b.x) & (a.y == b.y) & (a.z == b.z)); +} + +PX_FORCE_INLINE Vec3V V3Round(const Vec3V a) +{ + return Vec3V(floorf(a.x + 0.5f), floorf(a.y + 0.5f), floorf(a.z + 0.5f)); +} + +PX_FORCE_INLINE Vec3V V3Sin(const Vec3V a) +{ + return Vec3V(sinf(a.x), sinf(a.y), sinf(a.z)); +} + +PX_FORCE_INLINE Vec3V V3Cos(const Vec3V a) +{ + return Vec3V(cosf(a.x), cosf(a.y), cosf(a.z)); +} + +PX_FORCE_INLINE Vec3V V3PermYZZ(const Vec3V a) +{ + return Vec3V(a.y, a.z, a.z); +} + +PX_FORCE_INLINE Vec3V V3PermXYX(const Vec3V a) +{ + return Vec3V(a.x, a.y, a.x); +} + +PX_FORCE_INLINE Vec3V V3PermYZX(const Vec3V a) +{ + return Vec3V(a.y, a.z, a.x); +} + +PX_FORCE_INLINE Vec3V V3PermZXY(const Vec3V a) +{ + return Vec3V(a.z, a.x, a.y); +} + +PX_FORCE_INLINE Vec3V V3PermZZY(const Vec3V a) +{ + return Vec3V(a.z, a.z, a.y); +} + +PX_FORCE_INLINE Vec3V V3PermYXX(const Vec3V a) +{ + return Vec3V(a.y, a.x, a.x); +} + +PX_FORCE_INLINE Vec3V V3Perm_Zero_1Z_0Y(const Vec3V v0, const Vec3V v1) +{ + return Vec3V(0.0f, v1.z, v0.y); +} + +PX_FORCE_INLINE Vec3V V3Perm_0Z_Zero_1X(const Vec3V v0, const Vec3V v1) +{ + return Vec3V(v0.z, 0.0f, v1.x); +} + +PX_FORCE_INLINE Vec3V V3Perm_1Y_0X_Zero(const Vec3V v0, const Vec3V v1) +{ + return Vec3V(v1.y, v0.x, 0.0f); +} + +PX_FORCE_INLINE FloatV V3SumElems(const Vec3V a) +{ + return FloatV(a.x + a.y + a.z); +} + +PX_FORCE_INLINE PxU32 V3OutOfBounds(const Vec3V a, const Vec3V min, const Vec3V max) +{ + return BOOL_TO_U32(a.x > max.x || a.y > max.y || a.z > max.z || a.x < min.x || a.y < min.y || a.z < min.z); +} + +PX_FORCE_INLINE PxU32 V3InBounds(const Vec3V a, const Vec3V min, const Vec3V max) +{ + return BOOL_TO_U32(a.x <= max.x && a.y <= max.y && a.z <= max.z && a.x >= min.x && a.y >= min.y && a.z >= min.z); +} + +PX_FORCE_INLINE PxU32 V3OutOfBounds(const Vec3V a, const Vec3V bounds) +{ + return V3OutOfBounds(a, V3Neg(bounds), bounds); +} + +PX_FORCE_INLINE PxU32 V3InBounds(const Vec3V a, const Vec3V bounds) +{ + return V3InBounds(a, V3Neg(bounds), bounds); +} + +PX_FORCE_INLINE void V3Transpose(Vec3V& col0, Vec3V& col1, Vec3V& col2) +{ + const PxF32 t01 = col0.y, t02 = col0.z, t12 = col1.z; + col0.y = col1.x; + col0.z = col2.x; + col1.z = col2.y; + col1.x = t01; + col2.x = t02; + col2.y = t12; +} + +///////////////////////// +// VEC4V +///////////////////////// + +PX_FORCE_INLINE Vec4V V4Splat(const FloatV f) +{ + return Vec4V(f.x, f.x, f.x, f.x); +} + +PX_FORCE_INLINE Vec4V V4Merge(const FloatV* const floatVArray) +{ + return Vec4V(floatVArray[0].x, floatVArray[1].x, floatVArray[2].x, floatVArray[3].x); +} + +PX_FORCE_INLINE Vec4V V4Merge(const FloatVArg x, const FloatVArg y, const FloatVArg z, const FloatVArg w) +{ + return Vec4V(x.x, y.x, z.x, w.x); +} + +PX_FORCE_INLINE Vec4V V4MergeW(const Vec4VArg x, const Vec4VArg y, const Vec4VArg z, const Vec4VArg w) +{ + return Vec4V(x.w, y.w, z.w, w.w); +} + +PX_FORCE_INLINE Vec4V V4MergeZ(const Vec4VArg x, const Vec4VArg y, const Vec4VArg z, const Vec4VArg w) +{ + return Vec4V(x.z, y.z, z.z, w.z); +} + +PX_FORCE_INLINE Vec4V V4MergeY(const Vec4VArg x, const Vec4VArg y, const Vec4VArg z, const Vec4VArg w) +{ + return Vec4V(x.y, y.y, z.y, w.y); +} + +PX_FORCE_INLINE Vec4V V4MergeX(const Vec4VArg x, const Vec4VArg y, const Vec4VArg z, const Vec4VArg w) +{ + return Vec4V(x.x, y.x, z.x, w.x); +} + +PX_FORCE_INLINE Vec4V V4UnpackXY(const Vec4VArg a, const Vec4VArg b) +{ + return Vec4V(a.x, b.x, a.y, b.y); +} + +PX_FORCE_INLINE Vec4V V4UnpackZW(const Vec4VArg a, const Vec4VArg b) +{ + return Vec4V(a.z, b.z, a.w, b.w); +} + +PX_FORCE_INLINE Vec4V V4UnitX() +{ + return Vec4V(1.0f, 0.0f, 0.0f, 0.0f); +} + +PX_FORCE_INLINE Vec4V V4UnitY() +{ + return Vec4V(0.0f, 1.0f, 0.0f, 0.0f); +} + +PX_FORCE_INLINE Vec4V V4UnitZ() +{ + return Vec4V(0.0f, 0.0f, 1.0f, 0.0f); +} + +PX_FORCE_INLINE Vec4V V4UnitW() +{ + return Vec4V(0.0f, 0.0f, 0.0f, 1.0f); +} + +PX_FORCE_INLINE FloatV V4GetX(const Vec4V f) +{ + return FloatV(f.x); +} + +PX_FORCE_INLINE FloatV V4GetY(const Vec4V f) +{ + return FloatV(f.y); +} + +PX_FORCE_INLINE FloatV V4GetZ(const Vec4V f) +{ + return FloatV(f.z); +} + +PX_FORCE_INLINE FloatV V4GetW(const Vec4V f) +{ + return FloatV(f.w); +} + +PX_FORCE_INLINE Vec4V V4SetX(const Vec4V v, const FloatV f) +{ + return Vec4V(f.x, v.y, v.z, v.w); +} + +PX_FORCE_INLINE Vec4V V4SetY(const Vec4V v, const FloatV f) +{ + return Vec4V(v.x, f.x, v.z, v.w); +} + +PX_FORCE_INLINE Vec4V V4SetZ(const Vec4V v, const FloatV f) +{ + return Vec4V(v.x, v.y, f.x, v.w); +} + +PX_FORCE_INLINE Vec4V V4SetW(const Vec4V v, const FloatV f) +{ + return Vec4V(v.x, v.y, v.z, f.x); +} + +PX_FORCE_INLINE Vec4V V4SetW(const Vec3V v, const FloatV f) +{ + return Vec4V(v.x, v.y, v.z, f.x); +} + +PX_FORCE_INLINE Vec4V V4ClearW(const Vec4V v) +{ + return Vec4V(v.x, v.y, v.z, 0.0f); +} + +PX_FORCE_INLINE Vec4V V4PermYXWZ(const Vec4V v) +{ + return Vec4V(v.y, v.x, v.w, v.z); +} + +PX_FORCE_INLINE Vec4V V4PermXZXZ(const Vec4V v) +{ + return Vec4V(v.x, v.z, v.x, v.z); +} + +PX_FORCE_INLINE Vec4V V4PermYWYW(const Vec4V v) +{ + return Vec4V(v.y, v.w, v.y, v.w); +} + +PX_FORCE_INLINE Vec4V V4PermYZXW(const Vec4V v) +{ + return Vec4V(v.y, v.z, v.x, v.w); +} + +PX_FORCE_INLINE Vec4V V4PermZWXY(const Vec4V v) +{ + return Vec4V(v.z, v.w, v.x, v.y); +} + +template +PX_FORCE_INLINE Vec4V V4Perm(const Vec4V v) +{ + const PxF32 f[4] = { v.x, v.y, v.z, v.w }; + return Vec4V(f[_x], f[_y], f[_z], f[_w]); +} + +PX_FORCE_INLINE Vec4V V4Zero() +{ + return V4Load(0.0f); +} + +PX_FORCE_INLINE Vec4V V4One() +{ + return V4Load(1.0f); +} + +PX_FORCE_INLINE Vec4V V4Eps() +{ + return V4Load(PX_EPS_REAL); +} + +PX_FORCE_INLINE Vec4V V4Neg(const Vec4V c) +{ + return Vec4V(-c.x, -c.y, -c.z, -c.w); +} + +PX_FORCE_INLINE Vec4V V4Add(const Vec4V a, const Vec4V b) +{ + return Vec4V(a.x + b.x, a.y + b.y, a.z + b.z, a.w + b.w); +} + +PX_FORCE_INLINE Vec4V V4Sub(const Vec4V a, const Vec4V b) +{ + return Vec4V(a.x - b.x, a.y - b.y, a.z - b.z, a.w - b.w); +} + +PX_FORCE_INLINE Vec4V V4Scale(const Vec4V a, const FloatV b) +{ + return Vec4V(a.x * b.x, a.y * b.x, a.z * b.x, a.w * b.x); +} + +PX_FORCE_INLINE Vec4V V4Mul(const Vec4V a, const Vec4V b) +{ + return Vec4V(a.x * b.x, a.y * b.y, a.z * b.z, a.w * b.w); +} + +PX_FORCE_INLINE Vec4V V4ScaleInv(const Vec4V a, const FloatV b) +{ + const PxF32 bInv = 1.0f / b.x; + return Vec4V(a.x * bInv, a.y * bInv, a.z * bInv, a.w * bInv); +} + +PX_FORCE_INLINE Vec4V V4Div(const Vec4V a, const Vec4V b) +{ + VECMATHAOS_ASSERT(b.x != 0 && b.y != 0 && b.z != 0 && b.w != 0); + return Vec4V(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w); +} + +PX_FORCE_INLINE Vec4V V4ScaleInvFast(const Vec4V a, const FloatV b) +{ + const PxF32 bInv = 1.0f / b.x; + return Vec4V(a.x * bInv, a.y * bInv, a.z * bInv, a.w * bInv); +} + +PX_FORCE_INLINE Vec4V V4DivFast(const Vec4V a, const Vec4V b) +{ + return Vec4V(a.x / b.x, a.y / b.y, a.z / b.z, a.w / b.w); +} + +PX_FORCE_INLINE Vec4V V4Recip(const Vec4V a) +{ + return Vec4V(1.0f / a.x, 1.0f / a.y, 1.0f / a.z, 1.0f / a.w); +} + +PX_FORCE_INLINE Vec4V V4RecipFast(const Vec4V a) +{ + return Vec4V(1.0f / a.x, 1.0f / a.y, 1.0f / a.z, 1.0f / a.w); +} + +PX_FORCE_INLINE Vec4V V4Rsqrt(const Vec4V a) +{ + return Vec4V(PxRecipSqrt(a.x), PxRecipSqrt(a.y), PxRecipSqrt(a.z), PxRecipSqrt(a.w)); +} + +PX_FORCE_INLINE Vec4V V4RsqrtFast(const Vec4V a) +{ + return Vec4V(PxRecipSqrt(a.x), PxRecipSqrt(a.y), PxRecipSqrt(a.z), PxRecipSqrt(a.w)); +} + +PX_FORCE_INLINE Vec4V V4Sqrt(const Vec4V a) +{ + return Vec4V(PxSqrt(a.x), PxSqrt(a.y), PxSqrt(a.z), PxSqrt(a.w)); +} + +PX_FORCE_INLINE Vec4V V4ScaleAdd(const Vec4V a, const FloatV b, const Vec4V c) +{ + return V4Add(V4Scale(a, b), c); +} + +PX_FORCE_INLINE Vec4V V4NegScaleSub(const Vec4V a, const FloatV b, const Vec4V c) +{ + return V4Sub(c, V4Scale(a, b)); +} + +PX_FORCE_INLINE Vec4V V4MulAdd(const Vec4V a, const Vec4V b, const Vec4V c) +{ + return V4Add(V4Mul(a, b), c); +} + +PX_FORCE_INLINE Vec4V V4NegMulSub(const Vec4V a, const Vec4V b, const Vec4V c) +{ + return V4Sub(c, V4Mul(a, b)); +} + +PX_FORCE_INLINE FloatV V4SumElements(const Vec4V a) +{ + return FloatV(a.x + a.y + a.z + a.w); +} + +PX_FORCE_INLINE FloatV V4Dot(const Vec4V a, const Vec4V b) +{ + return FloatV(a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w); +} + +PX_FORCE_INLINE FloatV V4Dot3(const Vec4V a, const Vec4V b) +{ + return FloatV(a.x * b.x + a.y * b.y + a.z * b.z); +} + +PX_FORCE_INLINE Vec4V V4Cross(const Vec4V a, const Vec4V b) +{ + return Vec4V(a.y * b.z - a.z * b.y, a.z * b.x - a.x * b.z, a.x * b.y - a.y * b.x, 0.0f); +} + +PX_FORCE_INLINE FloatV V4Length(const Vec4V a) +{ + return FloatV(PxSqrt(a.x * a.x + a.y * a.y + a.z * a.z + a.w * a.w)); +} + +PX_FORCE_INLINE FloatV V4LengthSq(const Vec4V a) +{ + return V4Dot(a, a); +} + +PX_FORCE_INLINE Vec4V V4Normalize(const Vec4V a) +{ + VECMATHAOS_ASSERT(0 != a.x || 0 != a.y || 0 != a.z || 0 != a.w); + const FloatV length = FloatV(V4Length(a)); + return V4ScaleInv(a, length); +} + +PX_FORCE_INLINE Vec4V V4NormalizeSafe(const Vec4V a, const Vec4V unsafeReturnValue) +{ + const FloatV length = FloatV(V4Length(a)); + if(PX_EPS_REAL >= length.x) + { + return unsafeReturnValue; + } + else + { + return V4ScaleInv(a, length); + } +} +PX_FORCE_INLINE Vec4V V4NormalizeFast(const Vec4V a) +{ + VECMATHAOS_ASSERT(0 != a.x || 0 != a.y || 0 != a.z || 0 != a.w); + const FloatV length = FloatV(V4Length(a)); + return V4ScaleInv(a, length); +} + +PX_FORCE_INLINE Vec4V V4Sel(const BoolV c, const Vec4V a, const Vec4V b) +{ + return Vec4V(c.ux ? a.x : b.x, c.uy ? a.y : b.y, c.uz ? a.z : b.z, c.uw ? a.w : b.w); +} + +PX_FORCE_INLINE BoolV V4IsGrtr(const Vec4V a, const Vec4V b) +{ + return BoolV(BOOL_TO_U32(a.x > b.x), BOOL_TO_U32(a.y > b.y), BOOL_TO_U32(a.z > b.z), BOOL_TO_U32(a.w > b.w)); +} + +PX_FORCE_INLINE BoolV V4IsGrtrOrEq(const Vec4V a, const Vec4V b) +{ + return BoolV(BOOL_TO_U32(a.x >= b.x), BOOL_TO_U32(a.y >= b.y), BOOL_TO_U32(a.z >= b.z), BOOL_TO_U32(a.w >= b.w)); +} + +PX_FORCE_INLINE BoolV V4IsEq(const Vec4V a, const Vec4V b) +{ + return BoolV(BOOL_TO_U32(a.x == b.x), BOOL_TO_U32(a.y == b.y), BOOL_TO_U32(a.z == b.z), BOOL_TO_U32(a.w == b.w)); +} + +PX_FORCE_INLINE Vec4V V4Max(const Vec4V a, const Vec4V b) +{ + return Vec4V(a.x > b.x ? a.x : b.x, a.y > b.y ? a.y : b.y, a.z > b.z ? a.z : b.z, a.w > b.w ? a.w : b.w); +} + +PX_FORCE_INLINE Vec4V V4Min(const Vec4V a, const Vec4V b) +{ + return Vec4V(a.x < b.x ? a.x : b.x, a.y < b.y ? a.y : b.y, a.z < b.z ? a.z : b.z, a.w < b.w ? a.w : b.w); +} + +PX_FORCE_INLINE FloatV V4ExtractMax(const Vec4V a) +{ + const PxF32 t0 = (a.x >= a.y) ? a.x : a.y; + const PxF32 t1 = (a.z >= a.w) ? a.x : a.w; + return t0 >= t1 ? t0 : t1; +} + +PX_FORCE_INLINE FloatV V4ExtractMin(const Vec4V a) +{ + const PxF32 t0 = (a.x <= a.y) ? a.x : a.y; + const PxF32 t1 = (a.z <= a.w) ? a.x : a.w; + return t0 <= t1 ? t0 : t1; +} + +PX_FORCE_INLINE Vec4V V4Clamp(const Vec4V a, const Vec4V minV, const Vec4V maxV) +{ + return V4Max(V4Min(a, maxV), minV); +} + +PX_FORCE_INLINE Vec4V V4Round(const Vec4V a) +{ + return Vec4V(floorf(a.x + 0.5f), floorf(a.y + 0.5f), floorf(a.z + 0.5f), floorf(a.w + 0.5f)); +} + +PX_FORCE_INLINE Vec4V V4Sin(const Vec4V a) +{ + return Vec4V(sinf(a.x), sinf(a.y), sinf(a.z), sinf(a.w)); +} + +PX_FORCE_INLINE Vec4V V4Cos(const Vec4V a) +{ + return Vec4V(cosf(a.x), cosf(a.y), cosf(a.z), cosf(a.w)); +} + +PX_FORCE_INLINE PxU32 V4AllGrtr(const Vec4V a, const Vec4V b) +{ + return BOOL_TO_U32((a.x > b.x) & (a.y > b.y) & (a.z > b.z) & (a.w > b.w)); +} + +PX_FORCE_INLINE PxU32 V4AllGrtrOrEq(const Vec4V a, const Vec4V b) +{ + return BOOL_TO_U32((a.x >= b.x) & (a.y >= b.y) & (a.z >= b.z) & (a.w >= b.w)); +} + +PX_FORCE_INLINE PxU32 V4AllGrtrOrEq3(const Vec4V a, const Vec4V b) +{ + return BOOL_TO_U32((a.x >= b.x) & (a.y >= b.y) & (a.z >= b.z)); +} + +PX_FORCE_INLINE PxU32 V4AllEq(const Vec4V a, const Vec4V b) +{ + return BOOL_TO_U32((a.x == b.x) & (a.y == b.y) & (a.z == b.z) & (a.w == b.w)); +} + +PX_FORCE_INLINE PxU32 V4AnyGrtr3(const Vec4V a, const Vec4V b) +{ + return BOOL_TO_U32((a.x > b.x) | (a.y > b.y) | (a.z > b.z)); +} + +PX_FORCE_INLINE void V4Transpose(Vec4V& col0, Vec4V& col1, Vec4V& col2, Vec4V& col3) +{ + const PxF32 t01 = col0.y, t02 = col0.z, t03 = col0.w; + const PxF32 t12 = col1.z, t13 = col1.w; + const PxF32 t23 = col2.w; + col0.y = col1.x; + col0.z = col2.x; + col0.w = col3.x; + col1.z = col2.y; + col1.w = col3.y; + col2.w = col3.z; + col1.x = t01; + col2.x = t02; + col3.x = t03; + col2.y = t12; + col3.y = t13; + col3.z = t23; +} + +PX_FORCE_INLINE BoolV BFFFF() +{ + return BoolV(FALSE_TO_U32, FALSE_TO_U32, FALSE_TO_U32, FALSE_TO_U32); +} +PX_FORCE_INLINE BoolV BFFFT() +{ + return BoolV(FALSE_TO_U32, FALSE_TO_U32, FALSE_TO_U32, TRUE_TO_U32); +} +PX_FORCE_INLINE BoolV BFFTF() +{ + return BoolV(FALSE_TO_U32, FALSE_TO_U32, TRUE_TO_U32, FALSE_TO_U32); +} +PX_FORCE_INLINE BoolV BFFTT() +{ + return BoolV(FALSE_TO_U32, FALSE_TO_U32, TRUE_TO_U32, TRUE_TO_U32); +} +PX_FORCE_INLINE BoolV BFTFF() +{ + return BoolV(FALSE_TO_U32, TRUE_TO_U32, FALSE_TO_U32, FALSE_TO_U32); +} +PX_FORCE_INLINE BoolV BFTFT() +{ + return BoolV(FALSE_TO_U32, TRUE_TO_U32, FALSE_TO_U32, TRUE_TO_U32); +} +PX_FORCE_INLINE BoolV BFTTF() +{ + return BoolV(FALSE_TO_U32, TRUE_TO_U32, TRUE_TO_U32, FALSE_TO_U32); +} +PX_FORCE_INLINE BoolV BFTTT() +{ + return BoolV(FALSE_TO_U32, TRUE_TO_U32, TRUE_TO_U32, TRUE_TO_U32); +} +PX_FORCE_INLINE BoolV BTFFF() +{ + return BoolV(TRUE_TO_U32, FALSE_TO_U32, FALSE_TO_U32, FALSE_TO_U32); +} +PX_FORCE_INLINE BoolV BTFFT() +{ + return BoolV(TRUE_TO_U32, FALSE_TO_U32, FALSE_TO_U32, TRUE_TO_U32); +} +PX_FORCE_INLINE BoolV BTFTF() +{ + return BoolV(TRUE_TO_U32, FALSE_TO_U32, TRUE_TO_U32, FALSE_TO_U32); +} +PX_FORCE_INLINE BoolV BTFTT() +{ + return BoolV(TRUE_TO_U32, FALSE_TO_U32, TRUE_TO_U32, TRUE_TO_U32); +} +PX_FORCE_INLINE BoolV BTTFF() +{ + return BoolV(TRUE_TO_U32, TRUE_TO_U32, FALSE_TO_U32, FALSE_TO_U32); +} +PX_FORCE_INLINE BoolV BTTFT() +{ + return BoolV(TRUE_TO_U32, TRUE_TO_U32, FALSE_TO_U32, TRUE_TO_U32); +} +PX_FORCE_INLINE BoolV BTTTF() +{ + return BoolV(TRUE_TO_U32, TRUE_TO_U32, TRUE_TO_U32, FALSE_TO_U32); +} +PX_FORCE_INLINE BoolV BTTTT() +{ + return BoolV(TRUE_TO_U32, TRUE_TO_U32, TRUE_TO_U32, TRUE_TO_U32); +} + +PX_FORCE_INLINE BoolV BXMask() +{ + return BTFFF(); +} +PX_FORCE_INLINE BoolV BYMask() +{ + return BFTFF(); +} +PX_FORCE_INLINE BoolV BZMask() +{ + return BFFTF(); +} +PX_FORCE_INLINE BoolV BWMask() +{ + return BFFFT(); +} + +PX_FORCE_INLINE BoolV BGetX(const BoolV a) +{ + return BoolV(a.ux, a.ux, a.ux, a.ux); +} + +PX_FORCE_INLINE BoolV BGetY(const BoolV a) +{ + return BoolV(a.uy, a.uy, a.uy, a.uy); +} + +PX_FORCE_INLINE BoolV BGetZ(const BoolV a) +{ + return BoolV(a.uz, a.uz, a.uz, a.uz); +} + +PX_FORCE_INLINE BoolV BGetW(const BoolV a) +{ + return BoolV(a.uw, a.uw, a.uw, a.uw); +} + +PX_FORCE_INLINE BoolV BSetX(const BoolV v, const BoolV f) +{ + return BoolV(f.ux, v.uy, v.uz, v.uw); +} + +PX_FORCE_INLINE BoolV BSetY(const BoolV v, const BoolV f) +{ + return BoolV(v.ux, f.uy, v.uz, v.uw); +} + +PX_FORCE_INLINE BoolV BSetZ(const BoolV v, const BoolV f) +{ + return BoolV(v.ux, v.uy, f.uz, v.uw); +} + +PX_FORCE_INLINE BoolV BSetW(const BoolV v, const BoolV f) +{ + return BoolV(v.ux, v.uy, v.uz, f.uw); +} + +template +BoolV BSplatElement(BoolV a) +{ + PxU32* b = reinterpret_cast(&a); + return BoolV(b[index], b[index], b[index], b[index]); +} + +PX_FORCE_INLINE BoolV BAnd(const BoolV a, const BoolV b) +{ + return BoolV(BOOL_TO_U32(a.ux && b.ux), BOOL_TO_U32(a.uy && b.uy), BOOL_TO_U32(a.uz && b.uz), BOOL_TO_U32(a.uw && b.uw)); +} + +PX_FORCE_INLINE BoolV BAndNot(const BoolV a, const BoolV b) +{ + return BoolV(a.ux & ~b.ux, a.uy & ~b.uy, a.uz & ~b.uz, a.uw & ~b.uw); +} + +PX_FORCE_INLINE BoolV BNot(const BoolV a) +{ + return BoolV(~a.ux, ~a.uy, ~a.uz, ~a.uw); +} + +PX_FORCE_INLINE BoolV BOr(const BoolV a, const BoolV b) +{ + return BoolV(BOOL_TO_U32(a.ux || b.ux), BOOL_TO_U32(a.uy || b.uy), BOOL_TO_U32(a.uz || b.uz), BOOL_TO_U32(a.uw || b.uw)); +} + +PX_FORCE_INLINE PxU32 BAllEq(const BoolV a, const BoolV b) +{ + return (a.ux == b.ux && a.uy == b.uy && a.uz == b.uz && a.uw == b.uw ? 1 : 0); +} + +PX_FORCE_INLINE PxU32 BAllEqTTTT(const BoolV a) +{ + return BAllEq(a, BTTTT()); +} + +PX_FORCE_INLINE PxU32 BAllEqFFFF(const BoolV a) +{ + return BAllEq(a, BFFFF()); +} + +PX_FORCE_INLINE BoolV BAllTrue4(const BoolV a) +{ + return (a.ux & a.uy & a.uz & a.uw) ? BTTTT() : BFFFF(); +} + +PX_FORCE_INLINE BoolV BAnyTrue4(const BoolV a) +{ + return (a.ux | a.uy | a.uz | a.uw) ? BTTTT() : BFFFF(); +} + +PX_FORCE_INLINE BoolV BAllTrue3(const BoolV a) +{ + return (a.ux & a.uy & a.uz) ? BTTTT() : BFFFF(); +} + +PX_FORCE_INLINE BoolV BAnyTrue3(const BoolV a) +{ + return (a.ux | a.uy | a.uz) ? BTTTT() : BFFFF(); +} + +PX_FORCE_INLINE PxU32 BGetBitMask(const BoolV a) +{ + return (a.ux & 1) | (a.uy & 2) | (a.uz & 4) | (a.uw & 8); +} + +////////////////////////////////// +// MAT33V +////////////////////////////////// + +PX_FORCE_INLINE Vec3V M33MulV3(const Mat33V& a, const Vec3V b) +{ + return Vec3V(a.col0.x * b.x + a.col1.x * b.y + a.col2.x * b.z, a.col0.y * b.x + a.col1.y * b.y + a.col2.y * b.z, + a.col0.z * b.x + a.col1.z * b.y + a.col2.z * b.z); +} + +PX_FORCE_INLINE Vec3V M33TrnspsMulV3(const Mat33V& a, const Vec3V b) +{ + return Vec3V(a.col0.x * b.x + a.col0.y * b.y + a.col0.z * b.z, a.col1.x * b.x + a.col1.y * b.y + a.col1.z * b.z, + a.col2.x * b.x + a.col2.y * b.y + a.col2.z * b.z); +} + +PX_FORCE_INLINE Vec3V M33MulV3AddV3(const Mat33V& A, const Vec3V b, const Vec3V c) +{ + const FloatV x = V3GetX(b); + const FloatV y = V3GetY(b); + const FloatV z = V3GetZ(b); + Vec3V result = V3ScaleAdd(A.col0, x, c); + result = V3ScaleAdd(A.col1, y, result); + return V3ScaleAdd(A.col2, z, result); +} + +PX_FORCE_INLINE Mat33V M33MulM33(const Mat33V& a, const Mat33V& b) +{ + return Mat33V(M33MulV3(a, b.col0), M33MulV3(a, b.col1), M33MulV3(a, b.col2)); +} + +PX_FORCE_INLINE Mat33V M33Add(const Mat33V& a, const Mat33V& b) +{ + return Mat33V(V3Add(a.col0, b.col0), V3Add(a.col1, b.col1), V3Add(a.col2, b.col2)); +} + +PX_FORCE_INLINE Mat33V M33Scale(const Mat33V& a, const FloatV& b) +{ + return Mat33V(V3Scale(a.col0, b), V3Scale(a.col1, b), V3Scale(a.col2, b)); +} + +PX_FORCE_INLINE Mat33V M33Sub(const Mat33V& a, const Mat33V& b) +{ + return Mat33V(V3Sub(a.col0, b.col0), V3Sub(a.col1, b.col1), V3Sub(a.col2, b.col2)); +} + +PX_FORCE_INLINE Mat33V M33Neg(const Mat33V& a) +{ + return Mat33V(V3Neg(a.col0), V3Neg(a.col1), V3Neg(a.col2)); +} + +PX_FORCE_INLINE Mat33V M33Abs(const Mat33V& a) +{ + return Mat33V(V3Abs(a.col0), V3Abs(a.col1), V3Abs(a.col2)); +} + +PX_FORCE_INLINE Mat33V M33Diagonal(const Vec3VArg d) +{ + const Vec3V x = V3Mul(V3UnitX(), d); + const Vec3V y = V3Mul(V3UnitY(), d); + const Vec3V z = V3Mul(V3UnitZ(), d); + return Mat33V(x, y, z); +} + +PX_FORCE_INLINE Mat33V M33Inverse(const Mat33V& a) +{ + const PxF32 det = a.col0.x * (a.col1.y * a.col2.z - a.col1.z * a.col2.y) - + a.col1.x * (a.col0.y * a.col2.z - a.col2.y * a.col0.z) + + a.col2.x * (a.col0.y * a.col1.z - a.col1.y * a.col0.z); + + const PxF32 invDet = 1.0f / det; + + Mat33V ret; + ret.col0.x = invDet * (a.col1.y * a.col2.z - a.col2.y * a.col1.z); + ret.col0.y = invDet * (a.col2.y * a.col0.z - a.col0.y * a.col2.z); + ret.col0.z = invDet * (a.col0.y * a.col1.z - a.col1.y * a.col0.z); + + ret.col1.x = invDet * (a.col2.x * a.col1.z - a.col1.x * a.col2.z); + ret.col1.y = invDet * (a.col0.x * a.col2.z - a.col2.x * a.col0.z); + ret.col1.z = invDet * (a.col1.x * a.col0.z - a.col0.x * a.col1.z); + + ret.col2.x = invDet * (a.col1.x * a.col2.y - a.col2.x * a.col1.y); + ret.col2.y = invDet * (a.col2.x * a.col0.y - a.col0.x * a.col2.y); + ret.col2.z = invDet * (a.col0.x * a.col1.y - a.col1.x * a.col0.y); + + return ret; +} + +PX_FORCE_INLINE Mat33V Mat33V_From_PxMat33(const PxMat33& m) +{ + return Mat33V(V3LoadU(m.column0), V3LoadU(m.column1), V3LoadU(m.column2)); +} + +PX_FORCE_INLINE void PxMat33_From_Mat33V(const Mat33V& m, PxMat33& out) +{ + PX_ASSERT((size_t(&out) & 15) == 0); + V3StoreU(m.col0, out.column0); + V3StoreU(m.col1, out.column1); + V3StoreU(m.col2, out.column2); +} + +PX_FORCE_INLINE Mat33V M33Trnsps(const Mat33V& a) +{ + return Mat33V(Vec3V(a.col0.x, a.col1.x, a.col2.x), Vec3V(a.col0.y, a.col1.y, a.col2.y), + Vec3V(a.col0.z, a.col1.z, a.col2.z)); +} + +PX_FORCE_INLINE Mat33V M33Identity() +{ + return Mat33V(V3UnitX(), V3UnitY(), V3UnitZ()); +} + +////////////////////////////////// +// MAT34V +////////////////////////////////// + +PX_FORCE_INLINE Vec3V M34MulV3(const Mat34V& a, const Vec3V b) +{ + return Vec3V(a.col0.x * b.x + a.col1.x * b.y + a.col2.x * b.z + a.col3.x, + a.col0.y * b.x + a.col1.y * b.y + a.col2.y * b.z + a.col3.y, + a.col0.z * b.x + a.col1.z * b.y + a.col2.z * b.z + a.col3.z); +} + +PX_FORCE_INLINE Vec3V M34Mul33V3(const Mat34V& a, const Vec3V b) +{ + return Vec3V(a.col0.x * b.x + a.col1.x * b.y + a.col2.x * b.z, a.col0.y * b.x + a.col1.y * b.y + a.col2.y * b.z, + a.col0.z * b.x + a.col1.z * b.y + a.col2.z * b.z); +} + +PX_FORCE_INLINE Vec3V M34TrnspsMul33V3(const Mat34V& a, const Vec3V b) +{ + return Vec3V(a.col0.x * b.x + a.col0.y * b.y + a.col0.z * b.z, a.col1.x * b.x + a.col1.y * b.y + a.col1.z * b.z, + a.col2.x * b.x + a.col2.y * b.y + a.col2.z * b.z); +} + +PX_FORCE_INLINE Mat34V M34MulM34(const Mat34V& a, const Mat34V& b) +{ + return Mat34V(M34Mul33V3(a, b.col0), M34Mul33V3(a, b.col1), M34Mul33V3(a, b.col2), M34MulV3(a, b.col3)); +} + +PX_FORCE_INLINE Mat33V M34MulM33(const Mat34V& a, const Mat33V& b) +{ + return Mat33V(M34Mul33V3(a, b.col0), M34Mul33V3(a, b.col1), M34Mul33V3(a, b.col2)); +} + +PX_FORCE_INLINE Mat33V M34Mul33V3(const Mat34V& a, const Mat33V& b) +{ + return Mat33V(M34Mul33V3(a, b.col0), M34Mul33V3(a, b.col1), M34Mul33V3(a, b.col2)); +} + +PX_FORCE_INLINE Mat33V M34Mul33MM34(const Mat34V& a, const Mat34V& b) +{ + return Mat33V(M34Mul33V3(a, b.col0), M34Mul33V3(a, b.col1), M34Mul33V3(a, b.col2)); +} + +PX_FORCE_INLINE Mat34V M34Add(const Mat34V& a, const Mat34V& b) +{ + return Mat34V(V3Add(a.col0, b.col0), V3Add(a.col1, b.col1), V3Add(a.col2, b.col2), V3Add(a.col3, b.col3)); +} + +PX_FORCE_INLINE Mat33V M34Trnsps33(const Mat34V& a) +{ + return Mat33V(Vec3V(a.col0.x, a.col1.x, a.col2.x), Vec3V(a.col0.y, a.col1.y, a.col2.y), + Vec3V(a.col0.z, a.col1.z, a.col2.z)); +} + +////////////////////////////////// +// MAT44V +////////////////////////////////// + +PX_FORCE_INLINE Vec4V M44MulV4(const Mat44V& a, const Vec4V b) +{ + return Vec4V(a.col0.x * b.x + a.col1.x * b.y + a.col2.x * b.z + a.col3.x * b.w, + a.col0.y * b.x + a.col1.y * b.y + a.col2.y * b.z + a.col3.y * b.w, + a.col0.z * b.x + a.col1.z * b.y + a.col2.z * b.z + a.col3.z * b.w, + a.col0.w * b.x + a.col1.w * b.y + a.col2.w * b.z + a.col3.w * b.w); +} + +PX_FORCE_INLINE Vec4V M44TrnspsMulV4(const Mat44V& a, const Vec4V b) +{ + return Vec4V(a.col0.x * b.x + a.col0.y * b.y + a.col0.z * b.z + a.col0.w * b.w, + a.col1.x * b.x + a.col1.y * b.y + a.col1.z * b.z + a.col1.w * b.w, + a.col2.x * b.x + a.col2.y * b.y + a.col2.z * b.z + a.col2.w * b.w, + a.col3.x * b.x + a.col3.y * b.y + a.col3.z * b.z + a.col3.w * b.w); +} + +PX_FORCE_INLINE Mat44V M44MulM44(const Mat44V& a, const Mat44V& b) +{ + return Mat44V(M44MulV4(a, b.col0), M44MulV4(a, b.col1), M44MulV4(a, b.col2), M44MulV4(a, b.col3)); +} + +PX_FORCE_INLINE Mat44V M44Add(const Mat44V& a, const Mat44V& b) +{ + return Mat44V(V4Add(a.col0, b.col0), V4Add(a.col1, b.col1), V4Add(a.col2, b.col2), V4Add(a.col3, b.col3)); +} + +PX_FORCE_INLINE Mat44V M44Inverse(const Mat44V& a) +{ + PxF32 tmp[12]; + PxF32 dst[16]; + PxF32 det; + + const PxF32 src[16] = { a.col0.x, a.col0.y, a.col0.z, a.col0.w, a.col1.x, a.col1.y, a.col1.z, a.col1.w, + a.col2.x, a.col2.y, a.col2.z, a.col2.w, a.col3.x, a.col3.y, a.col3.z, a.col3.w }; + + tmp[0] = src[10] * src[15]; + tmp[1] = src[11] * src[14]; + tmp[2] = src[9] * src[15]; + tmp[3] = src[11] * src[13]; + tmp[4] = src[9] * src[14]; + tmp[5] = src[10] * src[13]; + tmp[6] = src[8] * src[15]; + tmp[7] = src[11] * src[12]; + tmp[8] = src[8] * src[14]; + tmp[9] = src[10] * src[12]; + tmp[10] = src[8] * src[13]; + tmp[11] = src[9] * src[12]; + + dst[0] = tmp[0] * src[5] + tmp[3] * src[6] + tmp[4] * src[7]; + dst[0] -= tmp[1] * src[5] + tmp[2] * src[6] + tmp[5] * src[7]; + dst[1] = tmp[1] * src[4] + tmp[6] * src[6] + tmp[9] * src[7]; + dst[1] -= tmp[0] * src[4] + tmp[7] * src[6] + tmp[8] * src[7]; + dst[2] = tmp[2] * src[4] + tmp[7] * src[5] + tmp[10] * src[7]; + dst[2] -= tmp[3] * src[4] + tmp[6] * src[5] + tmp[11] * src[7]; + dst[3] = tmp[5] * src[4] + tmp[8] * src[5] + tmp[11] * src[6]; + dst[3] -= tmp[4] * src[4] + tmp[9] * src[5] + tmp[10] * src[6]; + dst[4] = tmp[1] * src[1] + tmp[2] * src[2] + tmp[5] * src[3]; + dst[4] -= tmp[0] * src[1] + tmp[3] * src[2] + tmp[4] * src[3]; + dst[5] = tmp[0] * src[0] + tmp[7] * src[2] + tmp[8] * src[3]; + dst[5] -= tmp[1] * src[0] + tmp[6] * src[2] + tmp[9] * src[3]; + dst[6] = tmp[3] * src[0] + tmp[6] * src[1] + tmp[11] * src[3]; + dst[6] -= tmp[2] * src[0] + tmp[7] * src[1] + tmp[10] * src[3]; + dst[7] = tmp[4] * src[0] + tmp[9] * src[1] + tmp[10] * src[2]; + dst[7] -= tmp[5] * src[0] + tmp[8] * src[1] + tmp[11] * src[2]; + + tmp[0] = src[2] * src[7]; + tmp[1] = src[3] * src[6]; + tmp[2] = src[1] * src[7]; + tmp[3] = src[3] * src[5]; + tmp[4] = src[1] * src[6]; + tmp[5] = src[2] * src[5]; + tmp[6] = src[0] * src[7]; + tmp[7] = src[3] * src[4]; + tmp[8] = src[0] * src[6]; + tmp[9] = src[2] * src[4]; + tmp[10] = src[0] * src[5]; + tmp[11] = src[1] * src[4]; + + dst[8] = tmp[0] * src[13] + tmp[3] * src[14] + tmp[4] * src[15]; + dst[8] -= tmp[1] * src[13] + tmp[2] * src[14] + tmp[5] * src[15]; + dst[9] = tmp[1] * src[12] + tmp[6] * src[14] + tmp[9] * src[15]; + dst[9] -= tmp[0] * src[12] + tmp[7] * src[14] + tmp[8] * src[15]; + dst[10] = tmp[2] * src[12] + tmp[7] * src[13] + tmp[10] * src[15]; + dst[10] -= tmp[3] * src[12] + tmp[6] * src[13] + tmp[11] * src[15]; + dst[11] = tmp[5] * src[12] + tmp[8] * src[13] + tmp[11] * src[14]; + dst[11] -= tmp[4] * src[12] + tmp[9] * src[13] + tmp[10] * src[14]; + dst[12] = tmp[2] * src[10] + tmp[5] * src[11] + tmp[1] * src[9]; + dst[12] -= tmp[4] * src[11] + tmp[0] * src[9] + tmp[3] * src[10]; + dst[13] = tmp[8] * src[11] + tmp[0] * src[8] + tmp[7] * src[10]; + dst[13] -= tmp[6] * src[10] + tmp[9] * src[11] + tmp[1] * src[8]; + dst[14] = tmp[6] * src[9] + tmp[11] * src[11] + tmp[3] * src[8]; + dst[14] -= tmp[10] * src[11] + tmp[2] * src[8] + tmp[7] * src[9]; + dst[15] = tmp[10] * src[10] + tmp[4] * src[8] + tmp[9] * src[9]; + dst[15] -= tmp[8] * src[9] + tmp[11] * src[10] + tmp[5] * src[8]; + + det = src[0] * dst[0] + src[1] * dst[1] + src[2] * dst[2] + src[3] * dst[3]; + + det = 1.0f / det; + for(PxU32 j = 0; j < 16; j++) + { + dst[j] *= det; + } + + return Mat44V(Vec4V(dst[0], dst[4], dst[8], dst[12]), Vec4V(dst[1], dst[5], dst[9], dst[13]), + Vec4V(dst[2], dst[6], dst[10], dst[14]), Vec4V(dst[3], dst[7], dst[11], dst[15])); +} + +PX_FORCE_INLINE Mat44V M44Trnsps(const Mat44V& a) +{ + return Mat44V(Vec4V(a.col0.x, a.col1.x, a.col2.x, a.col3.x), Vec4V(a.col0.y, a.col1.y, a.col2.y, a.col3.y), + Vec4V(a.col0.z, a.col1.z, a.col2.z, a.col3.z), Vec4V(a.col0.w, a.col1.w, a.col2.w, a.col3.w)); +} + +PX_FORCE_INLINE Vec4V V4LoadXYZW(const PxF32& x, const PxF32& y, const PxF32& z, const PxF32& w) +{ + return Vec4V(x, y, z, w); +} + +/* +PX_FORCE_INLINE VecU16V V4U32PK(VecU32V a, VecU32V b) +{ + return VecU16V( + PxU16(PxClamp((a).u32[0], 0, 0xFFFF)), + PxU16(PxClamp((a).u32[1], 0, 0xFFFF)), + PxU16(PxClamp((a).u32[2], 0, 0xFFFF)), + PxU16(PxClamp((a).u32[3], 0, 0xFFFF)), + PxU16(PxClamp((b).u32[0], 0, 0xFFFF)), + PxU16(PxClamp((b).u32[1], 0, 0xFFFF)), + PxU16(PxClamp((b).u32[2], 0, 0xFFFF)), + PxU16(PxClamp((b).u32[3], 0, 0xFFFF))); +} +*/ + +PX_FORCE_INLINE VecU32V V4U32Sel(const BoolV c, const VecU32V a, const VecU32V b) +{ + return VecU32V(c.ux ? a.u32[0] : b.u32[0], c.uy ? a.u32[1] : b.u32[1], c.uz ? a.u32[2] : b.u32[2], + c.uw ? a.u32[3] : b.u32[3]); +} + +PX_FORCE_INLINE VecU32V V4U32or(VecU32V a, VecU32V b) +{ + return VecU32V((a).u32[0] | (b).u32[0], (a).u32[1] | (b).u32[1], (a).u32[2] | (b).u32[2], (a).u32[3] | (b).u32[3]); +} + +PX_FORCE_INLINE VecU32V V4U32xor(VecU32V a, VecU32V b) +{ + return VecU32V((a).u32[0] ^ (b).u32[0], (a).u32[1] ^ (b).u32[1], (a).u32[2] ^ (b).u32[2], (a).u32[3] ^ (b).u32[3]); +} + +PX_FORCE_INLINE VecU32V V4U32and(VecU32V a, VecU32V b) +{ + return VecU32V((a).u32[0] & (b).u32[0], (a).u32[1] & (b).u32[1], (a).u32[2] & (b).u32[2], (a).u32[3] & (b).u32[3]); +} + +PX_FORCE_INLINE VecU32V V4U32Andc(VecU32V a, VecU32V b) +{ + return VecU32V((a).u32[0] & ~(b).u32[0], (a).u32[1] & ~(b).u32[1], (a).u32[2] & ~(b).u32[2], + (a).u32[3] & ~(b).u32[3]); +} + +/* +PX_FORCE_INLINE VecU16V V4U16Or(VecU16V a, VecU16V b) +{ + return VecU16V( + (a).u16[0]|(b).u16[0], (a).u16[1]|(b).u16[1], (a).u16[2]|(b).u16[2], (a).u16[3]|(b).u16[3], + (a).u16[4]|(b).u16[4], (a).u16[5]|(b).u16[5], (a).u16[6]|(b).u16[6], (a).u16[7]|(b).u16[7]); +} +*/ + +/* +PX_FORCE_INLINE VecU16V V4U16And(VecU16V a, VecU16V b) +{ + return VecU16V( + (a).u16[0]&(b).u16[0], (a).u16[1]&(b).u16[1], (a).u16[2]&(b).u16[2], (a).u16[3]&(b).u16[3], + (a).u16[4]&(b).u16[4], (a).u16[5]&(b).u16[5], (a).u16[6]&(b).u16[6], (a).u16[7]&(b).u16[7]); +} +*/ + +/* +PX_FORCE_INLINE VecU16V V4U16Andc(VecU16V a, VecU16V b) +{ + return VecU16V( + (a).u16[0]&~(b).u16[0], (a).u16[1]&~(b).u16[1], (a).u16[2]&~(b).u16[2], (a).u16[3]&~(b).u16[3], + (a).u16[4]&~(b).u16[4], (a).u16[5]&~(b).u16[5], (a).u16[6]&~(b).u16[6], (a).u16[7]&~(b).u16[7]); +} +*/ + +/* +template PX_FORCE_INLINE VecI32V V4ISplat() +{ + return VecI32V(a, a, a, a); +} + +template PX_FORCE_INLINE VecU32V V4USplat() +{ + return VecU32V(a, a, a, a); +} +*/ + +/* +PX_FORCE_INLINE void V4U16StoreAligned(VecU16V val, VecU16V* address) +{ + *address = val; +} +*/ + +PX_FORCE_INLINE void V4U32StoreAligned(VecU32V val, VecU32V* address) +{ + *address = val; +} + +PX_FORCE_INLINE Vec4V V4Andc(const Vec4V a, const VecU32V b) +{ + VecU32V r = V4U32Andc(*reinterpret_cast(&a), b); + return (*reinterpret_cast(&r)); +} + +PX_FORCE_INLINE VecU32V V4IsGrtrV32u(const Vec4V a, const Vec4V b) +{ + return VecU32V(a.x > b.x ? 0xFFFFffff : 0, a.y > b.y ? 0xFFFFffff : 0, a.z > b.z ? 0xFFFFffff : 0, + a.w > b.w ? 0xFFFFffff : 0); +} + +PX_FORCE_INLINE VecU16V V4U16LoadAligned(VecU16V* addr) +{ + return *addr; +} + +PX_FORCE_INLINE VecU16V V4U16LoadUnaligned(VecU16V* addr) +{ + return *addr; +} + +PX_FORCE_INLINE VecU16V V4U16CompareGt(VecU16V a, VecU16V b) +{ + return VecU16V + ( + BOOL_TO_U16(a.u16[0] > b.u16[0]), BOOL_TO_U16(a.u16[1] > b.u16[1]), BOOL_TO_U16(a.u16[2] > b.u16[2]), BOOL_TO_U16(a.u16[3] > b.u16[3]), + BOOL_TO_U16(a.u16[4] > b.u16[4]), BOOL_TO_U16(a.u16[5] > b.u16[5]), BOOL_TO_U16(a.u16[6] > b.u16[6]), BOOL_TO_U16(a.u16[7] > b.u16[7]) + ); +} + +PX_FORCE_INLINE VecU16V V4I16CompareGt(VecU16V a, VecU16V b) +{ + return VecU16V + ( + BOOL_TO_U16(a.i16[0] > b.i16[0]), BOOL_TO_U16(a.i16[1] > b.i16[1]), BOOL_TO_U16(a.i16[2] > b.i16[2]), BOOL_TO_U16(a.i16[3] > b.i16[3]), + BOOL_TO_U16(a.i16[4] > b.i16[4]), BOOL_TO_U16(a.i16[5] > b.i16[5]), BOOL_TO_U16(a.i16[6] > b.i16[6]), BOOL_TO_U16(a.i16[7] > b.i16[7]) + ); +} + +PX_FORCE_INLINE Vec4V Vec4V_From_VecU32V(VecU32V a) +{ + return Vec4V(PxF32((a).u32[0]), PxF32((a).u32[1]), PxF32((a).u32[2]), PxF32((a).u32[3])); +} + +PX_FORCE_INLINE Vec4V Vec4V_From_VecI32V(VecI32V a) +{ + return Vec4V(PxF32((a).i32[0]), PxF32((a).i32[1]), PxF32((a).i32[2]), PxF32((a).i32[3])); +} + +PX_FORCE_INLINE VecI32V VecI32V_From_Vec4V(Vec4V a) +{ + float* data = reinterpret_cast(&a); + return VecI32V(PxI32(data[0]), PxI32(data[1]), PxI32(data[2]), PxI32(data[3])); +} + +PX_FORCE_INLINE Vec4V Vec4V_ReinterpretFrom_VecU32V(VecU32V a) +{ + Vec4V b = *reinterpret_cast(&a); + return b; +} + +PX_FORCE_INLINE Vec4V Vec4V_ReinterpretFrom_VecI32V(VecI32V a) +{ + Vec4V b = *reinterpret_cast(&a); + return b; +} + +PX_FORCE_INLINE VecU32V VecU32V_ReinterpretFrom_Vec4V(Vec4V a) +{ + VecU32V b = *reinterpret_cast(&a); + return b; +} + +PX_FORCE_INLINE VecI32V VecI32V_ReinterpretFrom_Vec4V(Vec4V a) +{ + VecI32V b = *reinterpret_cast(&a); + return b; +} + +template +PX_FORCE_INLINE VecU32V V4U32SplatElement(VecU32V a) +{ + return VecU32V((a).u32[index], (a).u32[index], (a).u32[index], (a).u32[index]); +} + +template +PX_FORCE_INLINE VecU32V V4U32SplatElement(BoolV a) +{ + const PxU32 u = (&a.ux)[index]; + return VecU32V(u, u, u, u); +} + +template +PX_FORCE_INLINE Vec4V V4SplatElement(Vec4V a) +{ + float* data = reinterpret_cast(&a); + return Vec4V(data[index], data[index], data[index], data[index]); +} + +PX_FORCE_INLINE VecU32V U4LoadXYZW(PxU32 x, PxU32 y, PxU32 z, PxU32 w) +{ + return VecU32V(x, y, z, w); +} + +PX_FORCE_INLINE Vec4V V4Abs(const Vec4V a) +{ + return V4Max(a, V4Neg(a)); +} + +PX_FORCE_INLINE BoolV V4IsEqU32(const VecU32V a, const VecU32V b) +{ + return BoolV(BOOL_TO_U32(a.u32[0] == b.u32[0]), BOOL_TO_U32(a.u32[1] == b.u32[1]), BOOL_TO_U32(a.u32[2] == b.u32[2]), BOOL_TO_U32(a.u32[3] == b.u32[3])); +} + +PX_FORCE_INLINE VecU32V U4Load(const PxU32 i) +{ + return VecU32V(i, i, i, i); +} + +PX_FORCE_INLINE VecU32V U4LoadU(const PxU32* i) +{ + return VecU32V(i[0], i[1], i[2], i[3]); +} + +PX_FORCE_INLINE VecU32V U4LoadA(const PxU32* i) +{ + return VecU32V(i[0], i[1], i[2], i[3]); +} + +PX_FORCE_INLINE VecI32V I4LoadXYZW(const PxI32& x, const PxI32& y, const PxI32& z, const PxI32& w) +{ + return VecI32V(x, y, z, w); +} + +PX_FORCE_INLINE VecI32V I4Load(const PxI32 i) +{ + return VecI32V(i, i, i, i); +} + +PX_FORCE_INLINE VecI32V I4LoadU(const PxI32* i) +{ + return VecI32V(i[0], i[1], i[2], i[3]); +} + +PX_FORCE_INLINE VecI32V I4LoadA(const PxI32* i) +{ + return VecI32V(i[0], i[1], i[2], i[3]); +} + +PX_FORCE_INLINE VecI32V VecI32V_Add(const VecI32VArg a, const VecI32VArg b) +{ + return VecI32V(a.i32[0] + b.i32[0], a.i32[1] + b.i32[1], a.i32[2] + b.i32[2], a.i32[3] + b.i32[3]); +} + +PX_FORCE_INLINE VecI32V VecI32V_Sub(const VecI32VArg a, const VecI32VArg b) +{ + return VecI32V(a.i32[0] - b.i32[0], a.i32[1] - b.i32[1], a.i32[2] - b.i32[2], a.i32[3] - b.i32[3]); +} + +PX_FORCE_INLINE BoolV VecI32V_IsGrtr(const VecI32VArg a, const VecI32VArg b) +{ + return BoolV(BOOL_TO_U32(a.i32[0] > b.i32[0]), BOOL_TO_U32(a.i32[1] > b.i32[1]), BOOL_TO_U32(a.i32[2] > b.i32[2]), BOOL_TO_U32(a.i32[3] > b.i32[3])); +} + +PX_FORCE_INLINE BoolV VecI32V_IsEq(const VecI32VArg a, const VecI32VArg b) +{ + return BoolV(BOOL_TO_U32(a.i32[0] == b.i32[0]), BOOL_TO_U32(a.i32[1] == b.i32[1]), BOOL_TO_U32(a.i32[2] == b.i32[2]), BOOL_TO_U32(a.i32[3] == b.i32[3])); +} + +PX_FORCE_INLINE VecI32V V4I32Sel(const BoolV c, const VecI32V a, const VecI32V b) +{ + return VecI32V(c.ux ? a.i32[0] : b.i32[0], c.uy ? a.i32[1] : b.i32[1], c.uz ? a.i32[2] : b.i32[2], + c.uw ? a.i32[3] : b.i32[3]); +} + +PX_FORCE_INLINE VecI32V VecI32V_Zero() +{ + return VecI32V(0, 0, 0, 0); +} + +PX_FORCE_INLINE VecI32V VecI32V_One() +{ + return VecI32V(1, 1, 1, 1); +} + +PX_FORCE_INLINE VecI32V VecI32V_Two() +{ + return VecI32V(2, 2, 2, 2); +} + +PX_FORCE_INLINE VecI32V VecI32V_MinusOne() +{ + return VecI32V(-1, -1, -1, -1); +} + +PX_FORCE_INLINE VecU32V U4Zero() +{ + return VecU32V(0, 0, 0, 0); +} + +PX_FORCE_INLINE VecU32V U4One() +{ + return VecU32V(1, 1, 1, 1); +} + +PX_FORCE_INLINE VecU32V U4Two() +{ + return VecU32V(2, 2, 2, 2); +} + +PX_FORCE_INLINE VecShiftV VecI32V_PrepareShift(const VecI32VArg shift) +{ + return shift; +} + +PX_FORCE_INLINE VecI32V VecI32V_LeftShift(const VecI32VArg a, const VecShiftVArg count) +{ + return VecI32V(a.i32[0] << count.i32[0], a.i32[1] << count.i32[1], a.i32[2] << count.i32[2], a.i32[3] + << count.i32[3]); +} + +PX_FORCE_INLINE VecI32V VecI32V_RightShift(const VecI32VArg a, const VecShiftVArg count) +{ + return VecI32V(a.i32[0] >> count.i32[0], a.i32[1] >> count.i32[1], a.i32[2] >> count.i32[2], + a.i32[3] >> count.i32[3]); +} + +PX_FORCE_INLINE VecI32V VecI32V_LeftShift(const VecI32VArg a, const PxU32 count) +{ + return VecI32V(a.i32[0] << count, a.i32[1] << count, a.i32[2] << count, a.i32[3] << count); +} + +PX_FORCE_INLINE VecI32V VecI32V_RightShift(const VecI32VArg a, const PxU32 count) +{ + return VecI32V(a.i32[0] >> count, a.i32[1] >> count, a.i32[2] >> count, a.i32[3] >> count); +} + +PX_FORCE_INLINE VecI32V VecI32V_And(const VecI32VArg a, const VecI32VArg b) +{ + return VecI32V(a.i32[0] & b.i32[0], a.i32[1] & b.i32[1], a.i32[2] & b.i32[2], a.i32[3] & b.i32[3]); +} + +PX_FORCE_INLINE VecI32V VecI32V_Or(const VecI32VArg a, const VecI32VArg b) +{ + return VecI32V(a.i32[0] | b.i32[0], a.i32[1] | b.i32[1], a.i32[2] | b.i32[2], a.i32[3] | b.i32[3]); +} + +PX_FORCE_INLINE VecI32V VecI32V_GetX(const VecI32VArg a) +{ + return VecI32V(a.i32[0], a.i32[0], a.i32[0], a.i32[0]); +} + +PX_FORCE_INLINE VecI32V VecI32V_GetY(const VecI32VArg a) +{ + return VecI32V(a.i32[1], a.i32[1], a.i32[1], a.i32[1]); +} + +PX_FORCE_INLINE VecI32V VecI32V_GetZ(const VecI32VArg a) +{ + return VecI32V(a.i32[2], a.i32[2], a.i32[2], a.i32[2]); +} + +PX_FORCE_INLINE VecI32V VecI32V_GetW(const VecI32VArg a) +{ + return VecI32V(a.i32[3], a.i32[3], a.i32[3], a.i32[3]); +} + +PX_FORCE_INLINE VecI32V VecI32V_Sel(const BoolV c, const VecI32VArg a, const VecI32VArg b) +{ + return VecI32V(c.ux ? a.i32[0] : b.i32[0], c.uy ? a.i32[1] : b.i32[1], c.uz ? a.i32[2] : b.i32[2], + c.uw ? a.i32[3] : b.i32[3]); +} + +PX_FORCE_INLINE VecI32V VecI32V_Merge(const VecI32VArg a, const VecI32VArg b, const VecI32VArg c, const VecI32VArg d) +{ + return VecI32V(a.i32[0], b.i32[0], c.i32[0], d.i32[0]); +} + +PX_FORCE_INLINE void PxI32_From_VecI32V(const VecI32VArg a, PxI32* i) +{ + *i = a.i32[0]; +} + +PX_FORCE_INLINE VecI32V VecI32V_From_BoolV(const BoolVArg b) +{ + return VecI32V(PxI32(b.ux), PxI32(b.uy), PxI32(b.uz), PxI32(b.uw)); +} + +PX_FORCE_INLINE VecU32V VecU32V_From_BoolV(const BoolVArg b) +{ + return VecU32V(b.ux, b.uy, b.uz, b.uw); +} + +PX_FORCE_INLINE void QuatGetMat33V(const QuatVArg q, Vec3V& column0, Vec3V& column1, Vec3V& column2) +{ + const FloatV one = FOne(); + const FloatV x = V4GetX(q); + const FloatV y = V4GetY(q); + const FloatV z = V4GetZ(q); + const FloatV w = V4GetW(q); + + const FloatV x2 = FAdd(x, x); + const FloatV y2 = FAdd(y, y); + const FloatV z2 = FAdd(z, z); + + const FloatV xx = FMul(x2, x); + const FloatV yy = FMul(y2, y); + const FloatV zz = FMul(z2, z); + + const FloatV xy = FMul(x2, y); + const FloatV xz = FMul(x2, z); + const FloatV xw = FMul(x2, w); + + const FloatV yz = FMul(y2, z); + const FloatV yw = FMul(y2, w); + const FloatV zw = FMul(z2, w); + + const FloatV v = FSub(one, xx); + + column0 = V3Merge(FSub(FSub(one, yy), zz), FAdd(xy, zw), FSub(xz, yw)); + column1 = V3Merge(FSub(xy, zw), FSub(v, zz), FAdd(yz, xw)); + column2 = V3Merge(FAdd(xz, yw), FSub(yz, xw), FSub(v, yy)); +} + + +// not used + +/* +PX_FORCE_INLINE Vec4V V4LoadAligned(Vec4V* addr) +{ + return *addr; +} +*/ + +/* +PX_FORCE_INLINE Vec4V V4LoadUnaligned(Vec4V* addr) +{ + return *addr; +} +*/ + +/* +PX_FORCE_INLINE Vec4V V4Ceil(const Vec4V a) +{ + return Vec4V(PxCeil(a.x), PxCeil(a.y), PxCeil(a.z), PxCeil(a.w)); +} + +PX_FORCE_INLINE Vec4V V4Floor(const Vec4V a) +{ + return Vec4V(PxFloor(a.x), PxFloor(a.y), PxFloor(a.z), PxFloor(a.w)); +} +*/ + +/* +PX_FORCE_INLINE VecU32V V4ConvertToU32VSaturate(const Vec4V a, PxU32 power) +{ + PX_ASSERT(power == 0 && "Non-zero power not supported in convertToU32VSaturate"); + PX_UNUSED(power); // prevent warning in release builds + PxF32 ffffFFFFasFloat = PxF32(0xFFFF0000); + return VecU32V( + PxU32(PxClamp((a).x, 0.0f, ffffFFFFasFloat)), + PxU32(PxClamp((a).y, 0.0f, ffffFFFFasFloat)), + PxU32(PxClamp((a).z, 0.0f, ffffFFFFasFloat)), + PxU32(PxClamp((a).w, 0.0f, ffffFFFFasFloat))); +} +*/ + +} // namespace aos +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxVecMathSSE.h b/Source/ThirdParty/PhysX/foundation/PxVecMathSSE.h new file mode 100644 index 000000000..0b0aaa924 --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxVecMathSSE.h @@ -0,0 +1,68 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_VEC_MATH_SSE_H +#define PX_VEC_MATH_SSE_H + +#if !PX_DOXYGEN +namespace physx +{ +#endif +namespace aos +{ + +namespace +{ + const PX_ALIGN(16, PxF32) minus1w[4] = { 0.0f, 0.0f, 0.0f, -1.0f }; +} + +PX_FORCE_INLINE void QuatGetMat33V(const QuatVArg q, Vec3V& column0, Vec3V& column1, Vec3V& column2) +{ + const __m128 q2 = V4Add(q, q); + const __m128 qw2 = V4MulAdd(q2, V4GetW(q), _mm_load_ps(minus1w)); // (2wx, 2wy, 2wz, 2ww-1) + const __m128 nw2 = Vec3V_From_Vec4V(V4Neg(qw2)); // (-2wx, -2wy, -2wz, 0) + const __m128 v = Vec3V_From_Vec4V(q); + + const __m128 a0 = _mm_shuffle_ps(qw2, nw2, _MM_SHUFFLE(3, 1, 2, 3)); // (2ww-1, 2wz, -2wy, 0) + column0 = V4MulAdd(v, V4GetX(q2), a0); + + const __m128 a1 = _mm_shuffle_ps(qw2, nw2, _MM_SHUFFLE(3, 2, 0, 3)); // (2ww-1, 2wx, -2wz, 0) + column1 = V4MulAdd(v, V4GetY(q2), _mm_shuffle_ps(a1, a1, _MM_SHUFFLE(3, 1, 0, 2))); + + const __m128 a2 = _mm_shuffle_ps(qw2, nw2, _MM_SHUFFLE(3, 0, 1, 3)); // (2ww-1, 2wy, -2wx, 0) + column2 = V4MulAdd(v, V4GetZ(q2), _mm_shuffle_ps(a2, a2, _MM_SHUFFLE(3, 0, 2, 1))); +} + +} // namespace aos +#if !PX_DOXYGEN +} // namespace physx +#endif + + +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/PxVecQuat.h b/Source/ThirdParty/PhysX/foundation/PxVecQuat.h new file mode 100644 index 000000000..1c6d04a31 --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxVecQuat.h @@ -0,0 +1,473 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_VEC_QUAT_H +#define PX_VEC_QUAT_H + +#if !PX_DOXYGEN +namespace physx +{ +#endif +namespace aos +{ + +#ifndef PX_PIDIV2 +#define PX_PIDIV2 1.570796327f +#endif + +////////////////////////////////// +// QuatV +////////////////////////////////// +PX_FORCE_INLINE QuatV QuatVLoadXYZW(const PxF32 x, const PxF32 y, const PxF32 z, const PxF32 w) +{ + return V4LoadXYZW(x, y, z, w); +} + +PX_FORCE_INLINE QuatV QuatVLoadU(const PxF32* v) +{ + return V4LoadU(v); +} + +PX_FORCE_INLINE QuatV QuatVLoadA(const PxF32* v) +{ + return V4LoadA(v); +} + +PX_FORCE_INLINE QuatV QuatV_From_RotationAxisAngle(const Vec3V u, const FloatV a) +{ + // q = cos(a/2) + u*sin(a/2) + const FloatV half = FLoad(0.5f); + const FloatV hangle = FMul(a, half); + const FloatV piByTwo(FLoad(PX_PIDIV2)); + const FloatV PiByTwoMinHangle(FSub(piByTwo, hangle)); + const Vec4V hangle2(Vec4V_From_Vec3V(V3Merge(hangle, PiByTwoMinHangle, hangle))); + + /*const FloatV sina = FSin(hangle); + const FloatV cosa = FCos(hangle);*/ + + const Vec4V _sina = V4Sin(hangle2); + const FloatV sina = V4GetX(_sina); + const FloatV cosa = V4GetY(_sina); + + const Vec3V v = V3Scale(u, sina); + // return V4Sel(BTTTF(), Vec4V_From_Vec3V(v), V4Splat(cosa)); + return V4SetW(Vec4V_From_Vec3V(v), cosa); +} + +// Normalize +PX_FORCE_INLINE QuatV QuatNormalize(const QuatV q) +{ + return V4Normalize(q); +} + +PX_FORCE_INLINE FloatV QuatLength(const QuatV q) +{ + return V4Length(q); +} + +PX_FORCE_INLINE FloatV QuatLengthSq(const QuatV q) +{ + return V4LengthSq(q); +} + +PX_FORCE_INLINE FloatV QuatDot(const QuatV a, const QuatV b) // convert this PxQuat to a unit quaternion +{ + return V4Dot(a, b); +} + +PX_FORCE_INLINE QuatV QuatConjugate(const QuatV q) +{ + return V4SetW(V4Neg(q), V4GetW(q)); +} + +PX_FORCE_INLINE Vec3V QuatGetImaginaryPart(const QuatV q) +{ + return Vec3V_From_Vec4V(q); +} + +/** brief computes rotation of x-axis */ +PX_FORCE_INLINE Vec3V QuatGetBasisVector0(const QuatV q) +{ + /*const PxF32 x2 = x*2.0f; + const PxF32 w2 = w*2.0f; + return PxVec3( (w * w2) - 1.0f + x*x2, + (z * w2) + y*x2, + (-y * w2) + z*x2);*/ + + const FloatV two = FLoad(2.f); + const FloatV w = V4GetW(q); + const Vec3V u = Vec3V_From_Vec4V(q); + + const FloatV x2 = FMul(V3GetX(u), two); + const FloatV w2 = FMul(w, two); + + const Vec3V a = V3Scale(u, x2); + const Vec3V tmp = V3Merge(w, V3GetZ(u), FNeg(V3GetY(u))); + // const Vec3V b = V3Scale(tmp, w2); + // const Vec3V ab = V3Add(a, b); + const Vec3V ab = V3ScaleAdd(tmp, w2, a); + return V3SetX(ab, FSub(V3GetX(ab), FOne())); +} + +/** brief computes rotation of y-axis */ +PX_FORCE_INLINE Vec3V QuatGetBasisVector1(const QuatV q) +{ + /*const PxF32 y2 = y*2.0f; + const PxF32 w2 = w*2.0f; + return PxVec3( (-z * w2) + x*y2, + (w * w2) - 1.0f + y*y2, + (x * w2) + z*y2);*/ + + const FloatV two = FLoad(2.f); + const FloatV w = V4GetW(q); + const Vec3V u = Vec3V_From_Vec4V(q); + + const FloatV y2 = FMul(V3GetY(u), two); + const FloatV w2 = FMul(w, two); + + const Vec3V a = V3Scale(u, y2); + const Vec3V tmp = V3Merge(FNeg(V3GetZ(u)), w, V3GetX(u)); + // const Vec3V b = V3Scale(tmp, w2); + // const Vec3V ab = V3Add(a, b); + const Vec3V ab = V3ScaleAdd(tmp, w2, a); + return V3SetY(ab, FSub(V3GetY(ab), FOne())); +} + +/** brief computes rotation of z-axis */ +PX_FORCE_INLINE Vec3V QuatGetBasisVector2(const QuatV q) +{ + /*const PxF32 z2 = z*2.0f; + const PxF32 w2 = w*2.0f; + return PxVec3( (y * w2) + x*z2, + (-x * w2) + y*z2, + (w * w2) - 1.0f + z*z2);*/ + + const FloatV two = FLoad(2.f); + const FloatV w = V4GetW(q); + const Vec3V u = Vec3V_From_Vec4V(q); + + const FloatV z2 = FMul(V3GetZ(u), two); + const FloatV w2 = FMul(w, two); + + const Vec3V a = V3Scale(u, z2); + const Vec3V tmp = V3Merge(V3GetY(u), FNeg(V3GetX(u)), w); + /*const Vec3V b = V3Scale(tmp, w2); + const Vec3V ab = V3Add(a, b);*/ + const Vec3V ab = V3ScaleAdd(tmp, w2, a); + return V3SetZ(ab, FSub(V3GetZ(ab), FOne())); +} + +PX_FORCE_INLINE Vec3V QuatRotate(const QuatV q, const Vec3V v) +{ + /* + const PxVec3 qv(x,y,z); + return (v*(w*w-0.5f) + (qv.cross(v))*w + qv*(qv.dot(v)))*2; + */ + + const FloatV two = FLoad(2.f); + // const FloatV half = FloatV_From_F32(0.5f); + const FloatV nhalf = FLoad(-0.5f); + const Vec3V u = Vec3V_From_Vec4V(q); + const FloatV w = V4GetW(q); + // const FloatV w2 = FSub(FMul(w, w), half); + const FloatV w2 = FScaleAdd(w, w, nhalf); + const Vec3V a = V3Scale(v, w2); + // const Vec3V b = V3Scale(V3Cross(u, v), w); + // const Vec3V c = V3Scale(u, V3Dot(u, v)); + // return V3Scale(V3Add(V3Add(a, b), c), two); + const Vec3V temp = V3ScaleAdd(V3Cross(u, v), w, a); + return V3Scale(V3ScaleAdd(u, V3Dot(u, v), temp), two); +} + +PX_FORCE_INLINE Vec3V QuatTransform(const QuatV q, const Vec3V p, const Vec3V v) +{ + // p + q.rotate(v) + const FloatV two = FLoad(2.f); + // const FloatV half = FloatV_From_F32(0.5f); + const FloatV nhalf = FLoad(-0.5f); + const Vec3V u = Vec3V_From_Vec4V(q); + const FloatV w = V4GetW(q); + // const FloatV w2 = FSub(FMul(w, w), half); + const FloatV w2 = FScaleAdd(w, w, nhalf); + const Vec3V a = V3Scale(v, w2); + /*const Vec3V b = V3Scale(V3Cross(u, v), w); + const Vec3V c = V3Scale(u, V3Dot(u, v)); + return V3ScaleAdd(V3Add(V3Add(a, b), c), two, p);*/ + const Vec3V temp = V3ScaleAdd(V3Cross(u, v), w, a); + const Vec3V z = V3ScaleAdd(u, V3Dot(u, v), temp); + return V3ScaleAdd(z, two, p); +} + +PX_FORCE_INLINE Vec3V QuatRotateInv(const QuatV q, const Vec3V v) +{ + + // const PxVec3 qv(x,y,z); + // return (v*(w*w-0.5f) - (qv.cross(v))*w + qv*(qv.dot(v)))*2; + + const FloatV two = FLoad(2.f); + const FloatV nhalf = FLoad(-0.5f); + const Vec3V u = Vec3V_From_Vec4V(q); + const FloatV w = V4GetW(q); + const FloatV w2 = FScaleAdd(w, w, nhalf); + const Vec3V a = V3Scale(v, w2); + /*const Vec3V b = V3Scale(V3Cross(u, v), w); + const Vec3V c = V3Scale(u, V3Dot(u, v)); + return V3Scale(V3Add(V3Sub(a, b), c), two);*/ + const Vec3V temp = V3NegScaleSub(V3Cross(u, v), w, a); + return V3Scale(V3ScaleAdd(u, V3Dot(u, v), temp), two); +} + +PX_FORCE_INLINE QuatV QuatMul(const QuatV a, const QuatV b) +{ + const Vec3V imagA = Vec3V_From_Vec4V(a); + const Vec3V imagB = Vec3V_From_Vec4V(b); + const FloatV rA = V4GetW(a); + const FloatV rB = V4GetW(b); + + const FloatV real = FSub(FMul(rA, rB), V3Dot(imagA, imagB)); + const Vec3V v0 = V3Scale(imagA, rB); + const Vec3V v1 = V3Scale(imagB, rA); + const Vec3V v2 = V3Cross(imagA, imagB); + const Vec3V imag = V3Add(V3Add(v0, v1), v2); + + return V4SetW(Vec4V_From_Vec3V(imag), real); +} + +PX_FORCE_INLINE QuatV QuatAdd(const QuatV a, const QuatV b) +{ + return V4Add(a, b); +} + +PX_FORCE_INLINE QuatV QuatNeg(const QuatV q) +{ + return V4Neg(q); +} + +PX_FORCE_INLINE QuatV QuatSub(const QuatV a, const QuatV b) +{ + return V4Sub(a, b); +} + +PX_FORCE_INLINE QuatV QuatScale(const QuatV a, const FloatV b) +{ + return V4Scale(a, b); +} + +PX_FORCE_INLINE QuatV QuatMerge(const FloatV* const floatVArray) +{ + return V4Merge(floatVArray); +} + +PX_FORCE_INLINE QuatV QuatMerge(const FloatVArg x, const FloatVArg y, const FloatVArg z, const FloatVArg w) +{ + return V4Merge(x, y, z, w); +} + +PX_FORCE_INLINE QuatV QuatIdentity() +{ + return V4SetW(V4Zero(), FOne()); +} + +PX_FORCE_INLINE bool isFiniteQuatV(const QuatV q) +{ + return isFiniteVec4V(q); +} + +#if PX_CLANG +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wbitwise-instead-of-logical" // bitwise intentionally chosen for performance +#endif + +PX_FORCE_INLINE bool isValidQuatV(const QuatV q) +{ + const FloatV unitTolerance = FLoad(1e-4f); + const FloatV tmp = FAbs(FSub(QuatLength(q), FOne())); + const BoolV con = FIsGrtr(unitTolerance, tmp); + return isFiniteVec4V(q) & (BAllEqTTTT(con) == 1); +} + +PX_FORCE_INLINE bool isSaneQuatV(const QuatV q) +{ + const FloatV unitTolerance = FLoad(1e-2f); + const FloatV tmp = FAbs(FSub(QuatLength(q), FOne())); + const BoolV con = FIsGrtr(unitTolerance, tmp); + return isFiniteVec4V(q) & (BAllEqTTTT(con) == 1); +} + +#if PX_CLANG +#pragma clang diagnostic pop +#endif + +PX_FORCE_INLINE Mat33V QuatGetMat33V(const QuatVArg q) +{ + // const FloatV two = FloatV_From_F32(2.f); + // const FloatV one = FOne(); + + // const FloatV x = V4GetX(q); + // const FloatV y = V4GetY(q); + // const FloatV z = V4GetZ(q); + // const Vec4V _q = V4Mul(q, two); + // + ////const FloatV w = V4GetW(q); + + // const Vec4V t0 = V4Mul(_q, x); // 2xx, 2xy, 2xz, 2xw + // const Vec4V t1 = V4Mul(_q, y); // 2xy, 2yy, 2yz, 2yw + // const Vec4V t2 = V4Mul(_q, z); // 2xz, 2yz, 2zz, 2zw + ////const Vec4V t3 = V4Mul(_q, w); // 2xw, 2yw, 2zw, 2ww + + // const FloatV xx2 = V4GetX(t0); + // const FloatV xy2 = V4GetY(t0); + // const FloatV xz2 = V4GetZ(t0); + // const FloatV xw2 = V4GetW(t0); + + // const FloatV yy2 = V4GetY(t1); + // const FloatV yz2 = V4GetZ(t1); + // const FloatV yw2 = V4GetW(t1); + + // const FloatV zz2 = V4GetZ(t2); + // const FloatV zw2 = V4GetW(t2); + + ////const FloatV ww2 = V4GetW(t3); + + // const FloatV c00 = FSub(one, FAdd(yy2, zz2)); + // const FloatV c01 = FSub(xy2, zw2); + // const FloatV c02 = FAdd(xz2, yw2); + + // const FloatV c10 = FAdd(xy2, zw2); + // const FloatV c11 = FSub(one, FAdd(xx2, zz2)); + // const FloatV c12 = FSub(yz2, xw2); + + // const FloatV c20 = FSub(xz2, yw2); + // const FloatV c21 = FAdd(yz2, xw2); + // const FloatV c22 = FSub(one, FAdd(xx2, yy2)); + + // const Vec3V c0 = V3Merge(c00, c10, c20); + // const Vec3V c1 = V3Merge(c01, c11, c21); + // const Vec3V c2 = V3Merge(c02, c12, c22); + + // return Mat33V(c0, c1, c2); + + const FloatV one = FOne(); + const FloatV x = V4GetX(q); + const FloatV y = V4GetY(q); + const FloatV z = V4GetZ(q); + const FloatV w = V4GetW(q); + + const FloatV x2 = FAdd(x, x); + const FloatV y2 = FAdd(y, y); + const FloatV z2 = FAdd(z, z); + + const FloatV xx = FMul(x2, x); + const FloatV yy = FMul(y2, y); + const FloatV zz = FMul(z2, z); + + const FloatV xy = FMul(x2, y); + const FloatV xz = FMul(x2, z); + const FloatV xw = FMul(x2, w); + + const FloatV yz = FMul(y2, z); + const FloatV yw = FMul(y2, w); + const FloatV zw = FMul(z2, w); + + const FloatV v = FSub(one, xx); + + const Vec3V column0 = V3Merge(FSub(FSub(one, yy), zz), FAdd(xy, zw), FSub(xz, yw)); + const Vec3V column1 = V3Merge(FSub(xy, zw), FSub(v, zz), FAdd(yz, xw)); + const Vec3V column2 = V3Merge(FAdd(xz, yw), FSub(yz, xw), FSub(v, yy)); + return Mat33V(column0, column1, column2); +} + +PX_FORCE_INLINE QuatV Mat33GetQuatV(const Mat33V& a) +{ + const FloatV one = FOne(); + const FloatV zero = FZero(); + const FloatV half = FLoad(0.5f); + const FloatV two = FLoad(2.f); + const FloatV scale = FLoad(0.25f); + const FloatV a00 = V3GetX(a.col0); + const FloatV a11 = V3GetY(a.col1); + const FloatV a22 = V3GetZ(a.col2); + + const FloatV a21 = V3GetZ(a.col1); // row=2, col=1; + const FloatV a12 = V3GetY(a.col2); // row=1, col=2; + const FloatV a02 = V3GetX(a.col2); // row=0, col=2; + const FloatV a20 = V3GetZ(a.col0); // row=2, col=0; + const FloatV a10 = V3GetY(a.col0); // row=1, col=0; + const FloatV a01 = V3GetX(a.col1); // row=0, col=1; + + const Vec3V vec0 = V3Merge(a21, a02, a10); + const Vec3V vec1 = V3Merge(a12, a20, a01); + const Vec3V v = V3Sub(vec0, vec1); + const Vec3V g = V3Add(vec0, vec1); + + const FloatV trace = FAdd(a00, FAdd(a11, a22)); + + if(FAllGrtrOrEq(trace, zero)) + { + const FloatV h = FSqrt(FAdd(trace, one)); + const FloatV w = FMul(half, h); + const FloatV s = FMul(half, FRecip(h)); + const Vec3V u = V3Scale(v, s); + return V4SetW(Vec4V_From_Vec3V(u), w); + } + else + { + const FloatV ntrace = FNeg(trace); + const Vec3V d = V3Merge(a00, a11, a22); + const BoolV con0 = BAllTrue3(V3IsGrtrOrEq(V3Splat(a00), d)); + const BoolV con1 = BAllTrue3(V3IsGrtrOrEq(V3Splat(a11), d)); + + const FloatV t0 = FAdd(one, FScaleAdd(a00, two, ntrace)); + const FloatV t1 = FAdd(one, FScaleAdd(a11, two, ntrace)); + const FloatV t2 = FAdd(one, FScaleAdd(a22, two, ntrace)); + + const FloatV t = FSel(con0, t0, FSel(con1, t1, t2)); + + const FloatV h = FMul(two, FSqrt(t)); + const FloatV s = FRecip(h); + const FloatV g0 = FMul(scale, h); + const Vec3V vs = V3Scale(v, s); + const Vec3V gs = V3Scale(g, s); + const FloatV gsx = V3GetX(gs); + const FloatV gsy = V3GetY(gs); + const FloatV gsz = V3GetZ(gs); + // vs.x= (a21 - a12)*s; vs.y=(a02 - a20)*s; vs.z=(a10 - a01)*s; + // gs.x= (a21 + a12)*s; gs.y=(a02 + a20)*s; gs.z=(a10 + a01)*s; + const Vec4V v0 = V4Merge(g0, gsz, gsy, V3GetX(vs)); + const Vec4V v1 = V4Merge(gsz, g0, gsx, V3GetY(vs)); + const Vec4V v2 = V4Merge(gsy, gsx, g0, V3GetZ(vs)); + return V4Sel(con0, v0, V4Sel(con1, v1, v2)); + } +} + +} // namespace aos +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif diff --git a/Source/ThirdParty/PhysX/foundation/PxVecTransform.h b/Source/ThirdParty/PhysX/foundation/PxVecTransform.h new file mode 100644 index 000000000..fcfd412f3 --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/PxVecTransform.h @@ -0,0 +1,291 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_VEC_TRANSFORM_H +#define PX_VEC_TRANSFORM_H + +#include "foundation/PxVecMath.h" +#include "foundation/PxTransform.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif +namespace aos +{ + +class PxTransformV +{ + public: + QuatV q; + Vec3V p; + + PX_FORCE_INLINE PxTransformV(const PxTransform& orientation) + { + // const PxQuat oq = orientation.q; + // const PxF32 f[4] = {oq.x, oq.y, oq.z, oq.w}; + q = QuatVLoadXYZW(orientation.q.x, orientation.q.y, orientation.q.z, orientation.q.w); + // q = QuatV_From_F32Array(&oq.x); + p = V3LoadU(orientation.p); + } + + PX_FORCE_INLINE PxTransformV(const Vec3VArg p0 = V3Zero(), const QuatVArg q0 = QuatIdentity()) : q(q0), p(p0) + { + PX_ASSERT(isSaneQuatV(q0)); + } + + PX_FORCE_INLINE PxTransformV operator*(const PxTransformV& x) const + { + PX_ASSERT(x.isSane()); + return transform(x); + } + + PX_FORCE_INLINE PxTransformV getInverse() const + { + PX_ASSERT(isFinite()); + // return PxTransform(q.rotateInv(-p),q.getConjugate()); + return PxTransformV(QuatRotateInv(q, V3Neg(p)), QuatConjugate(q)); + } + + PX_FORCE_INLINE void normalize() + { + p = V3Zero(); + q = QuatIdentity(); + } + + PX_FORCE_INLINE void Invalidate() + { + p = V3Splat(FMax()); + q = QuatIdentity(); + } + + PX_FORCE_INLINE Vec3V transform(const Vec3VArg input) const + { + PX_ASSERT(isFinite()); + // return q.rotate(input) + p; + return QuatTransform(q, p, input); + } + + PX_FORCE_INLINE Vec3V transformInv(const Vec3VArg input) const + { + PX_ASSERT(isFinite()); + // return q.rotateInv(input-p); + return QuatRotateInv(q, V3Sub(input, p)); + } + + PX_FORCE_INLINE Vec3V rotate(const Vec3VArg input) const + { + PX_ASSERT(isFinite()); + // return q.rotate(input); + return QuatRotate(q, input); + } + + PX_FORCE_INLINE Vec3V rotateInv(const Vec3VArg input) const + { + PX_ASSERT(isFinite()); + // return q.rotateInv(input); + return QuatRotateInv(q, input); + } + + //! Transform transform to parent (returns compound transform: first src, then *this) + PX_FORCE_INLINE PxTransformV transform(const PxTransformV& src) const + { + PX_ASSERT(src.isSane()); + PX_ASSERT(isSane()); + // src = [srct, srcr] -> [r*srct + t, r*srcr] + // return PxTransform(q.rotate(src.p) + p, q*src.q); + return PxTransformV(V3Add(QuatRotate(q, src.p), p), QuatMul(q, src.q)); + } + +#if PX_CLANG +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wbitwise-instead-of-logical" // bitwise intentionally chosen for performance +#endif + + /** + \brief returns true if finite and q is a unit quaternion + */ + PX_FORCE_INLINE bool isValid() const + { + // return p.isFinite() && q.isFinite() && q.isValid(); + return isFiniteVec3V(p) & isFiniteQuatV(q) & isValidQuatV(q); + } + + /** + \brief returns true if finite and quat magnitude is reasonably close to unit to allow for some accumulation of error + vs isValid + */ + + PX_FORCE_INLINE bool isSane() const + { + // return isFinite() && q.isSane(); + return isFinite() & isSaneQuatV(q); + } + + /** + \brief returns true if all elems are finite (not NAN or INF, etc.) + */ + PX_FORCE_INLINE bool isFinite() const + { + // return p.isFinite() && q.isFinite(); + return isFiniteVec3V(p) & isFiniteQuatV(q); + } + +#if PX_CLANG +#pragma clang diagnostic pop +#endif + + //! Transform transform from parent (returns compound transform: first src, then this->inverse) + PX_FORCE_INLINE PxTransformV transformInv(const PxTransformV& src) const + { + PX_ASSERT(src.isSane()); + PX_ASSERT(isFinite()); + // src = [srct, srcr] -> [r^-1*(srct-t), r^-1*srcr] + /*PxQuat qinv = q.getConjugate(); + return PxTransform(qinv.rotate(src.p - p), qinv*src.q);*/ + const QuatV qinv = QuatConjugate(q); + const Vec3V v = QuatRotate(qinv, V3Sub(src.p, p)); + const QuatV rot = QuatMul(qinv, src.q); + return PxTransformV(v, rot); + } + + static PX_FORCE_INLINE PxTransformV createIdentity() + { + return PxTransformV(V3Zero()); + } +}; + +PX_FORCE_INLINE PxTransformV loadTransformA(const PxTransform& transform) +{ + const QuatV q0 = QuatVLoadA(&transform.q.x); + const Vec3V p0 = V3LoadA(&transform.p.x); + + return PxTransformV(p0, q0); +} + +PX_FORCE_INLINE PxTransformV loadTransformU(const PxTransform& transform) +{ + const QuatV q0 = QuatVLoadU(&transform.q.x); + const Vec3V p0 = V3LoadU(&transform.p.x); + + return PxTransformV(p0, q0); +} + +class PxMatTransformV +{ + public: + Mat33V rot; + Vec3V p; + + PX_FORCE_INLINE PxMatTransformV() + { + p = V3Zero(); + rot = M33Identity(); + } + PX_FORCE_INLINE PxMatTransformV(const Vec3VArg _p, const Mat33V& _rot) + { + p = _p; + rot = _rot; + } + + PX_FORCE_INLINE PxMatTransformV(const PxTransformV& other) + { + p = other.p; + QuatGetMat33V(other.q, rot.col0, rot.col1, rot.col2); + } + + PX_FORCE_INLINE PxMatTransformV(const Vec3VArg _p, const QuatV& quat) + { + p = _p; + QuatGetMat33V(quat, rot.col0, rot.col1, rot.col2); + } + + PX_FORCE_INLINE Vec3V getCol0() const + { + return rot.col0; + } + + PX_FORCE_INLINE Vec3V getCol1() const + { + return rot.col1; + } + + PX_FORCE_INLINE Vec3V getCol2() const + { + return rot.col2; + } + + PX_FORCE_INLINE void setCol0(const Vec3VArg col0) + { + rot.col0 = col0; + } + + PX_FORCE_INLINE void setCol1(const Vec3VArg col1) + { + rot.col1 = col1; + } + + PX_FORCE_INLINE void setCol2(const Vec3VArg col2) + { + rot.col2 = col2; + } + + PX_FORCE_INLINE Vec3V transform(const Vec3VArg input) const + { + return V3Add(p, M33MulV3(rot, input)); + } + + PX_FORCE_INLINE Vec3V transformInv(const Vec3VArg input) const + { + return M33TrnspsMulV3(rot, V3Sub(input, p)); // QuatRotateInv(q, V3Sub(input, p)); + } + + PX_FORCE_INLINE Vec3V rotate(const Vec3VArg input) const + { + return M33MulV3(rot, input); + } + + PX_FORCE_INLINE Vec3V rotateInv(const Vec3VArg input) const + { + return M33TrnspsMulV3(rot, input); + } + + PX_FORCE_INLINE PxMatTransformV transformInv(const PxMatTransformV& src) const + { + + const Vec3V v = M33TrnspsMulV3(rot, V3Sub(src.p, p)); + const Mat33V mat = M33MulM33(M33Trnsps(rot), src.rot); + return PxMatTransformV(v, mat); + } +}; +} +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif diff --git a/Source/ThirdParty/PhysX/foundation/unix/PxUnixAoS.h b/Source/ThirdParty/PhysX/foundation/unix/PxUnixAoS.h new file mode 100644 index 000000000..530cc9525 --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/unix/PxUnixAoS.h @@ -0,0 +1,46 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PXFOUNDATION_PXUNIXAOS_H +#define PXFOUNDATION_PXUNIXAOS_H + +// no includes here! this file should be included from PxcVecMath.h only!!! + +#if !COMPILE_VECTOR_INTRINSICS +#error Vector intrinsics should not be included when using scalar implementation. +#endif + +#if PX_INTEL_FAMILY +#include "foundation/unix/sse2/PxUnixSse2AoS.h" +#elif PX_NEON +#include "foundation/unix/neon/PxUnixNeonAoS.h" +#else +#error No SIMD implementation for this unix platform. +#endif + +#endif // PXFOUNDATION_PXUNIXAOS_H diff --git a/Source/ThirdParty/PhysX/foundation/unix/PxUnixFPU.h b/Source/ThirdParty/PhysX/foundation/unix/PxUnixFPU.h new file mode 100644 index 000000000..6accc20fd --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/unix/PxUnixFPU.h @@ -0,0 +1,83 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PXFOUNDATION_PXUNIXFPU_H +#define PXFOUNDATION_PXUNIXFPU_H + +#include "foundation/PxPreprocessor.h" + +#if PX_LINUX || PX_PS4 || PX_PS5 || PX_OSX + +#if PX_X86 || PX_X64 +#if PX_EMSCRIPTEN +#include +#endif +#include +#elif PX_NEON +#include +#endif + +PX_INLINE physx::PxSIMDGuard::PxSIMDGuard(bool enable) +#if !PX_EMSCRIPTEN && (PX_X86 || PX_X64) + : mEnabled(enable) +#endif +{ +#if !PX_EMSCRIPTEN && (PX_X86 || PX_X64) + if(enable) + { + mControlWord = _mm_getcsr(); + // set default (disable exceptions: _MM_MASK_MASK) and FTZ (_MM_FLUSH_ZERO_ON), DAZ (_MM_DENORMALS_ZERO_ON: (1<<6)) + _mm_setcsr(_MM_MASK_MASK | _MM_FLUSH_ZERO_ON | (1 << 6)); + } + else + { + PX_UNUSED(enable); + PX_ASSERT(_mm_getcsr() & _MM_FLUSH_ZERO_ON); + PX_ASSERT(_mm_getcsr() & (1 << 6)); + PX_ASSERT(_mm_getcsr() & _MM_MASK_MASK); + } +#endif +} + +PX_INLINE physx::PxSIMDGuard::~PxSIMDGuard() +{ +#if !PX_EMSCRIPTEN && (PX_X86 || PX_X64) + if(mEnabled) + { + // restore control word and clear exception flags + // (setting exception state flags cause exceptions on the first following fp operation) + _mm_setcsr(mControlWord & PxU32(~_MM_EXCEPT_MASK)); + } +#endif +} + +#else + #error No SIMD implementation for this unix platform. +#endif + +#endif // #ifndef PXFOUNDATION_PXUNIXFPU_H diff --git a/Source/ThirdParty/PhysX/foundation/unix/PxUnixInlineAoS.h b/Source/ThirdParty/PhysX/foundation/unix/PxUnixInlineAoS.h new file mode 100644 index 000000000..e257d17b5 --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/unix/PxUnixInlineAoS.h @@ -0,0 +1,44 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PXFOUNDATION_PXUNIXINLINEAOS_H +#define PXFOUNDATION_PXUNIXINLINEAOS_H + +#if !COMPILE_VECTOR_INTRINSICS +#error Vector intrinsics should not be included when using scalar implementation. +#endif + +#if PX_INTEL_FAMILY +#include "foundation/unix/sse2/PxUnixSse2InlineAoS.h" +#elif PX_NEON +#include "foundation/unix/neon/PxUnixNeonInlineAoS.h" +#else +#error No SIMD implementation for this unix platform. +#endif + +#endif // PXFOUNDATION_PXUNIXINLINEAOS_H diff --git a/Source/ThirdParty/PhysX/foundation/unix/PxUnixIntrinsics.h b/Source/ThirdParty/PhysX/foundation/unix/PxUnixIntrinsics.h index 1095b1356..02104221a 100644 --- a/Source/ThirdParty/PhysX/foundation/unix/PxUnixIntrinsics.h +++ b/Source/ThirdParty/PhysX/foundation/unix/PxUnixIntrinsics.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,163 +22,106 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PXFOUNDATION_PXUNIXINTRINSICS_H -#define PXFOUNDATION_PXUNIXINTRINSICS_H - -#include "foundation/Px.h" -#include "foundation/PxSharedAssert.h" - -#if !(PX_LINUX || PX_ANDROID || PX_PS4 || PX_APPLE_FAMILY) -#error "This file should only be included by Unix builds!!" -#endif - -#if (PX_LINUX || PX_ANDROID) && !defined(__CUDACC__) && !PX_EMSCRIPTEN - // Linux/android and CUDA compilation does not work with std::isfnite, as it is not marked as CUDA callable - #include - #ifndef isfinite - using std::isfinite; - #endif -#endif +#ifndef PSFOUNDATION_PSUNIXINTRINSICS_H +#define PSFOUNDATION_PSUNIXINTRINSICS_H +#include "foundation/PxAssert.h" #include -#include +#if PX_ANDROID +#include // for PxDebugBreak() { raise(SIGTRAP); } +#endif + +// this file is for internal intrinsics - that is, intrinsics that are used in +// cross platform code but do not appear in the API + +#if !(PX_LINUX || PX_ANDROID || PX_PS4 || PX_PS5 || PX_APPLE_FAMILY) +#error "This file should only be included by unix builds!!" +#endif + +#if !PX_DOXYGEN namespace physx { -namespace intrinsics -{ -//! \brief platform-specific absolute value -PX_CUDA_CALLABLE PX_FORCE_INLINE float abs(float a) -{ - return ::fabsf(a); -} +#endif -//! \brief platform-specific select float -PX_CUDA_CALLABLE PX_FORCE_INLINE float fsel(float a, float b, float c) +PX_FORCE_INLINE void PxMemoryBarrier() { - return (a >= 0.0f) ? b : c; -} - -//! \brief platform-specific sign -PX_CUDA_CALLABLE PX_FORCE_INLINE float sign(float a) -{ - return (a >= 0.0f) ? 1.0f : -1.0f; -} - -//! \brief platform-specific reciprocal -PX_CUDA_CALLABLE PX_FORCE_INLINE float recip(float a) -{ - return 1.0f / a; -} - -//! \brief platform-specific reciprocal estimate -PX_CUDA_CALLABLE PX_FORCE_INLINE float recipFast(float a) -{ - return 1.0f / a; -} - -//! \brief platform-specific square root -PX_CUDA_CALLABLE PX_FORCE_INLINE float sqrt(float a) -{ - return ::sqrtf(a); -} - -//! \brief platform-specific reciprocal square root -PX_CUDA_CALLABLE PX_FORCE_INLINE float recipSqrt(float a) -{ - return 1.0f / ::sqrtf(a); -} - -PX_CUDA_CALLABLE PX_FORCE_INLINE float recipSqrtFast(float a) -{ - return 1.0f / ::sqrtf(a); -} - -//! \brief platform-specific sine -PX_CUDA_CALLABLE PX_FORCE_INLINE float sin(float a) -{ - return ::sinf(a); -} - -//! \brief platform-specific cosine -PX_CUDA_CALLABLE PX_FORCE_INLINE float cos(float a) -{ - return ::cosf(a); -} - -//! \brief platform-specific minimum -PX_CUDA_CALLABLE PX_FORCE_INLINE float selectMin(float a, float b) -{ - return a < b ? a : b; -} - -//! \brief platform-specific maximum -PX_CUDA_CALLABLE PX_FORCE_INLINE float selectMax(float a, float b) -{ - return a > b ? a : b; -} - -//! \brief platform-specific finiteness check (not INF or NAN) -PX_CUDA_CALLABLE PX_FORCE_INLINE bool isFinite(float a) -{ - //std::isfinite not recommended as of Feb 2017, since it doesn't work with g++/clang's floating point optimization. - union localU { PxU32 i; float f; } floatUnion; - floatUnion.f = a; - return !((floatUnion.i & 0x7fffffff) >= 0x7f800000); -} - -//! \brief platform-specific finiteness check (not INF or NAN) -PX_CUDA_CALLABLE PX_FORCE_INLINE bool isFinite(double a) -{ - return !!isfinite(a); + __sync_synchronize(); } /*! -Sets \c count bytes starting at \c dst to zero. +Return the index of the highest set bit. Undefined for zero arg. */ -PX_FORCE_INLINE void* memZero(void* dest, uint32_t count) +PX_INLINE uint32_t PxHighestSetBitUnsafe(uint32_t v) { - return memset(dest, 0, count); + + return uint32_t(31 - __builtin_clz(v)); } /*! -Sets \c count bytes starting at \c dst to \c c. +Return the index of the highest set bit. Undefined for zero arg. */ -PX_FORCE_INLINE void* memSet(void* dest, int32_t c, uint32_t count) +PX_INLINE uint32_t PxLowestSetBitUnsafe(uint32_t v) { - return memset(dest, c, count); + return uint32_t(__builtin_ctz(v)); } /*! -Copies \c count bytes from \c src to \c dst. User memMove if regions overlap. +Returns the index of the highest set bit. Returns 32 for v=0. */ -PX_FORCE_INLINE void* memCopy(void* dest, const void* src, uint32_t count) +PX_INLINE uint32_t PxCountLeadingZeros(uint32_t v) { - return memcpy(dest, src, count); + if(v) + return uint32_t(__builtin_clz(v)); + else + return 32u; } /*! -Copies \c count bytes from \c src to \c dst. Supports overlapping regions. +Prefetch aligned 64B x86, 32b ARM around \c ptr+offset. */ -PX_FORCE_INLINE void* memMove(void* dest, const void* src, uint32_t count) +PX_FORCE_INLINE void PxPrefetchLine(const void* ptr, uint32_t offset = 0) { - return memmove(dest, src, count); + __builtin_prefetch(reinterpret_cast(ptr) + offset, 0, 3); } /*! -Set 128B to zero starting at \c dst+offset. Must be aligned. +Prefetch \c count bytes starting at \c ptr. */ -PX_FORCE_INLINE void memZero128(void* dest, uint32_t offset = 0) +#if PX_ANDROID || PX_IOS +PX_FORCE_INLINE void PxPrefetch(const void* ptr, uint32_t count = 1) { - PX_SHARED_ASSERT(((size_t(dest) + offset) & 0x7f) == 0); - memSet(reinterpret_cast(dest) + offset, 0, 128); + const char* cp = static_cast(ptr); + size_t p = reinterpret_cast(ptr); + uint32_t startLine = uint32_t(p >> 5), endLine = uint32_t((p + count - 1) >> 5); + uint32_t lines = endLine - startLine + 1; + do + { + PxPrefetchLine(cp); + cp += 32; + } while(--lines); } +#else +PX_FORCE_INLINE void PxPrefetch(const void* ptr, uint32_t count = 1) +{ + const char* cp = reinterpret_cast(ptr); + uint64_t p = size_t(ptr); + uint64_t startLine = p >> 6, endLine = (p + count - 1) >> 6; + uint64_t lines = endLine - startLine + 1; + do + { + PxPrefetchLine(cp); + cp += 64; + } while(--lines); +} +#endif -} // namespace intrinsics +#if !PX_DOXYGEN } // namespace physx +#endif -#endif // #ifndef PXFOUNDATION_PXUNIXINTRINSICS_H +#endif // #ifndef PSFOUNDATION_PSUNIXINTRINSICS_H diff --git a/Source/ThirdParty/PhysX/foundation/unix/PxUnixMathIntrinsics.h b/Source/ThirdParty/PhysX/foundation/unix/PxUnixMathIntrinsics.h new file mode 100644 index 000000000..4e6ab96b9 --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/unix/PxUnixMathIntrinsics.h @@ -0,0 +1,180 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PXFOUNDATION_PXUNIXINTRINSICS_H +#define PXFOUNDATION_PXUNIXINTRINSICS_H + +#include "foundation/Px.h" +#include "foundation/PxAssert.h" + +#if !(PX_LINUX || PX_ANDROID || PX_APPLE_FAMILY) +#error "This file should only be included by Unix builds!!" +#endif + +#if PX_LINUX && !defined(__CUDACC__) && !PX_EMSCRIPTEN + // Linux and CUDA compilation does not work with std::isfnite, as it is not marked as CUDA callable + #include + #ifndef isfinite + using std::isfinite; + #endif +#endif + +#include +#include + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +namespace intrinsics +{ +//! \brief platform-specific absolute value +PX_CUDA_CALLABLE PX_FORCE_INLINE float abs(float a) +{ + return ::fabsf(a); +} + +//! \brief platform-specific select float +PX_CUDA_CALLABLE PX_FORCE_INLINE float fsel(float a, float b, float c) +{ + return (a >= 0.0f) ? b : c; +} + +//! \brief platform-specific sign +PX_CUDA_CALLABLE PX_FORCE_INLINE float sign(float a) +{ + return (a >= 0.0f) ? 1.0f : -1.0f; +} + +//! \brief platform-specific reciprocal +PX_CUDA_CALLABLE PX_FORCE_INLINE float recip(float a) +{ + return 1.0f / a; +} + +//! \brief platform-specific reciprocal estimate +PX_CUDA_CALLABLE PX_FORCE_INLINE float recipFast(float a) +{ + return 1.0f / a; +} + +//! \brief platform-specific square root +PX_CUDA_CALLABLE PX_FORCE_INLINE float sqrt(float a) +{ + return ::sqrtf(a); +} + +//! \brief platform-specific reciprocal square root +PX_CUDA_CALLABLE PX_FORCE_INLINE float recipSqrt(float a) +{ + return 1.0f / ::sqrtf(a); +} + +PX_CUDA_CALLABLE PX_FORCE_INLINE float recipSqrtFast(float a) +{ + return 1.0f / ::sqrtf(a); +} + +//! \brief platform-specific sine +PX_CUDA_CALLABLE PX_FORCE_INLINE float sin(float a) +{ + return ::sinf(a); +} + +//! \brief platform-specific cosine +PX_CUDA_CALLABLE PX_FORCE_INLINE float cos(float a) +{ + return ::cosf(a); +} + +//! \brief platform-specific minimum +PX_CUDA_CALLABLE PX_FORCE_INLINE float selectMin(float a, float b) +{ + return a < b ? a : b; +} + +//! \brief platform-specific maximum +PX_CUDA_CALLABLE PX_FORCE_INLINE float selectMax(float a, float b) +{ + return a > b ? a : b; +} + +//! \brief platform-specific finiteness check (not INF or NAN) +PX_CUDA_CALLABLE PX_FORCE_INLINE bool isFinite(float a) +{ + //std::isfinite not recommended as of Feb 2017, since it doesn't work with g++/clang's floating point optimization. + union localU { PxU32 i; float f; } floatUnion; + floatUnion.f = a; + return !((floatUnion.i & 0x7fffffff) >= 0x7f800000); +} + +//! \brief platform-specific finiteness check (not INF or NAN) +PX_CUDA_CALLABLE PX_FORCE_INLINE bool isFinite(double a) +{ + return !!isfinite(a); +} + +/*! +Sets \c count bytes starting at \c dst to zero. +*/ +PX_FORCE_INLINE void* memZero(void* dest, uint32_t count) +{ + return memset(dest, 0, count); +} + +/*! +Sets \c count bytes starting at \c dst to \c c. +*/ +PX_FORCE_INLINE void* memSet(void* dest, int32_t c, uint32_t count) +{ + return memset(dest, c, count); +} + +/*! +Copies \c count bytes from \c src to \c dst. User memMove if regions overlap. +*/ +PX_FORCE_INLINE void* memCopy(void* dest, const void* src, uint32_t count) +{ + return memcpy(dest, src, count); +} + +/*! +Copies \c count bytes from \c src to \c dst. Supports overlapping regions. +*/ +PX_FORCE_INLINE void* memMove(void* dest, const void* src, uint32_t count) +{ + return memmove(dest, src, count); +} + +} // namespace intrinsics +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif // #ifndef PXFOUNDATION_PXUNIXINTRINSICS_H diff --git a/Source/ThirdParty/PhysX/foundation/unix/PxUnixTrigConstants.h b/Source/ThirdParty/PhysX/foundation/unix/PxUnixTrigConstants.h new file mode 100644 index 000000000..635d5222e --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/unix/PxUnixTrigConstants.h @@ -0,0 +1,75 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PXFOUNDATION_PXUNIXTRIGCONSTANTS_H +#define PXFOUNDATION_PXUNIXTRIGCONSTANTS_H + +#include "foundation/PxPreprocessor.h" + +namespace physx +{ +namespace aos +{ + +#if PX_CLANG +#if PX_LINUX +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wmissing-variable-declarations" +#endif +#endif + +#define PX_GLOBALCONST extern const __attribute__((weak)) + +PX_ALIGN_PREFIX(16) +struct PX_VECTORF32 +{ + float f[4]; +} PX_ALIGN_SUFFIX(16); + +PX_GLOBALCONST PX_VECTORF32 g_PXSinCoefficients0 = { { 1.0f, -0.166666667f, 8.333333333e-3f, -1.984126984e-4f } }; +PX_GLOBALCONST PX_VECTORF32 +g_PXSinCoefficients1 = { { 2.755731922e-6f, -2.505210839e-8f, 1.605904384e-10f, -7.647163732e-13f } }; +PX_GLOBALCONST PX_VECTORF32 +g_PXSinCoefficients2 = { { 2.811457254e-15f, -8.220635247e-18f, 1.957294106e-20f, -3.868170171e-23f } }; +PX_GLOBALCONST PX_VECTORF32 g_PXCosCoefficients0 = { { 1.0f, -0.5f, 4.166666667e-2f, -1.388888889e-3f } }; +PX_GLOBALCONST PX_VECTORF32 +g_PXCosCoefficients1 = { { 2.480158730e-5f, -2.755731922e-7f, 2.087675699e-9f, -1.147074560e-11f } }; +PX_GLOBALCONST PX_VECTORF32 +g_PXCosCoefficients2 = { { 4.779477332e-14f, -1.561920697e-16f, 4.110317623e-19f, -8.896791392e-22f } }; +PX_GLOBALCONST PX_VECTORF32 g_PXReciprocalTwoPi = { { PxInvTwoPi, PxInvTwoPi, PxInvTwoPi, PxInvTwoPi } }; +PX_GLOBALCONST PX_VECTORF32 g_PXTwoPi = { { PxTwoPi, PxTwoPi, PxTwoPi, PxTwoPi } }; + +#if PX_CLANG +#if PX_LINUX +#pragma clang diagnostic pop +#endif +#endif +} // namespace aos +} // namespace physx + +#endif //PXFOUNDATION_PXUNIXTRIGCONSTANTS_H diff --git a/Source/ThirdParty/PhysX/foundation/unix/neon/PxUnixNeonAoS.h b/Source/ThirdParty/PhysX/foundation/unix/neon/PxUnixNeonAoS.h new file mode 100644 index 000000000..bf0085163 --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/unix/neon/PxUnixNeonAoS.h @@ -0,0 +1,136 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PXFOUNDATION_PXUNIXNEONAOS_H +#define PXFOUNDATION_PXUNIXNEONAOS_H + +// no includes here! this file should be included from PxcVecMath.h only!!! + +#if !COMPILE_VECTOR_INTRINSICS +#error Vector intrinsics should not be included when using scalar implementation. +#endif + +// only ARM NEON compatible platforms should reach this +#include + +namespace physx +{ +namespace aos +{ + +typedef float32x2_t FloatV; +typedef float32x4_t Vec3V; +typedef float32x4_t Vec4V; +typedef uint32x4_t BoolV; +typedef float32x4_t QuatV; + +typedef uint32x4_t VecU32V; +typedef int32x4_t VecI32V; +typedef uint16x8_t VecU16V; +typedef int16x8_t VecI16V; +typedef uint8x16_t VecU8V; + +#define FloatVArg FloatV & +#define Vec3VArg Vec3V & +#define Vec4VArg Vec4V & +#define BoolVArg BoolV & +#define VecU32VArg VecU32V & +#define VecI32VArg VecI32V & +#define VecU16VArg VecU16V & +#define VecI16VArg VecI16V & +#define VecU8VArg VecU8V & +#define QuatVArg QuatV & + +// KS - TODO - make an actual VecCrossV type for NEON +#define VecCrossV Vec3V + +typedef VecI32V VecShiftV; +#define VecShiftVArg VecShiftV & + +PX_ALIGN_PREFIX(16) +struct Mat33V +{ + Mat33V() + { + } + Mat33V(const Vec3V& c0, const Vec3V& c1, const Vec3V& c2) : col0(c0), col1(c1), col2(c2) + { + } + Vec3V PX_ALIGN(16, col0); + Vec3V PX_ALIGN(16, col1); + Vec3V PX_ALIGN(16, col2); +} PX_ALIGN_SUFFIX(16); + +PX_ALIGN_PREFIX(16) +struct Mat34V +{ + Mat34V() + { + } + Mat34V(const Vec3V& c0, const Vec3V& c1, const Vec3V& c2, const Vec3V& c3) : col0(c0), col1(c1), col2(c2), col3(c3) + { + } + Vec3V PX_ALIGN(16, col0); + Vec3V PX_ALIGN(16, col1); + Vec3V PX_ALIGN(16, col2); + Vec3V PX_ALIGN(16, col3); +} PX_ALIGN_SUFFIX(16); + +PX_ALIGN_PREFIX(16) +struct Mat43V +{ + Mat43V() + { + } + Mat43V(const Vec4V& c0, const Vec4V& c1, const Vec4V& c2) : col0(c0), col1(c1), col2(c2) + { + } + Vec4V PX_ALIGN(16, col0); + Vec4V PX_ALIGN(16, col1); + Vec4V PX_ALIGN(16, col2); +} PX_ALIGN_SUFFIX(16); + +PX_ALIGN_PREFIX(16) +struct Mat44V +{ + Mat44V() + { + } + Mat44V(const Vec4V& c0, const Vec4V& c1, const Vec4V& c2, const Vec4V& c3) : col0(c0), col1(c1), col2(c2), col3(c3) + { + } + Vec4V PX_ALIGN(16, col0); + Vec4V PX_ALIGN(16, col1); + Vec4V PX_ALIGN(16, col2); + Vec4V PX_ALIGN(16, col3); +} PX_ALIGN_SUFFIX(16); + +} // namespace aos +} // namespace physx + +#endif // PXFOUNDATION_PXUNIXNEONAOS_H diff --git a/Source/ThirdParty/PhysX/foundation/unix/neon/PxUnixNeonInlineAoS.h b/Source/ThirdParty/PhysX/foundation/unix/neon/PxUnixNeonInlineAoS.h new file mode 100644 index 000000000..9a3692aef --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/unix/neon/PxUnixNeonInlineAoS.h @@ -0,0 +1,3640 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PXFOUNDATION_PXUNIXNEONINLINEAOS_H +#define PXFOUNDATION_PXUNIXNEONINLINEAOS_H + +#if !COMPILE_VECTOR_INTRINSICS +#error Vector intrinsics should not be included when using scalar implementation. +#endif + +namespace physx +{ +namespace aos +{ + +// improved estimates +#define VRECIPEQ recipq_newton<1> +#define VRECIPE recip_newton<1> +#define VRECIPSQRTEQ rsqrtq_newton<1> +#define VRECIPSQRTE rsqrt_newton<1> + +// "exact" +#define VRECIPQ recipq_newton<4> +#if PX_SWITCH +// StabilizationTests.AveragePoint needs more precision to succeed. +#define VRECIP recip_newton<5> +#else +#define VRECIP recip_newton<4> +#endif +#define VRECIPSQRTQ rsqrtq_newton<4> +#define VRECIPSQRT rsqrt_newton<4> + +#define VECMATH_AOS_EPSILON (1e-3f) + +////////////////////////////////////////////////////////////////////// +//Test that Vec3V and FloatV are legal +////////////////////////////////// + +#define FLOAT_COMPONENTS_EQUAL_THRESHOLD 0.01f +PX_FORCE_INLINE bool isValidFloatV(const FloatV a) +{ + /* + PX_ALIGN(16, PxF32) data[4]; + vst1_f32(reinterpret_cast(data), a); + return + PxU32* intData = reinterpret_cast(data); + return intData[0] == intData[1]; + */ + PX_ALIGN(16, PxF32) data[4]; + vst1_f32(reinterpret_cast(data), a); + const float32_t x = data[0]; + const float32_t y = data[1]; + + return (x == y); + + /*if (PxAbs(x - y) < FLOAT_COMPONENTS_EQUAL_THRESHOLD) + { + return true; + } + + if (PxAbs((x - y) / x) < FLOAT_COMPONENTS_EQUAL_THRESHOLD) + { + return true; + } + + return false;*/ +} + +PX_FORCE_INLINE bool isValidVec3V(const Vec3V a) +{ + const float32_t w = vgetq_lane_f32(a, 3); + return (0.0f == w); + //const PxU32* intData = reinterpret_cast(&w); + //return *intData == 0; +} + +PX_FORCE_INLINE bool isAligned16(const void* a) +{ + return(0 == (size_t(a) & 0x0f)); +} + +#if PX_DEBUG +#define ASSERT_ISVALIDVEC3V(a) PX_ASSERT(isValidVec3V(a)) +#define ASSERT_ISVALIDFLOATV(a) PX_ASSERT(isValidFloatV(a)) +#define ASSERT_ISALIGNED16(a) PX_ASSERT(isAligned16(static_cast(a))) +#else +#define ASSERT_ISVALIDVEC3V(a) +#define ASSERT_ISVALIDFLOATV(a) +#define ASSERT_ISALIGNED16(a) +#endif + +namespace internalUnitNeonSimd +{ +PX_FORCE_INLINE PxU32 BAllTrue4_R(const BoolV a) +{ + const uint16x4_t dHigh = vget_high_u16(vreinterpretq_u16_u32(a)); + const uint16x4_t dLow = vmovn_u32(a); + const uint16x8_t combined = vcombine_u16(dLow, dHigh); + const uint32x2_t finalReduce = vreinterpret_u32_u8(vmovn_u16(combined)); + return PxU32(vget_lane_u32(finalReduce, 0) == 0xffffFFFF); +} + +PX_FORCE_INLINE PxU32 BAllTrue3_R(const BoolV a) +{ + const uint16x4_t dHigh = vget_high_u16(vreinterpretq_u16_u32(a)); + const uint16x4_t dLow = vmovn_u32(a); + const uint16x8_t combined = vcombine_u16(dLow, dHigh); + const uint32x2_t finalReduce = vreinterpret_u32_u8(vmovn_u16(combined)); + return PxU32((vget_lane_u32(finalReduce, 0) & 0xffFFff) == 0xffFFff); +} + +PX_FORCE_INLINE PxU32 BAnyTrue4_R(const BoolV a) +{ + const uint16x4_t dHigh = vget_high_u16(vreinterpretq_u16_u32(a)); + const uint16x4_t dLow = vmovn_u32(a); + const uint16x8_t combined = vcombine_u16(dLow, dHigh); + const uint32x2_t finalReduce = vreinterpret_u32_u8(vmovn_u16(combined)); + return PxU32(vget_lane_u32(finalReduce, 0) != 0x0); +} + +PX_FORCE_INLINE PxU32 BAnyTrue3_R(const BoolV a) +{ + const uint16x4_t dHigh = vget_high_u16(vreinterpretq_u16_u32(a)); + const uint16x4_t dLow = vmovn_u32(a); + const uint16x8_t combined = vcombine_u16(dLow, dHigh); + const uint32x2_t finalReduce = vreinterpret_u32_u8(vmovn_u16(combined)); + return PxU32((vget_lane_u32(finalReduce, 0) & 0xffFFff) != 0); +} +} + +namespace vecMathTests +{ +// PT: this function returns an invalid Vec3V (W!=0.0f) just for unit-testing 'isValidVec3V' +PX_FORCE_INLINE Vec3V getInvalidVec3V() +{ + PX_ALIGN(16, PxF32) data[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; + return V4LoadA(data); +} + +PX_FORCE_INLINE bool allElementsEqualFloatV(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return vget_lane_u32(vceq_f32(a, b), 0) != 0; +} + +PX_FORCE_INLINE bool allElementsEqualVec3V(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return V3AllEq(a, b) != 0; +} + +PX_FORCE_INLINE bool allElementsEqualVec4V(const Vec4V a, const Vec4V b) +{ + return V4AllEq(a, b) != 0; +} + +PX_FORCE_INLINE bool allElementsEqualBoolV(const BoolV a, const BoolV b) +{ + return internalUnitNeonSimd::BAllTrue4_R(vceqq_u32(a, b)) != 0; +} + +PX_FORCE_INLINE PxU32 V4U32AllEq(const VecU32V a, const VecU32V b) +{ + return internalUnitNeonSimd::BAllTrue4_R(V4IsEqU32(a, b)); +} + +PX_FORCE_INLINE bool allElementsEqualVecU32V(const VecU32V a, const VecU32V b) +{ + return V4U32AllEq(a, b) != 0; +} + +PX_FORCE_INLINE BoolV V4IsEqI32(const VecI32V a, const VecI32V b) +{ + return vceqq_s32(a, b); +} + +PX_FORCE_INLINE PxU32 V4I32AllEq(const VecI32V a, const VecI32V b) +{ + return internalUnitNeonSimd::BAllTrue4_R(V4IsEqI32(a, b)); +} + +PX_FORCE_INLINE bool allElementsEqualVecI32V(const VecI32V a, const VecI32V b) +{ + return V4I32AllEq(a, b) != 0; +} + +PX_FORCE_INLINE bool allElementsNearEqualFloatV(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + + const float32x2_t c = vsub_f32(a, b); + const float32x2_t error = vdup_n_f32(VECMATH_AOS_EPSILON); +// absolute compare abs(error) > abs(c) + const uint32x2_t greater = vcagt_f32(error, c); + const uint32x2_t min = vpmin_u32(greater, greater); + return vget_lane_u32(min, 0) != 0x0; +} + +PX_FORCE_INLINE bool allElementsNearEqualVec3V(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + const float32x4_t c = vsubq_f32(a, b); + const float32x4_t error = vdupq_n_f32(VECMATH_AOS_EPSILON); +// absolute compare abs(error) > abs(c) + const uint32x4_t greater = vcagtq_f32(error, c); + return internalUnitNeonSimd::BAllTrue3_R(greater) != 0; +} + +PX_FORCE_INLINE bool allElementsNearEqualVec4V(const Vec4V a, const Vec4V b) +{ + const float32x4_t c = vsubq_f32(a, b); + const float32x4_t error = vdupq_n_f32(VECMATH_AOS_EPSILON); +// absolute compare abs(error) > abs(c) + const uint32x4_t greater = vcagtq_f32(error, c); + return internalUnitNeonSimd::BAllTrue4_R(greater) != 0x0; +} +} + +#if 0 // debugging printfs +#include +PX_FORCE_INLINE void printVec(const float32x4_t& v, const char* name) +{ + PX_ALIGN(16, float32_t) data[4]; + vst1q_f32(data, v); + printf("%s: (%f, %f, %f, %f)\n", name, data[0], data[1], data[2], data[3]); +} + +PX_FORCE_INLINE void printVec(const float32x2_t& v, const char* name) +{ + PX_ALIGN(16, float32_t) data[2]; + vst1_f32(data, v); + printf("%s: (%f, %f)\n", name, data[0], data[1]); +} + +PX_FORCE_INLINE void printVec(const uint32x4_t& v, const char* name) +{ + PX_ALIGN(16, uint32_t) data[4]; + vst1q_u32(data, v); + printf("%s: (0x%x, 0x%x, 0x%x, 0x%x)\n", name, data[0], data[1], data[2], data[3]); +} + +PX_FORCE_INLINE void printVec(const uint16x8_t& v, const char* name) +{ + PX_ALIGN(16, uint16_t) data[8]; + vst1q_u16(data, v); + printf("%s: (0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n", name, data[0], data[1], data[2], data[3], + data[4], data[5], data[6], data[7]); +} + +PX_FORCE_INLINE void printVec(const int32x4_t& v, const char* name) +{ + PX_ALIGN(16, int32_t) data[4]; + vst1q_s32(data, v); + printf("%s: (0x%x, 0x%x, 0x%x, 0x%x)\n", name, data[0], data[1], data[2], data[3]); +} + +PX_FORCE_INLINE void printVec(const int16x8_t& v, const char* name) +{ + PX_ALIGN(16, int16_t) data[8]; + vst1q_s16(data, v); + printf("%s: (0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x)\n", name, data[0], data[1], data[2], data[3], + data[4], data[5], data[6], data[7]); +} + +PX_FORCE_INLINE void printVec(const uint16x4_t& v, const char* name) +{ + PX_ALIGN(16, uint16_t) data[4]; + vst1_u16(data, v); + printf("%s: (0x%x, 0x%x, 0x%x, 0x%x)\n", name, data[0], data[1], data[2], data[3]); +} + +PX_FORCE_INLINE void printVec(const uint32x2_t& v, const char* name) +{ + PX_ALIGN(16, uint32_t) data[2]; + vst1_u32(data, v); + printf("%s: (0x%x, 0x%x)\n", name, data[0], data[1]); +} + +PX_FORCE_INLINE void printVar(const PxU32 v, const char* name) +{ + printf("%s: 0x%x\n", name, v); +} + +PX_FORCE_INLINE void printVar(const PxF32 v, const char* name) +{ + printf("%s: %f\n", name, v); +} + +#define PRINT_VAR(X) printVar((X), #X) +#define PRINT_VEC(X) printVec((X), #X) +#define PRINT_VEC_TITLE(TITLE, X) printVec((X), TITLE #X) +#endif // debugging printf + +///////////////////////////////////////////////////////////////////// +////FUNCTIONS USED ONLY FOR ASSERTS IN VECTORISED IMPLEMENTATIONS +///////////////////////////////////////////////////////////////////// + +PX_FORCE_INLINE bool isFiniteFloatV(const FloatV a) +{ + PX_ALIGN(16, PxF32) data[4]; + vst1_f32(reinterpret_cast(data), a); + return PxIsFinite(data[0]) && PxIsFinite(data[1]); +} + +PX_FORCE_INLINE bool isFiniteVec3V(const Vec3V a) +{ + PX_ALIGN(16, PxF32) data[4]; + vst1q_f32(reinterpret_cast(data), a); + return PxIsFinite(data[0]) && PxIsFinite(data[1]) && PxIsFinite(data[2]); +} + +PX_FORCE_INLINE bool isFiniteVec4V(const Vec4V a) +{ + PX_ALIGN(16, PxF32) data[4]; + vst1q_f32(reinterpret_cast(data), a); + return PxIsFinite(data[0]) && PxIsFinite(data[1]) && PxIsFinite(data[2]) && PxIsFinite(data[3]); +} + +PX_FORCE_INLINE bool hasZeroElementinFloatV(const FloatV a) +{ + ASSERT_ISVALIDFLOATV(a); + return vget_lane_u32(vreinterpret_u32_f32(a), 0) == 0; +} + +PX_FORCE_INLINE bool hasZeroElementInVec3V(const Vec3V a) +{ + const uint32x2_t dLow = vget_low_u32(vreinterpretq_u32_f32(a)); + const uint32x2_t dMin = vpmin_u32(dLow, dLow); + + return vget_lane_u32(dMin, 0) == 0 || vgetq_lane_u32(vreinterpretq_u32_f32(a), 2) == 0; +} + +PX_FORCE_INLINE bool hasZeroElementInVec4V(const Vec4V a) +{ + const uint32x2_t dHigh = vget_high_u32(vreinterpretq_u32_f32(a)); + const uint32x2_t dLow = vget_low_u32(vreinterpretq_u32_f32(a)); + + const uint32x2_t dMin = vmin_u32(dHigh, dLow); + const uint32x2_t pairMin = vpmin_u32(dMin, dMin); + return vget_lane_u32(pairMin, 0) == 0; +} + +///////////////////////////////////////////////////////////////////// +////VECTORISED FUNCTION IMPLEMENTATIONS +///////////////////////////////////////////////////////////////////// + +PX_FORCE_INLINE FloatV FLoad(const PxF32 f) +{ + return vdup_n_f32(reinterpret_cast(f)); +} + +PX_FORCE_INLINE FloatV FLoadA(const PxF32* const f) +{ + ASSERT_ISALIGNED16(f); + return vld1_f32(reinterpret_cast(f)); +} + +PX_FORCE_INLINE Vec3V V3Load(const PxF32 f) +{ + PX_ALIGN(16, PxF32) data[4] = { f, f, f, 0.0f }; + return V4LoadA(data); +} + +PX_FORCE_INLINE Vec4V V4Load(const PxF32 f) +{ + return vdupq_n_f32(reinterpret_cast(f)); +} + +PX_FORCE_INLINE BoolV BLoad(const bool f) +{ + const PxU32 i = static_cast(-(static_cast(f))); + return vdupq_n_u32(i); +} + +PX_FORCE_INLINE Vec3V V3LoadA(const PxVec3& f) +{ + ASSERT_ISALIGNED16(&f); + PX_ALIGN(16, PxF32) data[4] = { f.x, f.y, f.z, 0.0f }; + return V4LoadA(data); +} + +PX_FORCE_INLINE Vec3V V3LoadU(const PxVec3& f) +{ + PX_ALIGN(16, PxF32) data[4] = { f.x, f.y, f.z, 0.0f }; + return V4LoadA(data); +} + +PX_FORCE_INLINE Vec3V V3LoadUnsafeA(const PxVec3& f) +{ + ASSERT_ISALIGNED16(&f); + PX_ALIGN(16, PxF32) data[4] = { f.x, f.y, f.z, 0.0f }; + return V4LoadA(data); +} + +PX_FORCE_INLINE Vec3V V3LoadA(const PxF32* f) +{ + ASSERT_ISALIGNED16(f); + PX_ALIGN(16, PxF32) data[4] = { f[0], f[1], f[2], 0.0f }; + return V4LoadA(data); +} + +PX_FORCE_INLINE Vec3V V3LoadU(const PxF32* f) +{ + PX_ALIGN(16, PxF32) data[4] = { f[0], f[1], f[2], 0.0f }; + return V4LoadA(data); +} + +PX_FORCE_INLINE Vec3V Vec3V_From_Vec4V(Vec4V v) +{ + return vsetq_lane_f32(0.0f, v, 3); +} + +PX_FORCE_INLINE Vec3V Vec3V_From_Vec4V_WUndefined(Vec4V v) +{ + return v; +} + +PX_FORCE_INLINE Vec4V Vec4V_From_Vec3V(Vec3V f) +{ + return f; // ok if it is implemented as the same type. +} + +PX_FORCE_INLINE Vec4V Vec4V_From_FloatV(FloatV f) +{ + return vcombine_f32(f, f); +} + +PX_FORCE_INLINE Vec3V Vec3V_From_FloatV(FloatV f) +{ + return Vec3V_From_Vec4V(Vec4V_From_FloatV(f)); +} + +PX_FORCE_INLINE Vec3V Vec3V_From_FloatV_WUndefined(FloatV f) +{ + return Vec3V_From_Vec4V_WUndefined(Vec4V_From_FloatV(f)); +} + +PX_FORCE_INLINE Vec4V Vec4V_From_PxVec3_WUndefined(const PxVec3& f) +{ + PX_ALIGN(16, PxF32) data[4] = { f.x, f.y, f.z, 0.0f }; + return V4LoadA(data); +} + +PX_FORCE_INLINE Mat33V Mat33V_From_PxMat33(const PxMat33& m) +{ + return Mat33V(V3LoadU(m.column0), V3LoadU(m.column1), V3LoadU(m.column2)); +} + +PX_FORCE_INLINE void PxMat33_From_Mat33V(const Mat33V& m, PxMat33& out) +{ + V3StoreU(m.col0, out.column0); + V3StoreU(m.col1, out.column1); + V3StoreU(m.col2, out.column2); +} + +PX_FORCE_INLINE Vec4V V4LoadA(const PxF32* const f) +{ + ASSERT_ISALIGNED16(f); + return vld1q_f32(reinterpret_cast(f)); +} + +PX_FORCE_INLINE void V4StoreA(Vec4V a, PxF32* f) +{ + ASSERT_ISALIGNED16(f); + vst1q_f32(reinterpret_cast(f), a); +} + +PX_FORCE_INLINE void V4StoreU(const Vec4V a, PxF32* f) +{ + PX_ALIGN(16, PxF32) f2[4]; + vst1q_f32(reinterpret_cast(f2), a); + f[0] = f2[0]; + f[1] = f2[1]; + f[2] = f2[2]; + f[3] = f2[3]; +} + +PX_FORCE_INLINE void BStoreA(const BoolV a, PxU32* u) +{ + ASSERT_ISALIGNED16(u); + vst1q_u32(reinterpret_cast(u), a); +} + +PX_FORCE_INLINE void U4StoreA(const VecU32V uv, PxU32* u) +{ + ASSERT_ISALIGNED16(u); + vst1q_u32(reinterpret_cast(u), uv); +} + +PX_FORCE_INLINE void I4StoreA(const VecI32V iv, PxI32* i) +{ + ASSERT_ISALIGNED16(i); + vst1q_s32(reinterpret_cast(i), iv); +} + +PX_FORCE_INLINE Vec4V V4LoadU(const PxF32* const f) +{ + return vld1q_f32(reinterpret_cast(f)); +} + +PX_FORCE_INLINE BoolV BLoad(const bool* const f) +{ + const PX_ALIGN(16, PxU32) b[4] = { static_cast(-static_cast(f[0])), + static_cast(-static_cast(f[1])), + static_cast(-static_cast(f[2])), + static_cast(-static_cast(f[3])) }; + return vld1q_u32(b); +} + +PX_FORCE_INLINE void FStore(const FloatV a, PxF32* PX_RESTRICT f) +{ + ASSERT_ISVALIDFLOATV(a); + // vst1q_lane_f32(f, a, 0); // causes vst1 alignment bug + *f = vget_lane_f32(a, 0); +} + +PX_FORCE_INLINE void Store_From_BoolV(const BoolV a, PxU32* PX_RESTRICT f) +{ + *f = vget_lane_u32(vget_low_u32(a), 0); +} + +PX_FORCE_INLINE void V3StoreA(const Vec3V a, PxVec3& f) +{ + ASSERT_ISALIGNED16(&f); + PX_ALIGN(16, PxF32) f2[4]; + vst1q_f32(reinterpret_cast(f2), a); + f = PxVec3(f2[0], f2[1], f2[2]); +} + +PX_FORCE_INLINE void V3StoreU(const Vec3V a, PxVec3& f) +{ + PX_ALIGN(16, PxF32) f2[4]; + vst1q_f32(reinterpret_cast(f2), a); + f = PxVec3(f2[0], f2[1], f2[2]); +} + +////////////////////////////////// +// FLOATV +////////////////////////////////// + +PX_FORCE_INLINE FloatV FZero() +{ + return FLoad(0.0f); +} + +PX_FORCE_INLINE FloatV FOne() +{ + return FLoad(1.0f); +} + +PX_FORCE_INLINE FloatV FHalf() +{ + return FLoad(0.5f); +} + +PX_FORCE_INLINE FloatV FEps() +{ + return FLoad(PX_EPS_REAL); +} + +PX_FORCE_INLINE FloatV FEps6() +{ + return FLoad(1e-6f); +} + +PX_FORCE_INLINE FloatV FMax() +{ + return FLoad(PX_MAX_REAL); +} + +PX_FORCE_INLINE FloatV FNegMax() +{ + return FLoad(-PX_MAX_REAL); +} + +PX_FORCE_INLINE FloatV IZero() +{ + return vreinterpret_f32_u32(vdup_n_u32(0)); +} + +PX_FORCE_INLINE FloatV IOne() +{ + return vreinterpret_f32_u32(vdup_n_u32(1)); +} + +PX_FORCE_INLINE FloatV ITwo() +{ + return vreinterpret_f32_u32(vdup_n_u32(2)); +} + +PX_FORCE_INLINE FloatV IThree() +{ + return vreinterpret_f32_u32(vdup_n_u32(3)); +} + +PX_FORCE_INLINE FloatV IFour() +{ + return vreinterpret_f32_u32(vdup_n_u32(4)); +} + +PX_FORCE_INLINE FloatV FNeg(const FloatV f) +{ + ASSERT_ISVALIDFLOATV(f); + return vneg_f32(f); +} + +PX_FORCE_INLINE FloatV FAdd(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return vadd_f32(a, b); +} + +PX_FORCE_INLINE FloatV FSub(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return vsub_f32(a, b); +} + +PX_FORCE_INLINE FloatV FMul(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return vmul_f32(a, b); +} + +template +PX_FORCE_INLINE float32x2_t recip_newton(const float32x2_t& in) +{ + float32x2_t recip = vrecpe_f32(in); + for(int i = 0; i < n; ++i) + recip = vmul_f32(recip, vrecps_f32(in, recip)); + return recip; +} + +template +PX_FORCE_INLINE float32x4_t recipq_newton(const float32x4_t& in) +{ + float32x4_t recip = vrecpeq_f32(in); + for(int i = 0; i < n; ++i) + recip = vmulq_f32(recip, vrecpsq_f32(recip, in)); + return recip; +} + +template +PX_FORCE_INLINE float32x2_t rsqrt_newton(const float32x2_t& in) +{ + float32x2_t rsqrt = vrsqrte_f32(in); + for(int i = 0; i < n; ++i) + rsqrt = vmul_f32(rsqrt, vrsqrts_f32(vmul_f32(rsqrt, rsqrt), in)); + return rsqrt; +} + +template +PX_FORCE_INLINE float32x4_t rsqrtq_newton(const float32x4_t& in) +{ + float32x4_t rsqrt = vrsqrteq_f32(in); + for(int i = 0; i < n; ++i) + rsqrt = vmulq_f32(rsqrt, vrsqrtsq_f32(vmulq_f32(rsqrt, rsqrt), in)); + return rsqrt; +} + +PX_FORCE_INLINE FloatV FDiv(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return vmul_f32(a, VRECIP(b)); +} + +PX_FORCE_INLINE FloatV FDivFast(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return vmul_f32(a, VRECIPE(b)); +} + +PX_FORCE_INLINE FloatV FRecip(const FloatV a) +{ + ASSERT_ISVALIDFLOATV(a); + return VRECIP(a); +} + +PX_FORCE_INLINE FloatV FRecipFast(const FloatV a) +{ + ASSERT_ISVALIDFLOATV(a); + return VRECIPE(a); +} + +PX_FORCE_INLINE FloatV FRsqrt(const FloatV a) +{ + ASSERT_ISVALIDFLOATV(a); + return VRECIPSQRT(a); +} + +PX_FORCE_INLINE FloatV FSqrt(const FloatV a) +{ + ASSERT_ISVALIDFLOATV(a); + return FSel(FIsEq(a, FZero()), a, vmul_f32(a, VRECIPSQRT(a))); +} + +PX_FORCE_INLINE FloatV FRsqrtFast(const FloatV a) +{ + ASSERT_ISVALIDFLOATV(a); + return VRECIPSQRTE(a); +} + +PX_FORCE_INLINE FloatV FScaleAdd(const FloatV a, const FloatV b, const FloatV c) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + ASSERT_ISVALIDFLOATV(c); + return vmla_f32(c, a, b); +} + +PX_FORCE_INLINE FloatV FNegScaleSub(const FloatV a, const FloatV b, const FloatV c) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + ASSERT_ISVALIDFLOATV(c); + return vmls_f32(c, a, b); +} + +PX_FORCE_INLINE FloatV FAbs(const FloatV a) +{ + ASSERT_ISVALIDFLOATV(a); + return vabs_f32(a); +} + +PX_FORCE_INLINE FloatV FSel(const BoolV c, const FloatV a, const FloatV b) +{ + PX_ASSERT( vecMathTests::allElementsEqualBoolV(c, BTTTT()) || + vecMathTests::allElementsEqualBoolV(c, BFFFF())); + ASSERT_ISVALIDFLOATV(vbsl_f32(vget_low_u32(c), a, b)); + return vbsl_f32(vget_low_u32(c), a, b); +} + +PX_FORCE_INLINE BoolV FIsGrtr(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return vdupq_lane_u32(vcgt_f32(a, b), 0); +} + +PX_FORCE_INLINE BoolV FIsGrtrOrEq(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return vdupq_lane_u32(vcge_f32(a, b), 0); +} + +PX_FORCE_INLINE BoolV FIsEq(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return vdupq_lane_u32(vceq_f32(a, b), 0); +} + +PX_FORCE_INLINE FloatV FMax(const FloatV a, const FloatV b) +{ + //ASSERT_ISVALIDFLOATV(a); + //ASSERT_ISVALIDFLOATV(b); + return vmax_f32(a, b); +} + +PX_FORCE_INLINE FloatV FMin(const FloatV a, const FloatV b) +{ + //ASSERT_ISVALIDFLOATV(a); + //ASSERT_ISVALIDFLOATV(b); + return vmin_f32(a, b); +} + +PX_FORCE_INLINE FloatV FClamp(const FloatV a, const FloatV minV, const FloatV maxV) +{ + ASSERT_ISVALIDFLOATV(minV); + ASSERT_ISVALIDFLOATV(maxV); + return vmax_f32(vmin_f32(a, maxV), minV); +} + +PX_FORCE_INLINE PxU32 FAllGrtr(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return vget_lane_u32(vcgt_f32(a, b), 0); +} + +PX_FORCE_INLINE PxU32 FAllGrtrOrEq(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return vget_lane_u32(vcge_f32(a, b), 0); +} + +PX_FORCE_INLINE PxU32 FAllEq(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return vget_lane_u32(vceq_f32(a, b), 0); +} + +PX_FORCE_INLINE FloatV FRound(const FloatV a) +{ + ASSERT_ISVALIDFLOATV(a); + + // truncate(a + (0.5f - sign(a))) + const float32x2_t half = vdup_n_f32(0.5f); + const float32x2_t sign = vcvt_f32_u32((vshr_n_u32(vreinterpret_u32_f32(a), 31))); + const float32x2_t aPlusHalf = vadd_f32(a, half); + const float32x2_t aRound = vsub_f32(aPlusHalf, sign); + int32x2_t tmp = vcvt_s32_f32(aRound); + return vcvt_f32_s32(tmp); +} + +PX_FORCE_INLINE FloatV FSin(const FloatV a) +{ + ASSERT_ISVALIDFLOATV(a); + + // Modulo the range of the given angles such that -XM_2PI <= Angles < XM_2PI + const FloatV recipTwoPi = FLoadA(g_PXReciprocalTwoPi.f); + const FloatV twoPi = FLoadA(g_PXTwoPi.f); + const FloatV tmp = FMul(a, recipTwoPi); + const FloatV b = FRound(tmp); + const FloatV V1 = FNegScaleSub(twoPi, b, a); + + // sin(V) ~= V - V^3 / 3! + V^5 / 5! - V^7 / 7! + V^9 / 9! - V^11 / 11! + V^13 / 13! - + // V^15 / 15! + V^17 / 17! - V^19 / 19! + V^21 / 21! - V^23 / 23! (for -PI <= V < PI) + const FloatV V2 = FMul(V1, V1); + const FloatV V3 = FMul(V2, V1); + const FloatV V5 = FMul(V3, V2); + const FloatV V7 = FMul(V5, V2); + const FloatV V9 = FMul(V7, V2); + const FloatV V11 = FMul(V9, V2); + const FloatV V13 = FMul(V11, V2); + const FloatV V15 = FMul(V13, V2); + const FloatV V17 = FMul(V15, V2); + const FloatV V19 = FMul(V17, V2); + const FloatV V21 = FMul(V19, V2); + const FloatV V23 = FMul(V21, V2); + + const Vec4V sinCoefficients0 = V4LoadA(g_PXSinCoefficients0.f); + const Vec4V sinCoefficients1 = V4LoadA(g_PXSinCoefficients1.f); + const Vec4V sinCoefficients2 = V4LoadA(g_PXSinCoefficients2.f); + + const FloatV S1 = V4GetY(sinCoefficients0); + const FloatV S2 = V4GetZ(sinCoefficients0); + const FloatV S3 = V4GetW(sinCoefficients0); + const FloatV S4 = V4GetX(sinCoefficients1); + const FloatV S5 = V4GetY(sinCoefficients1); + const FloatV S6 = V4GetZ(sinCoefficients1); + const FloatV S7 = V4GetW(sinCoefficients1); + const FloatV S8 = V4GetX(sinCoefficients2); + const FloatV S9 = V4GetY(sinCoefficients2); + const FloatV S10 = V4GetZ(sinCoefficients2); + const FloatV S11 = V4GetW(sinCoefficients2); + + FloatV Result; + Result = FScaleAdd(S1, V3, V1); + Result = FScaleAdd(S2, V5, Result); + Result = FScaleAdd(S3, V7, Result); + Result = FScaleAdd(S4, V9, Result); + Result = FScaleAdd(S5, V11, Result); + Result = FScaleAdd(S6, V13, Result); + Result = FScaleAdd(S7, V15, Result); + Result = FScaleAdd(S8, V17, Result); + Result = FScaleAdd(S9, V19, Result); + Result = FScaleAdd(S10, V21, Result); + Result = FScaleAdd(S11, V23, Result); + + return Result; +} + +PX_FORCE_INLINE FloatV FCos(const FloatV a) +{ + ASSERT_ISVALIDFLOATV(a); + + // Modulo the range of the given angles such that -XM_2PI <= Angles < XM_2PI + const FloatV recipTwoPi = FLoadA(g_PXReciprocalTwoPi.f); + const FloatV twoPi = FLoadA(g_PXTwoPi.f); + const FloatV tmp = FMul(a, recipTwoPi); + const FloatV b = FRound(tmp); + const FloatV V1 = FNegScaleSub(twoPi, b, a); + + // cos(V) ~= 1 - V^2 / 2! + V^4 / 4! - V^6 / 6! + V^8 / 8! - V^10 / 10! + V^12 / 12! - + // V^14 / 14! + V^16 / 16! - V^18 / 18! + V^20 / 20! - V^22 / 22! (for -PI <= V < PI) + const FloatV V2 = FMul(V1, V1); + const FloatV V4 = FMul(V2, V2); + const FloatV V6 = FMul(V4, V2); + const FloatV V8 = FMul(V4, V4); + const FloatV V10 = FMul(V6, V4); + const FloatV V12 = FMul(V6, V6); + const FloatV V14 = FMul(V8, V6); + const FloatV V16 = FMul(V8, V8); + const FloatV V18 = FMul(V10, V8); + const FloatV V20 = FMul(V10, V10); + const FloatV V22 = FMul(V12, V10); + + const Vec4V cosCoefficients0 = V4LoadA(g_PXCosCoefficients0.f); + const Vec4V cosCoefficients1 = V4LoadA(g_PXCosCoefficients1.f); + const Vec4V cosCoefficients2 = V4LoadA(g_PXCosCoefficients2.f); + + const FloatV C1 = V4GetY(cosCoefficients0); + const FloatV C2 = V4GetZ(cosCoefficients0); + const FloatV C3 = V4GetW(cosCoefficients0); + const FloatV C4 = V4GetX(cosCoefficients1); + const FloatV C5 = V4GetY(cosCoefficients1); + const FloatV C6 = V4GetZ(cosCoefficients1); + const FloatV C7 = V4GetW(cosCoefficients1); + const FloatV C8 = V4GetX(cosCoefficients2); + const FloatV C9 = V4GetY(cosCoefficients2); + const FloatV C10 = V4GetZ(cosCoefficients2); + const FloatV C11 = V4GetW(cosCoefficients2); + + FloatV Result; + Result = FScaleAdd(C1, V2, FOne()); + Result = FScaleAdd(C2, V4, Result); + Result = FScaleAdd(C3, V6, Result); + Result = FScaleAdd(C4, V8, Result); + Result = FScaleAdd(C5, V10, Result); + Result = FScaleAdd(C6, V12, Result); + Result = FScaleAdd(C7, V14, Result); + Result = FScaleAdd(C8, V16, Result); + Result = FScaleAdd(C9, V18, Result); + Result = FScaleAdd(C10, V20, Result); + Result = FScaleAdd(C11, V22, Result); + + return Result; +} + +PX_FORCE_INLINE PxU32 FOutOfBounds(const FloatV a, const FloatV min, const FloatV max) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(min); + ASSERT_ISVALIDFLOATV(max); + + const BoolV c = BOr(FIsGrtr(a, max), FIsGrtr(min, a)); + return PxU32(!BAllEqFFFF(c)); +} + +PX_FORCE_INLINE PxU32 FInBounds(const FloatV a, const FloatV min, const FloatV max) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(min); + ASSERT_ISVALIDFLOATV(max); + + const BoolV c = BAnd(FIsGrtrOrEq(a, min), FIsGrtrOrEq(max, a)); + return PxU32(BAllEqTTTT(c)); +} + +PX_FORCE_INLINE PxU32 FOutOfBounds(const FloatV a, const FloatV bounds) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(bounds); + const uint32x2_t greater = vcagt_f32(a, bounds); + return vget_lane_u32(greater, 0); +} + +PX_FORCE_INLINE PxU32 FInBounds(const FloatV a, const FloatV bounds) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(bounds); + const uint32x2_t geq = vcage_f32(bounds, a); + return vget_lane_u32(geq, 0); +} + +////////////////////////////////// +// VEC3V +////////////////////////////////// + +PX_FORCE_INLINE Vec3V V3Splat(const FloatV f) +{ + ASSERT_ISVALIDFLOATV(f); + + const uint32x2_t mask = { 0xffffFFFF, 0x0 }; + const uint32x2_t uHigh = vreinterpret_u32_f32(f); + const float32x2_t dHigh = vreinterpret_f32_u32(vand_u32(uHigh, mask)); + + return vcombine_f32(f, dHigh); +} + +PX_FORCE_INLINE Vec3V V3Merge(const FloatVArg x, const FloatVArg y, const FloatVArg z) +{ + ASSERT_ISVALIDFLOATV(x); + ASSERT_ISVALIDFLOATV(y); + ASSERT_ISVALIDFLOATV(z); + + const uint32x2_t mask = { 0xffffFFFF, 0x0 }; + const uint32x2_t dHigh = vand_u32(vreinterpret_u32_f32(z), mask); + const uint32x2_t dLow = vext_u32(vreinterpret_u32_f32(x), vreinterpret_u32_f32(y), 1); + return vreinterpretq_f32_u32(vcombine_u32(dLow, dHigh)); +} + +PX_FORCE_INLINE Vec3V V3UnitX() +{ + const float32x4_t x = { 1.0f, 0.0f, 0.0f, 0.0f }; + return x; +} + +PX_FORCE_INLINE Vec3V V3UnitY() +{ + const float32x4_t y = { 0, 1.0f, 0, 0 }; + return y; +} + +PX_FORCE_INLINE Vec3V V3UnitZ() +{ + const float32x4_t z = { 0, 0, 1.0f, 0 }; + return z; +} + +PX_FORCE_INLINE FloatV V3GetX(const Vec3V f) +{ + ASSERT_ISVALIDVEC3V(f); + const float32x2_t fLow = vget_low_f32(f); + return vdup_lane_f32(fLow, 0); +} + +PX_FORCE_INLINE FloatV V3GetY(const Vec3V f) +{ + ASSERT_ISVALIDVEC3V(f); + const float32x2_t fLow = vget_low_f32(f); + return vdup_lane_f32(fLow, 1); +} + +PX_FORCE_INLINE FloatV V3GetZ(const Vec3V f) +{ + ASSERT_ISVALIDVEC3V(f); + const float32x2_t fhigh = vget_high_f32(f); + return vdup_lane_f32(fhigh, 0); +} + +PX_FORCE_INLINE Vec3V V3SetX(const Vec3V v, const FloatV f) +{ + ASSERT_ISVALIDVEC3V(v); + ASSERT_ISVALIDFLOATV(f); + return V4Sel(BFTTT(), v, vcombine_f32(f, f)); +} + +PX_FORCE_INLINE Vec3V V3SetY(const Vec3V v, const FloatV f) +{ + ASSERT_ISVALIDVEC3V(v); + ASSERT_ISVALIDFLOATV(f); + return V4Sel(BTFTT(), v, vcombine_f32(f, f)); +} + +PX_FORCE_INLINE Vec3V V3SetZ(const Vec3V v, const FloatV f) +{ + ASSERT_ISVALIDVEC3V(v); + ASSERT_ISVALIDFLOATV(f); + return V4Sel(BTTFT(), v, vcombine_f32(f, f)); +} + +PX_FORCE_INLINE Vec3V V3ColX(const Vec3V a, const Vec3V b, const Vec3V c) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + ASSERT_ISVALIDVEC3V(c); + + const float32x2_t aLow = vget_low_f32(a); + const float32x2_t bLow = vget_low_f32(b); + const float32x2_t cLow = vget_low_f32(c); + const float32x2_t zero = vdup_n_f32(0.0f); + + const float32x2x2_t zipL = vzip_f32(aLow, bLow); + const float32x2x2_t zipH = vzip_f32(cLow, zero); + + return vcombine_f32(zipL.val[0], zipH.val[0]); +} + +PX_FORCE_INLINE Vec3V V3ColY(const Vec3V a, const Vec3V b, const Vec3V c) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + ASSERT_ISVALIDVEC3V(c); + + const float32x2_t aLow = vget_low_f32(a); + const float32x2_t bLow = vget_low_f32(b); + const float32x2_t cLow = vget_low_f32(c); + const float32x2_t zero = vdup_n_f32(0.0f); + + const float32x2x2_t zipL = vzip_f32(aLow, bLow); + const float32x2x2_t zipH = vzip_f32(cLow, zero); + + return vcombine_f32(zipL.val[1], zipH.val[1]); +} + +PX_FORCE_INLINE Vec3V V3ColZ(const Vec3V a, const Vec3V b, const Vec3V c) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + ASSERT_ISVALIDVEC3V(c); + + const float32x2_t aHi = vget_high_f32(a); + const float32x2_t bHi = vget_high_f32(b); + const float32x2_t cHi = vget_high_f32(c); + + const float32x2x2_t zipL = vzip_f32(aHi, bHi); + + return vcombine_f32(zipL.val[0], cHi); +} + +PX_FORCE_INLINE Vec3V V3Zero() +{ + return vdupq_n_f32(0.0f); +} + +PX_FORCE_INLINE Vec3V V3Eps() +{ + return V3Load(PX_EPS_REAL); +} + +PX_FORCE_INLINE Vec3V V3One() +{ + return V3Load(1.0f); +} + +PX_FORCE_INLINE Vec3V V3Neg(const Vec3V f) +{ + ASSERT_ISVALIDVEC3V(f); + const float32x4_t tmp = vnegq_f32(f); + return vsetq_lane_f32(0.0f, tmp, 3); +} + +PX_FORCE_INLINE Vec3V V3Add(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return vaddq_f32(a, b); +} + +PX_FORCE_INLINE Vec3V V3Add(const Vec3V a, const FloatV b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDFLOATV(b); + return vaddq_f32(a, Vec3V_From_FloatV(b)); +} + +PX_FORCE_INLINE Vec3V V3Sub(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return vsubq_f32(a, b); +} + +PX_FORCE_INLINE Vec3V V3Sub(const Vec3V a, const FloatV b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDFLOATV(b); + return vsubq_f32(a, Vec3V_From_FloatV(b)); +} + +PX_FORCE_INLINE Vec3V V3Scale(const Vec3V a, const FloatV b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDFLOATV(b); + const float32x4_t tmp = vmulq_lane_f32(a, b, 0); + return vsetq_lane_f32(0.0f, tmp, 3); +} + +PX_FORCE_INLINE Vec3V V3Mul(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return vmulq_f32(a, b); +} + +PX_FORCE_INLINE Vec3V V3ScaleInv(const Vec3V a, const FloatV b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDFLOATV(b); + const float32x2_t invB = VRECIP(b); + const float32x4_t tmp = vmulq_lane_f32(a, invB, 0); + return vsetq_lane_f32(0.0f, tmp, 3); +} + +PX_FORCE_INLINE Vec3V V3Div(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + float32x4_t invB = VRECIPQ(b); + invB = vsetq_lane_f32(0.0f, invB, 3); + return vmulq_f32(a, invB); +} + +PX_FORCE_INLINE Vec3V V3ScaleInvFast(const Vec3V a, const FloatV b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDFLOATV(b); + const float32x2_t invB = VRECIPE(b); + const float32x4_t tmp = vmulq_lane_f32(a, invB, 0); + return vsetq_lane_f32(0.0f, tmp, 3); +} + +PX_FORCE_INLINE Vec3V V3DivFast(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + float32x4_t invB = VRECIPEQ(b); + invB = vsetq_lane_f32(0.0f, invB, 3); + return vmulq_f32(a, invB); +} + +PX_FORCE_INLINE Vec3V V3Recip(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + const float32x4_t recipA = VRECIPQ(a); + return vsetq_lane_f32(0.0f, recipA, 3); +} + +PX_FORCE_INLINE Vec3V V3RecipFast(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + const float32x4_t recipA = VRECIPEQ(a); + return vsetq_lane_f32(0.0f, recipA, 3); +} + +PX_FORCE_INLINE Vec3V V3Rsqrt(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + const float32x4_t rSqrA = VRECIPSQRTQ(a); + return vsetq_lane_f32(0.0f, rSqrA, 3); +} + +PX_FORCE_INLINE Vec3V V3RsqrtFast(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + const float32x4_t rSqrA = VRECIPSQRTEQ(a); + return vsetq_lane_f32(0.0f, rSqrA, 3); +} + +PX_FORCE_INLINE Vec3V V3ScaleAdd(const Vec3V a, const FloatV b, const Vec3V c) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDFLOATV(b); + ASSERT_ISVALIDVEC3V(c); + + float32x4_t tmp = vmlaq_lane_f32(c, a, b, 0); + // using vsetq_lane_f32 resulted in failures, + // probably related to a compiler bug on + // ndk r9d-win32, gcc 4.8, cardhu/shield + + // code with issue + // return vsetq_lane_f32(0.0f, tmp, 3); + + // workaround + float32x2_t w_z = vget_high_f32(tmp); + float32x2_t y_x = vget_low_f32(tmp); + w_z = vset_lane_f32(0.0f, w_z, 1); + return vcombine_f32(y_x, w_z); +} + +PX_FORCE_INLINE Vec3V V3NegScaleSub(const Vec3V a, const FloatV b, const Vec3V c) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDFLOATV(b); + ASSERT_ISVALIDVEC3V(c); + + float32x4_t tmp = vmlsq_lane_f32(c, a, b, 0); + // using vsetq_lane_f32 resulted in failures, + // probably related to a compiler bug on + // ndk r9d-win32, gcc 4.8, cardhu/shield + + // code with issue + // return vsetq_lane_f32(0.0f, tmp, 3); + + // workaround + float32x2_t w_z = vget_high_f32(tmp); + float32x2_t y_x = vget_low_f32(tmp); + w_z = vset_lane_f32(0.0f, w_z, 1); + return vcombine_f32(y_x, w_z); +} + +PX_FORCE_INLINE Vec3V V3MulAdd(const Vec3V a, const Vec3V b, const Vec3V c) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + ASSERT_ISVALIDVEC3V(c); + return vmlaq_f32(c, a, b); +} + +PX_FORCE_INLINE Vec3V V3NegMulSub(const Vec3V a, const Vec3V b, const Vec3V c) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + ASSERT_ISVALIDVEC3V(c); + return vmlsq_f32(c, a, b); +} + +PX_FORCE_INLINE Vec3V V3Abs(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + return vabsq_f32(a); +} + +PX_FORCE_INLINE FloatV V3Dot(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + + // const uint32x2_t mask = {0xffffFFFF, 0x0}; + const float32x4_t tmp = vmulq_f32(a, b); + + const float32x2_t low = vget_low_f32(tmp); + const float32x2_t high = vget_high_f32(tmp); + // const float32x2_t high = vreinterpret_f32_u32(vand_u32(vreinterpret_u32_f32(high_), mask)); + + const float32x2_t sumTmp = vpadd_f32(low, high); // = {0+z, x+y} + const float32x2_t sum0ZYX = vpadd_f32(sumTmp, sumTmp); // = {x+y+z, x+y+z} + + return sum0ZYX; +} + +PX_FORCE_INLINE Vec3V V3Cross(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + + const uint32x2_t TF = { 0xffffFFFF, 0x0 }; + const float32x2_t ay_ax = vget_low_f32(a); // d2 + const float32x2_t aw_az = vget_high_f32(a); // d3 + const float32x2_t by_bx = vget_low_f32(b); // d4 + const float32x2_t bw_bz = vget_high_f32(b); // d5 + // Hi, Lo + const float32x2_t bz_by = vext_f32(by_bx, bw_bz, 1); // bz, by + const float32x2_t az_ay = vext_f32(ay_ax, aw_az, 1); // az, ay + + const float32x2_t azbx = vmul_f32(aw_az, by_bx); // 0, az*bx + const float32x2_t aybz_axby = vmul_f32(ay_ax, bz_by); // ay*bz, ax*by + + const float32x2_t azbxSUBaxbz = vmls_f32(azbx, bw_bz, ay_ax); // 0, az*bx-ax*bz + const float32x2_t aybzSUBazby_axbySUBaybx = vmls_f32(aybz_axby, by_bx, az_ay); // ay*bz-az*by, ax*by-ay*bx + + const float32x2_t retLow = vext_f32(aybzSUBazby_axbySUBaybx, azbxSUBaxbz, 1); // az*bx-ax*bz, ay*bz-az*by + const uint32x2_t retHigh = vand_u32(TF, vreinterpret_u32_f32(aybzSUBazby_axbySUBaybx)); // 0, ax*by-ay*bx + + return vcombine_f32(retLow, vreinterpret_f32_u32(retHigh)); +} + +PX_FORCE_INLINE VecCrossV V3PrepareCross(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + return a; +} + +PX_FORCE_INLINE FloatV V3Length(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + + // const uint32x2_t mask = {0xffffFFFF, 0x0}; + + const float32x4_t tmp = vmulq_f32(a, a); + const float32x2_t low = vget_low_f32(tmp); + const float32x2_t high = vget_high_f32(tmp); + // const float32x2_t high = vreinterpret_f32_u32(vand_u32(vreinterpret_u32_f32(high_), mask)); + + const float32x2_t sumTmp = vpadd_f32(low, high); // = {0+z, x+y} + const float32x2_t sum0ZYX = vpadd_f32(sumTmp, sumTmp); // = {x+y+z, x+y+z} + + return FSqrt(sum0ZYX); +} + +PX_FORCE_INLINE FloatV V3LengthSq(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + return V3Dot(a, a); +} + +PX_FORCE_INLINE Vec3V V3Normalize(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + //PX_ASSERT(!FAllEq(V4LengthSq(a), FZero())); + return V3ScaleInv(a, V3Length(a)); +} + +PX_FORCE_INLINE Vec3V V3NormalizeFast(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + //PX_ASSERT(!FAllEq(V4LengthSq(a), FZero())); + return V3Scale(a, VRECIPSQRTE(V3Dot(a, a))); +} + +PX_FORCE_INLINE Vec3V V3NormalizeSafe(const Vec3V a, const Vec3V unsafeReturnValue) +{ + ASSERT_ISVALIDVEC3V(a); + const FloatV zero = vdup_n_f32(0.0f); + const FloatV length = V3Length(a); + const uint32x4_t isGreaterThanZero = FIsGrtr(length, zero); + return V3Sel(isGreaterThanZero, V3ScaleInv(a, length), unsafeReturnValue); +} + +PX_FORCE_INLINE Vec3V V3Sel(const BoolV c, const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V( vbslq_f32(c, a, b)); + return vbslq_f32(c, a, b); +} + +PX_FORCE_INLINE BoolV V3IsGrtr(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return vcgtq_f32(a, b); +} + +PX_FORCE_INLINE BoolV V3IsGrtrOrEq(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return vcgeq_f32(a, b); +} + +PX_FORCE_INLINE BoolV V3IsEq(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return vceqq_f32(a, b); +} + +PX_FORCE_INLINE Vec3V V3Max(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return vmaxq_f32(a, b); +} + +PX_FORCE_INLINE Vec3V V3Min(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return vminq_f32(a, b); +} + +PX_FORCE_INLINE FloatV V3ExtractMax(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + + const float32x2_t low = vget_low_f32(a); + const float32x2_t high = vget_high_f32(a); + + const float32x2_t zz = vdup_lane_f32(high, 0); + const float32x2_t max0 = vpmax_f32(zz, low); + const float32x2_t max1 = vpmax_f32(max0, max0); + + return max1; +} + +PX_FORCE_INLINE FloatV V3ExtractMin(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + + const float32x2_t low = vget_low_f32(a); + const float32x2_t high = vget_high_f32(a); + + const float32x2_t zz = vdup_lane_f32(high, 0); + const float32x2_t min0 = vpmin_f32(zz, low); + const float32x2_t min1 = vpmin_f32(min0, min0); + + return min1; +} + +// return (a >= 0.0f) ? 1.0f : -1.0f; +PX_FORCE_INLINE Vec3V V3Sign(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + const Vec3V zero = V3Zero(); + const Vec3V one = V3One(); + const Vec3V none = V3Neg(one); + return V3Sel(V3IsGrtrOrEq(a, zero), one, none); +} + +PX_FORCE_INLINE Vec3V V3Clamp(const Vec3V a, const Vec3V minV, const Vec3V maxV) +{ + ASSERT_ISVALIDVEC3V(minV); + ASSERT_ISVALIDVEC3V(maxV); + return V3Max(V3Min(a, maxV), minV); +} + +PX_FORCE_INLINE PxU32 V3AllGrtr(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return internalUnitNeonSimd::BAllTrue3_R(V4IsGrtr(a, b)); +} + +PX_FORCE_INLINE PxU32 V3AllGrtrOrEq(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return internalUnitNeonSimd::BAllTrue3_R(V4IsGrtrOrEq(a, b)); +} + +PX_FORCE_INLINE PxU32 V3AllEq(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return internalUnitNeonSimd::BAllTrue3_R(V4IsEq(a, b)); +} + +PX_FORCE_INLINE Vec3V V3Round(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + // truncate(a + (0.5f - sign(a))) + const Vec3V half = V3Load(0.5f); + const float32x4_t sign = vcvtq_f32_u32((vshrq_n_u32(vreinterpretq_u32_f32(a), 31))); + const Vec3V aPlusHalf = V3Add(a, half); + const Vec3V aRound = V3Sub(aPlusHalf, sign); + return vcvtq_f32_s32(vcvtq_s32_f32(aRound)); +} + +PX_FORCE_INLINE Vec3V V3Sin(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + + // Modulo the range of the given angles such that -XM_2PI <= Angles < XM_2PI + const Vec4V recipTwoPi = V4LoadA(g_PXReciprocalTwoPi.f); + const Vec4V twoPi = V4LoadA(g_PXTwoPi.f); + const Vec3V tmp = V4Mul(a, recipTwoPi); + const Vec3V b = V3Round(tmp); + const Vec3V V1 = V4NegMulSub(twoPi, b, a); + + // sin(V) ~= V - V^3 / 3! + V^5 / 5! - V^7 / 7! + V^9 / 9! - V^11 / 11! + V^13 / 13! - + // V^15 / 15! + V^17 / 17! - V^19 / 19! + V^21 / 21! - V^23 / 23! (for -PI <= V < PI) + const Vec3V V2 = V3Mul(V1, V1); + const Vec3V V3 = V3Mul(V2, V1); + const Vec3V V5 = V3Mul(V3, V2); + const Vec3V V7 = V3Mul(V5, V2); + const Vec3V V9 = V3Mul(V7, V2); + const Vec3V V11 = V3Mul(V9, V2); + const Vec3V V13 = V3Mul(V11, V2); + const Vec3V V15 = V3Mul(V13, V2); + const Vec3V V17 = V3Mul(V15, V2); + const Vec3V V19 = V3Mul(V17, V2); + const Vec3V V21 = V3Mul(V19, V2); + const Vec3V V23 = V3Mul(V21, V2); + + const Vec4V sinCoefficients0 = V4LoadA(g_PXSinCoefficients0.f); + const Vec4V sinCoefficients1 = V4LoadA(g_PXSinCoefficients1.f); + const Vec4V sinCoefficients2 = V4LoadA(g_PXSinCoefficients2.f); + + const FloatV S1 = V4GetY(sinCoefficients0); + const FloatV S2 = V4GetZ(sinCoefficients0); + const FloatV S3 = V4GetW(sinCoefficients0); + const FloatV S4 = V4GetX(sinCoefficients1); + const FloatV S5 = V4GetY(sinCoefficients1); + const FloatV S6 = V4GetZ(sinCoefficients1); + const FloatV S7 = V4GetW(sinCoefficients1); + const FloatV S8 = V4GetX(sinCoefficients2); + const FloatV S9 = V4GetY(sinCoefficients2); + const FloatV S10 = V4GetZ(sinCoefficients2); + const FloatV S11 = V4GetW(sinCoefficients2); + + Vec3V Result; + Result = V4ScaleAdd(V3, S1, V1); + Result = V4ScaleAdd(V5, S2, Result); + Result = V4ScaleAdd(V7, S3, Result); + Result = V4ScaleAdd(V9, S4, Result); + Result = V4ScaleAdd(V11, S5, Result); + Result = V4ScaleAdd(V13, S6, Result); + Result = V4ScaleAdd(V15, S7, Result); + Result = V4ScaleAdd(V17, S8, Result); + Result = V4ScaleAdd(V19, S9, Result); + Result = V4ScaleAdd(V21, S10, Result); + Result = V4ScaleAdd(V23, S11, Result); + + return Result; +} + +PX_FORCE_INLINE Vec3V V3Cos(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + + // Modulo the range of the given angles such that -XM_2PI <= Angles < XM_2PI + const Vec4V recipTwoPi = V4LoadA(g_PXReciprocalTwoPi.f); + const Vec4V twoPi = V4LoadA(g_PXTwoPi.f); + const Vec3V tmp = V4Mul(a, recipTwoPi); + const Vec3V b = V3Round(tmp); + const Vec3V V1 = V4NegMulSub(twoPi, b, a); + + // cos(V) ~= 1 - V^2 / 2! + V^4 / 4! - V^6 / 6! + V^8 / 8! - V^10 / 10! + V^12 / 12! - + // V^14 / 14! + V^16 / 16! - V^18 / 18! + V^20 / 20! - V^22 / 22! (for -PI <= V < PI) + const Vec3V V2 = V3Mul(V1, V1); + const Vec3V V4 = V3Mul(V2, V2); + const Vec3V V6 = V3Mul(V4, V2); + const Vec3V V8 = V3Mul(V4, V4); + const Vec3V V10 = V3Mul(V6, V4); + const Vec3V V12 = V3Mul(V6, V6); + const Vec3V V14 = V3Mul(V8, V6); + const Vec3V V16 = V3Mul(V8, V8); + const Vec3V V18 = V3Mul(V10, V8); + const Vec3V V20 = V3Mul(V10, V10); + const Vec3V V22 = V3Mul(V12, V10); + + const Vec4V cosCoefficients0 = V4LoadA(g_PXCosCoefficients0.f); + const Vec4V cosCoefficients1 = V4LoadA(g_PXCosCoefficients1.f); + const Vec4V cosCoefficients2 = V4LoadA(g_PXCosCoefficients2.f); + + const FloatV C1 = V4GetY(cosCoefficients0); + const FloatV C2 = V4GetZ(cosCoefficients0); + const FloatV C3 = V4GetW(cosCoefficients0); + const FloatV C4 = V4GetX(cosCoefficients1); + const FloatV C5 = V4GetY(cosCoefficients1); + const FloatV C6 = V4GetZ(cosCoefficients1); + const FloatV C7 = V4GetW(cosCoefficients1); + const FloatV C8 = V4GetX(cosCoefficients2); + const FloatV C9 = V4GetY(cosCoefficients2); + const FloatV C10 = V4GetZ(cosCoefficients2); + const FloatV C11 = V4GetW(cosCoefficients2); + + Vec3V Result; + Result = V4ScaleAdd(V2, C1, V4One()); + Result = V4ScaleAdd(V4, C2, Result); + Result = V4ScaleAdd(V6, C3, Result); + Result = V4ScaleAdd(V8, C4, Result); + Result = V4ScaleAdd(V10, C5, Result); + Result = V4ScaleAdd(V12, C6, Result); + Result = V4ScaleAdd(V14, C7, Result); + Result = V4ScaleAdd(V16, C8, Result); + Result = V4ScaleAdd(V18, C9, Result); + Result = V4ScaleAdd(V20, C10, Result); + Result = V4ScaleAdd(V22, C11, Result); + + return V4ClearW(Result); +} + +PX_FORCE_INLINE Vec3V V3PermYZZ(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + const float32x2_t xy = vget_low_f32(a); + const float32x2_t zw = vget_high_f32(a); + const float32x2_t yz = vext_f32(xy, zw, 1); + return vcombine_f32(yz, zw); +} + +PX_FORCE_INLINE Vec3V V3PermXYX(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + + const uint32x2_t mask = { 0xffffFFFF, 0x0 }; + const uint32x2_t xy = vget_low_u32(vreinterpretq_u32_f32(a)); + const uint32x2_t xw = vand_u32(xy, mask); + return vreinterpretq_f32_u32(vcombine_u32(xy, xw)); +} + +PX_FORCE_INLINE Vec3V V3PermYZX(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + + const uint32x2_t mask = { 0xffffFFFF, 0x0 }; + const uint32x2_t xy = vget_low_u32(vreinterpretq_u32_f32(a)); + const uint32x2_t zw = vget_high_u32(vreinterpretq_u32_f32(a)); + const uint32x2_t yz = vext_u32(xy, zw, 1); + const uint32x2_t xw = vand_u32(xy, mask); + return vreinterpretq_f32_u32(vcombine_u32(yz, xw)); +} + +PX_FORCE_INLINE Vec3V V3PermZXY(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + + const uint32x2_t xy = vget_low_u32(vreinterpretq_u32_f32(a)); + const uint32x2_t zw = vget_high_u32(vreinterpretq_u32_f32(a)); + const uint32x2_t wz = vrev64_u32(zw); + + const uint32x2_t zx = vext_u32(wz, xy, 1); + const uint32x2_t yw = vext_u32(xy, wz, 1); + + return vreinterpretq_f32_u32(vcombine_u32(zx, yw)); +} + +PX_FORCE_INLINE Vec3V V3PermZZY(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + + const uint32x2_t xy = vget_low_u32(vreinterpretq_u32_f32(a)); + const uint32x2_t zw = vget_high_u32(vreinterpretq_u32_f32(a)); + + const uint32x2_t wz = vrev64_u32(zw); + const uint32x2_t yw = vext_u32(xy, wz, 1); + const uint32x2_t zz = vdup_lane_u32(wz, 1); + + return vreinterpretq_f32_u32(vcombine_u32(zz, yw)); +} + +PX_FORCE_INLINE Vec3V V3PermYXX(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + + const uint32x2_t mask = { 0xffffFFFF, 0x0 }; + const uint32x2_t xy = vget_low_u32(vreinterpretq_u32_f32(a)); + const uint32x2_t yx = vrev64_u32(xy); + const uint32x2_t xw = vand_u32(xy, mask); + return vreinterpretq_f32_u32(vcombine_u32(yx, xw)); +} + +PX_FORCE_INLINE Vec3V V3Perm_Zero_1Z_0Y(const Vec3V v0, const Vec3V v1) +{ + ASSERT_ISVALIDVEC3V(v0); + ASSERT_ISVALIDVEC3V(v1); + + const uint32x2_t xy = vget_low_u32(vreinterpretq_u32_f32(v0)); + const uint32x2_t zw = vget_high_u32(vreinterpretq_u32_f32(v1)); + const uint32x2_t wz = vrev64_u32(zw); + const uint32x2_t yw = vext_u32(xy, wz, 1); + + return vreinterpretq_f32_u32(vcombine_u32(wz, yw)); +} + +PX_FORCE_INLINE Vec3V V3Perm_0Z_Zero_1X(const Vec3V v0, const Vec3V v1) +{ + ASSERT_ISVALIDVEC3V(v0); + ASSERT_ISVALIDVEC3V(v1); + + const uint32x2_t mask = { 0xffffFFFF, 0x0 }; + const uint32x2_t zw = vget_high_u32(vreinterpretq_u32_f32(v0)); + const uint32x2_t xy = vget_low_u32(vreinterpretq_u32_f32(v1)); + const uint32x2_t xw = vand_u32(xy, mask); + + return vreinterpretq_f32_u32(vcombine_u32(zw, xw)); +} + +PX_FORCE_INLINE Vec3V V3Perm_1Y_0X_Zero(const Vec3V v0, const Vec3V v1) +{ + ASSERT_ISVALIDVEC3V(v0); + ASSERT_ISVALIDVEC3V(v1); + + const uint32x2_t axy = vget_low_u32(vreinterpretq_u32_f32(v0)); + const uint32x2_t bxy = vget_low_u32(vreinterpretq_u32_f32(v1)); + const uint32x2_t byax = vext_u32(bxy, axy, 1); + const uint32x2_t ww = vdup_n_u32(0); + + return vreinterpretq_f32_u32(vcombine_u32(byax, ww)); +} + +PX_FORCE_INLINE FloatV V3SumElems(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + + // const uint32x2_t mask = {0xffffFFFF, 0x0}; + + const float32x2_t low = vget_low_f32(a); + const float32x2_t high = vget_high_f32(a); + // const float32x2_t high = vreinterpret_f32_u32(vand_u32(vreinterpret_u32_f32(high_), mask)); + + const float32x2_t sumTmp = vpadd_f32(low, high); // = {0+z, x+y} + const float32x2_t sum0ZYX = vpadd_f32(sumTmp, sumTmp); // = {x+y+z, x+y+z} + + return sum0ZYX; +} + +PX_FORCE_INLINE PxU32 V3OutOfBounds(const Vec3V a, const Vec3V min, const Vec3V max) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(min); + ASSERT_ISVALIDVEC3V(max); + + const BoolV c = BOr(V3IsGrtr(a, max), V3IsGrtr(min, a)); + return internalUnitNeonSimd::BAnyTrue3_R(c); +} + +PX_FORCE_INLINE PxU32 V3InBounds(const Vec3V a, const Vec3V min, const Vec3V max) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(min); + ASSERT_ISVALIDVEC3V(max); + + const BoolV c = BAnd(V3IsGrtrOrEq(a, min), V3IsGrtrOrEq(max, a)); + return internalUnitNeonSimd::BAllTrue4_R(c); +} + +PX_FORCE_INLINE PxU32 V3OutOfBounds(const Vec3V a, const Vec3V bounds) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(bounds); + + const BoolV greater = V3IsGrtr(V3Abs(a), bounds); + return internalUnitNeonSimd::BAnyTrue3_R(greater); +} + +PX_FORCE_INLINE PxU32 V3InBounds(const Vec3V a, const Vec3V bounds) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(bounds); + + const BoolV greaterOrEq = V3IsGrtrOrEq(bounds, V3Abs(a)); + return internalUnitNeonSimd::BAllTrue4_R(greaterOrEq); +} + +PX_FORCE_INLINE void V3Transpose(Vec3V& col0, Vec3V& col1, Vec3V& col2) +{ + ASSERT_ISVALIDVEC3V(col0); + ASSERT_ISVALIDVEC3V(col1); + ASSERT_ISVALIDVEC3V(col2); + + Vec3V col3 = V3Zero(); + const float32x4x2_t v0v1 = vzipq_f32(col0, col2); + const float32x4x2_t v2v3 = vzipq_f32(col1, col3); + const float32x4x2_t zip0 = vzipq_f32(v0v1.val[0], v2v3.val[0]); + const float32x4x2_t zip1 = vzipq_f32(v0v1.val[1], v2v3.val[1]); + col0 = zip0.val[0]; + col1 = zip0.val[1]; + col2 = zip1.val[0]; + // col3 = zip1.val[1]; +} + +////////////////////////////////// +// VEC4V +////////////////////////////////// + +PX_FORCE_INLINE Vec4V V4Splat(const FloatV f) +{ + ASSERT_ISVALIDFLOATV(f); + return vcombine_f32(f, f); +} + +PX_FORCE_INLINE Vec4V V4Merge(const FloatV* const floatVArray) +{ + ASSERT_ISVALIDFLOATV(floatVArray[0]); + ASSERT_ISVALIDFLOATV(floatVArray[1]); + ASSERT_ISVALIDFLOATV(floatVArray[2]); + ASSERT_ISVALIDFLOATV(floatVArray[3]); + + const uint32x2_t xLow = vreinterpret_u32_f32(floatVArray[0]); + const uint32x2_t yLow = vreinterpret_u32_f32(floatVArray[1]); + const uint32x2_t zLow = vreinterpret_u32_f32(floatVArray[2]); + const uint32x2_t wLow = vreinterpret_u32_f32(floatVArray[3]); + + const uint32x2_t dLow = vext_u32(xLow, yLow, 1); + const uint32x2_t dHigh = vext_u32(zLow, wLow, 1); + + return vreinterpretq_f32_u32(vcombine_u32(dLow, dHigh)); +} + +PX_FORCE_INLINE Vec4V V4Merge(const FloatVArg x, const FloatVArg y, const FloatVArg z, const FloatVArg w) +{ + ASSERT_ISVALIDFLOATV(x); + ASSERT_ISVALIDFLOATV(y); + ASSERT_ISVALIDFLOATV(z); + ASSERT_ISVALIDFLOATV(w); + + const uint32x2_t xLow = vreinterpret_u32_f32(x); + const uint32x2_t yLow = vreinterpret_u32_f32(y); + const uint32x2_t zLow = vreinterpret_u32_f32(z); + const uint32x2_t wLow = vreinterpret_u32_f32(w); + + const uint32x2_t dLow = vext_u32(xLow, yLow, 1); + const uint32x2_t dHigh = vext_u32(zLow, wLow, 1); + + return vreinterpretq_f32_u32(vcombine_u32(dLow, dHigh)); +} + +PX_FORCE_INLINE Vec4V V4MergeW(const Vec4VArg x, const Vec4VArg y, const Vec4VArg z, const Vec4VArg w) +{ + const float32x2_t xx = vget_high_f32(x); + const float32x2_t yy = vget_high_f32(y); + const float32x2_t zz = vget_high_f32(z); + const float32x2_t ww = vget_high_f32(w); + + const float32x2x2_t zipL = vzip_f32(xx, yy); + const float32x2x2_t zipH = vzip_f32(zz, ww); + + return vcombine_f32(zipL.val[1], zipH.val[1]); +} + +PX_FORCE_INLINE Vec4V V4MergeZ(const Vec4VArg x, const Vec4VArg y, const Vec4VArg z, const Vec4VArg w) +{ + const float32x2_t xx = vget_high_f32(x); + const float32x2_t yy = vget_high_f32(y); + const float32x2_t zz = vget_high_f32(z); + const float32x2_t ww = vget_high_f32(w); + + const float32x2x2_t zipL = vzip_f32(xx, yy); + const float32x2x2_t zipH = vzip_f32(zz, ww); + + return vcombine_f32(zipL.val[0], zipH.val[0]); +} + +PX_FORCE_INLINE Vec4V V4MergeY(const Vec4VArg x, const Vec4VArg y, const Vec4VArg z, const Vec4VArg w) +{ + const float32x2_t xx = vget_low_f32(x); + const float32x2_t yy = vget_low_f32(y); + const float32x2_t zz = vget_low_f32(z); + const float32x2_t ww = vget_low_f32(w); + + const float32x2x2_t zipL = vzip_f32(xx, yy); + const float32x2x2_t zipH = vzip_f32(zz, ww); + + return vcombine_f32(zipL.val[1], zipH.val[1]); +} + +PX_FORCE_INLINE Vec4V V4MergeX(const Vec4VArg x, const Vec4VArg y, const Vec4VArg z, const Vec4VArg w) +{ + const float32x2_t xx = vget_low_f32(x); + const float32x2_t yy = vget_low_f32(y); + const float32x2_t zz = vget_low_f32(z); + const float32x2_t ww = vget_low_f32(w); + + const float32x2x2_t zipL = vzip_f32(xx, yy); + const float32x2x2_t zipH = vzip_f32(zz, ww); + + return vcombine_f32(zipL.val[0], zipH.val[0]); +} + +PX_FORCE_INLINE Vec4V V4UnpackXY(const Vec4VArg a, const Vec4VArg b) +{ + return vzipq_f32(a, b).val[0]; +} + +PX_FORCE_INLINE Vec4V V4UnpackZW(const Vec4VArg a, const Vec4VArg b) +{ + return vzipq_f32(a, b).val[1]; +} + +PX_FORCE_INLINE Vec4V V4UnitW() +{ + const float32x2_t zeros = vreinterpret_f32_u32(vmov_n_u32(0)); + const float32x2_t ones = vmov_n_f32(1.0f); + const float32x2_t zo = vext_f32(zeros, ones, 1); + return vcombine_f32(zeros, zo); +} + +PX_FORCE_INLINE Vec4V V4UnitX() +{ + const float32x2_t zeros = vreinterpret_f32_u32(vmov_n_u32(0)); + const float32x2_t ones = vmov_n_f32(1.0f); + const float32x2_t oz = vext_f32(ones, zeros, 1); + return vcombine_f32(oz, zeros); +} + +PX_FORCE_INLINE Vec4V V4UnitY() +{ + const float32x2_t zeros = vreinterpret_f32_u32(vmov_n_u32(0)); + const float32x2_t ones = vmov_n_f32(1.0f); + const float32x2_t zo = vext_f32(zeros, ones, 1); + return vcombine_f32(zo, zeros); +} + +PX_FORCE_INLINE Vec4V V4UnitZ() +{ + const float32x2_t zeros = vreinterpret_f32_u32(vmov_n_u32(0)); + const float32x2_t ones = vmov_n_f32(1.0f); + const float32x2_t oz = vext_f32(ones, zeros, 1); + return vcombine_f32(zeros, oz); +} + +PX_FORCE_INLINE FloatV V4GetW(const Vec4V f) +{ + const float32x2_t fhigh = vget_high_f32(f); + return vdup_lane_f32(fhigh, 1); +} + +PX_FORCE_INLINE FloatV V4GetX(const Vec4V f) +{ + const float32x2_t fLow = vget_low_f32(f); + return vdup_lane_f32(fLow, 0); +} + +PX_FORCE_INLINE FloatV V4GetY(const Vec4V f) +{ + const float32x2_t fLow = vget_low_f32(f); + return vdup_lane_f32(fLow, 1); +} + +PX_FORCE_INLINE FloatV V4GetZ(const Vec4V f) +{ + const float32x2_t fhigh = vget_high_f32(f); + return vdup_lane_f32(fhigh, 0); +} + +PX_FORCE_INLINE Vec4V V4SetW(const Vec4V v, const FloatV f) +{ + ASSERT_ISVALIDFLOATV(f); + return V4Sel(BTTTF(), v, vcombine_f32(f, f)); +} + +PX_FORCE_INLINE Vec4V V4SetX(const Vec4V v, const FloatV f) +{ + ASSERT_ISVALIDFLOATV(f); + return V4Sel(BFTTT(), v, vcombine_f32(f, f)); +} + +PX_FORCE_INLINE Vec4V V4SetY(const Vec4V v, const FloatV f) +{ + ASSERT_ISVALIDFLOATV(f); + return V4Sel(BTFTT(), v, vcombine_f32(f, f)); +} + +PX_FORCE_INLINE Vec4V V4SetZ(const Vec4V v, const FloatV f) +{ + ASSERT_ISVALIDFLOATV(f); + return V4Sel(BTTFT(), v, vcombine_f32(f, f)); +} + +PX_FORCE_INLINE Vec4V V4ClearW(const Vec4V v) +{ + return V4Sel(BTTTF(), v, V4Zero()); +} + +PX_FORCE_INLINE Vec4V V4PermYXWZ(const Vec4V a) +{ + const float32x2_t xy = vget_low_f32(a); + const float32x2_t zw = vget_high_f32(a); + const float32x2_t yx = vext_f32(xy, xy, 1); + const float32x2_t wz = vext_f32(zw, zw, 1); + return vcombine_f32(yx, wz); +} + +PX_FORCE_INLINE Vec4V V4PermXZXZ(const Vec4V a) +{ + const float32x2_t xy = vget_low_f32(a); + const float32x2_t zw = vget_high_f32(a); + const float32x2x2_t xzyw = vzip_f32(xy, zw); + return vcombine_f32(xzyw.val[0], xzyw.val[0]); +} + +PX_FORCE_INLINE Vec4V V4PermYWYW(const Vec4V a) +{ + const float32x2_t xy = vget_low_f32(a); + const float32x2_t zw = vget_high_f32(a); + const float32x2x2_t xzyw = vzip_f32(xy, zw); + return vcombine_f32(xzyw.val[1], xzyw.val[1]); +} + +PX_FORCE_INLINE Vec4V V4PermYZXW(const Vec4V a) +{ + const uint32x2_t xy = vget_low_u32(vreinterpretq_u32_f32(a)); + const uint32x2_t zw = vget_high_u32(vreinterpretq_u32_f32(a)); + const uint32x2_t yz = vext_u32(xy, zw, 1); + const uint32x2_t xw = vrev64_u32(vext_u32(zw, xy, 1)); + return vreinterpretq_f32_u32(vcombine_u32(yz, xw)); +} + +PX_FORCE_INLINE Vec4V V4PermZWXY(const Vec4V a) +{ + const float32x2_t low = vget_low_f32(a); + const float32x2_t high = vget_high_f32(a); + return vcombine_f32(high, low); +} + +template +PX_FORCE_INLINE Vec4V V4Perm(const Vec4V V) +{ + static const uint32_t ControlElement[4] = + { +#if 1 + 0x03020100, // XM_SWIZZLE_X + 0x07060504, // XM_SWIZZLE_Y + 0x0B0A0908, // XM_SWIZZLE_Z + 0x0F0E0D0C, // XM_SWIZZLE_W +#else + 0x00010203, // XM_SWIZZLE_X + 0x04050607, // XM_SWIZZLE_Y + 0x08090A0B, // XM_SWIZZLE_Z + 0x0C0D0E0F, // XM_SWIZZLE_W +#endif + }; + + uint8x8x2_t tbl; + tbl.val[0] = vreinterpret_u8_f32(vget_low_f32(V)); + tbl.val[1] = vreinterpret_u8_f32(vget_high_f32(V)); + + uint8x8_t idx = + vcreate_u8(static_cast(ControlElement[E0]) | (static_cast(ControlElement[E1]) << 32)); + const uint8x8_t rL = vtbl2_u8(tbl, idx); + idx = vcreate_u8(static_cast(ControlElement[E2]) | (static_cast(ControlElement[E3]) << 32)); + const uint8x8_t rH = vtbl2_u8(tbl, idx); + return vreinterpretq_f32_u8(vcombine_u8(rL, rH)); +} + +// PT: this seems measurably slower than the hardcoded version +/*PX_FORCE_INLINE Vec4V V4PermYZXW(const Vec4V a) +{ + return V4Perm<1, 2, 0, 3>(a); +}*/ + +PX_FORCE_INLINE Vec4V V4Zero() +{ + return vreinterpretq_f32_u32(vmovq_n_u32(0)); + // return vmovq_n_f32(0.0f); +} + +PX_FORCE_INLINE Vec4V V4One() +{ + return vmovq_n_f32(1.0f); +} + +PX_FORCE_INLINE Vec4V V4Eps() +{ + // return vmovq_n_f32(PX_EPS_REAL); + return V4Load(PX_EPS_REAL); +} + +PX_FORCE_INLINE Vec4V V4Neg(const Vec4V f) +{ + return vnegq_f32(f); +} + +PX_FORCE_INLINE Vec4V V4Add(const Vec4V a, const Vec4V b) +{ + return vaddq_f32(a, b); +} + +PX_FORCE_INLINE Vec4V V4Sub(const Vec4V a, const Vec4V b) +{ + return vsubq_f32(a, b); +} + +PX_FORCE_INLINE Vec4V V4Scale(const Vec4V a, const FloatV b) +{ + return vmulq_lane_f32(a, b, 0); +} + +PX_FORCE_INLINE Vec4V V4Mul(const Vec4V a, const Vec4V b) +{ + return vmulq_f32(a, b); +} + +PX_FORCE_INLINE Vec4V V4ScaleInv(const Vec4V a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(b); + const float32x2_t invB = VRECIP(b); + return vmulq_lane_f32(a, invB, 0); +} + +PX_FORCE_INLINE Vec4V V4Div(const Vec4V a, const Vec4V b) +{ + const float32x4_t invB = VRECIPQ(b); + return vmulq_f32(a, invB); +} + +PX_FORCE_INLINE Vec4V V4ScaleInvFast(const Vec4V a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(b); + const float32x2_t invB = VRECIPE(b); + return vmulq_lane_f32(a, invB, 0); +} + +PX_FORCE_INLINE Vec4V V4DivFast(const Vec4V a, const Vec4V b) +{ + const float32x4_t invB = VRECIPEQ(b); + return vmulq_f32(a, invB); +} + +PX_FORCE_INLINE Vec4V V4Recip(const Vec4V a) +{ + return VRECIPQ(a); +} + +PX_FORCE_INLINE Vec4V V4RecipFast(const Vec4V a) +{ + return VRECIPEQ(a); +} + +PX_FORCE_INLINE Vec4V V4Rsqrt(const Vec4V a) +{ + return VRECIPSQRTQ(a); +} + +PX_FORCE_INLINE Vec4V V4RsqrtFast(const Vec4V a) +{ + return VRECIPSQRTEQ(a); +} + +PX_FORCE_INLINE Vec4V V4Sqrt(const Vec4V a) +{ + return V4Sel(V4IsEq(a, V4Zero()), a, V4Mul(a, VRECIPSQRTQ(a))); +} + +PX_FORCE_INLINE Vec4V V4ScaleAdd(const Vec4V a, const FloatV b, const Vec4V c) +{ + ASSERT_ISVALIDFLOATV(b); + return vmlaq_lane_f32(c, a, b, 0); +} + +PX_FORCE_INLINE Vec4V V4NegScaleSub(const Vec4V a, const FloatV b, const Vec4V c) +{ + ASSERT_ISVALIDFLOATV(b); + return vmlsq_lane_f32(c, a, b, 0); +} + +PX_FORCE_INLINE Vec4V V4MulAdd(const Vec4V a, const Vec4V b, const Vec4V c) +{ + return vmlaq_f32(c, a, b); +} + +PX_FORCE_INLINE Vec4V V4NegMulSub(const Vec4V a, const Vec4V b, const Vec4V c) +{ + return vmlsq_f32(c, a, b); +} + +PX_FORCE_INLINE Vec4V V4Abs(const Vec4V a) +{ + return vabsq_f32(a); +} + +PX_FORCE_INLINE FloatV V4SumElements(const Vec4V a) +{ + const Vec4V xy = V4UnpackXY(a, a); // x,x,y,y + const Vec4V zw = V4UnpackZW(a, a); // z,z,w,w + const Vec4V xz_yw = V4Add(xy, zw); // x+z,x+z,y+w,y+w + const FloatV xz = V4GetX(xz_yw); // x+z + const FloatV yw = V4GetZ(xz_yw); // y+w + return FAdd(xz, yw); // sum +} + +PX_FORCE_INLINE FloatV V4Dot(const Vec4V a, const Vec4V b) +{ + const float32x4_t tmp = vmulq_f32(a, b); + const float32x2_t low = vget_low_f32(tmp); + const float32x2_t high = vget_high_f32(tmp); + + const float32x2_t sumTmp = vpadd_f32(low, high); // = {z+w, x+y} + const float32x2_t sumWZYX = vpadd_f32(sumTmp, sumTmp); // = {x+y+z+w, x+y+z+w} + return sumWZYX; +} + +PX_FORCE_INLINE FloatV V4Dot3(const Vec4V aa, const Vec4V bb) +{ + // PT: the V3Dot code relies on the fact that W=0 so we can't reuse it as-is, we need to clear W first. + // TODO: find a better implementation that does not need to clear W. + const Vec4V a = V4ClearW(aa); + const Vec4V b = V4ClearW(bb); + + const float32x4_t tmp = vmulq_f32(a, b); + const float32x2_t low = vget_low_f32(tmp); + const float32x2_t high = vget_high_f32(tmp); + + const float32x2_t sumTmp = vpadd_f32(low, high); // = {0+z, x+y} + const float32x2_t sum0ZYX = vpadd_f32(sumTmp, sumTmp); // = {x+y+z, x+y+z} + return sum0ZYX; +} + +PX_FORCE_INLINE Vec4V V4Cross(const Vec4V a, const Vec4V b) +{ + const uint32x2_t TF = { 0xffffFFFF, 0x0 }; + const float32x2_t ay_ax = vget_low_f32(a); // d2 + const float32x2_t aw_az = vget_high_f32(a); // d3 + const float32x2_t by_bx = vget_low_f32(b); // d4 + const float32x2_t bw_bz = vget_high_f32(b); // d5 + // Hi, Lo + const float32x2_t bz_by = vext_f32(by_bx, bw_bz, 1); // bz, by + const float32x2_t az_ay = vext_f32(ay_ax, aw_az, 1); // az, ay + + const float32x2_t azbx = vmul_f32(aw_az, by_bx); // 0, az*bx + const float32x2_t aybz_axby = vmul_f32(ay_ax, bz_by); // ay*bz, ax*by + + const float32x2_t azbxSUBaxbz = vmls_f32(azbx, bw_bz, ay_ax); // 0, az*bx-ax*bz + const float32x2_t aybzSUBazby_axbySUBaybx = vmls_f32(aybz_axby, by_bx, az_ay); // ay*bz-az*by, ax*by-ay*bx + + const float32x2_t retLow = vext_f32(aybzSUBazby_axbySUBaybx, azbxSUBaxbz, 1); // az*bx-ax*bz, ay*bz-az*by + const uint32x2_t retHigh = vand_u32(TF, vreinterpret_u32_f32(aybzSUBazby_axbySUBaybx)); // 0, ax*by-ay*bx + + return vcombine_f32(retLow, vreinterpret_f32_u32(retHigh)); +} + +PX_FORCE_INLINE FloatV V4Length(const Vec4V a) +{ + const float32x4_t tmp = vmulq_f32(a, a); + const float32x2_t low = vget_low_f32(tmp); + const float32x2_t high = vget_high_f32(tmp); + + const float32x2_t sumTmp = vpadd_f32(low, high); // = {0+z, x+y} + const float32x2_t sumWZYX = vpadd_f32(sumTmp, sumTmp); // = {x+y+z, x+y+z} + return FSqrt(sumWZYX); +} + +PX_FORCE_INLINE FloatV V4LengthSq(const Vec4V a) +{ + return V4Dot(a, a); +} + +PX_FORCE_INLINE Vec4V V4Normalize(const Vec4V a) +{ + //PX_ASSERT(!FAllEq(V4LengthSq(a), FZero())); + return V4ScaleInv(a, V4Length(a)); +} + +PX_FORCE_INLINE Vec4V V4NormalizeFast(const Vec4V a) +{ + //PX_ASSERT(!FAllEq(V4LengthSq(a), FZero())); + return V4Scale(a, FRsqrtFast(V4Dot(a, a))); +} + +PX_FORCE_INLINE Vec4V V4NormalizeSafe(const Vec4V a, const Vec4V unsafeReturnValue) +{ + const FloatV zero = FZero(); + const FloatV length = V4Length(a); + const uint32x4_t isGreaterThanZero = FIsGrtr(length, zero); + return V4Sel(isGreaterThanZero, V4ScaleInv(a, length), unsafeReturnValue); +} + +PX_FORCE_INLINE BoolV V4IsEqU32(const VecU32V a, const VecU32V b) +{ + return vceqq_u32(a, b); +} + +PX_FORCE_INLINE Vec4V V4Sel(const BoolV c, const Vec4V a, const Vec4V b) +{ + return vbslq_f32(c, a, b); +} + +PX_FORCE_INLINE BoolV V4IsGrtr(const Vec4V a, const Vec4V b) +{ + return vcgtq_f32(a, b); +} + +PX_FORCE_INLINE BoolV V4IsGrtrOrEq(const Vec4V a, const Vec4V b) +{ + return vcgeq_f32(a, b); +} + +PX_FORCE_INLINE BoolV V4IsEq(const Vec4V a, const Vec4V b) +{ + return vceqq_f32(a, b); +} + +PX_FORCE_INLINE Vec4V V4Max(const Vec4V a, const Vec4V b) +{ + return vmaxq_f32(a, b); +} + +PX_FORCE_INLINE Vec4V V4Min(const Vec4V a, const Vec4V b) +{ + return vminq_f32(a, b); +} + +PX_FORCE_INLINE FloatV V4ExtractMax(const Vec4V a) +{ + const float32x2_t low = vget_low_f32(a); + const float32x2_t high = vget_high_f32(a); + + const float32x2_t max0 = vpmax_f32(high, low); + const float32x2_t max1 = vpmax_f32(max0, max0); + + return max1; +} + +PX_FORCE_INLINE FloatV V4ExtractMin(const Vec4V a) +{ + const float32x2_t low = vget_low_f32(a); + const float32x2_t high = vget_high_f32(a); + + const float32x2_t min0 = vpmin_f32(high, low); + const float32x2_t min1 = vpmin_f32(min0, min0); + + return min1; +} + +PX_FORCE_INLINE Vec4V V4Clamp(const Vec4V a, const Vec4V minV, const Vec4V maxV) +{ + return V4Max(V4Min(a, maxV), minV); +} + +PX_FORCE_INLINE PxU32 V4AllGrtr(const Vec4V a, const Vec4V b) +{ + return internalUnitNeonSimd::BAllTrue4_R(V4IsGrtr(a, b)); +} + +PX_FORCE_INLINE PxU32 V4AllGrtrOrEq(const Vec4V a, const Vec4V b) +{ + return internalUnitNeonSimd::BAllTrue4_R(V4IsGrtrOrEq(a, b)); +} + +PX_FORCE_INLINE PxU32 V4AllGrtrOrEq3(const Vec4V a, const Vec4V b) +{ + return internalUnitNeonSimd::BAllTrue3_R(V4IsGrtrOrEq(a, b)); +} + +PX_FORCE_INLINE PxU32 V4AllEq(const Vec4V a, const Vec4V b) +{ + return internalUnitNeonSimd::BAllTrue4_R(V4IsEq(a, b)); +} + +PX_FORCE_INLINE PxU32 V4AnyGrtr3(const Vec4V a, const Vec4V b) +{ + return internalUnitNeonSimd::BAnyTrue3_R(V4IsGrtr(a, b)); +} + +PX_FORCE_INLINE Vec4V V4Round(const Vec4V a) +{ + // truncate(a + (0.5f - sign(a))) + const Vec4V half = V4Load(0.5f); + const float32x4_t sign = vcvtq_f32_u32((vshrq_n_u32(vreinterpretq_u32_f32(a), 31))); + const Vec4V aPlusHalf = V4Add(a, half); + const Vec4V aRound = V4Sub(aPlusHalf, sign); + return vcvtq_f32_s32(vcvtq_s32_f32(aRound)); +} + +PX_FORCE_INLINE Vec4V V4Sin(const Vec4V a) +{ + const Vec4V recipTwoPi = V4LoadA(g_PXReciprocalTwoPi.f); + const Vec4V twoPi = V4LoadA(g_PXTwoPi.f); + const Vec4V tmp = V4Mul(a, recipTwoPi); + const Vec4V b = V4Round(tmp); + const Vec4V V1 = V4NegMulSub(twoPi, b, a); + + // sin(V) ~= V - V^3 / 3! + V^5 / 5! - V^7 / 7! + V^9 / 9! - V^11 / 11! + V^13 / 13! - + // V^15 / 15! + V^17 / 17! - V^19 / 19! + V^21 / 21! - V^23 / 23! (for -PI <= V < PI) + const Vec4V V2 = V4Mul(V1, V1); + const Vec4V V3 = V4Mul(V2, V1); + const Vec4V V5 = V4Mul(V3, V2); + const Vec4V V7 = V4Mul(V5, V2); + const Vec4V V9 = V4Mul(V7, V2); + const Vec4V V11 = V4Mul(V9, V2); + const Vec4V V13 = V4Mul(V11, V2); + const Vec4V V15 = V4Mul(V13, V2); + const Vec4V V17 = V4Mul(V15, V2); + const Vec4V V19 = V4Mul(V17, V2); + const Vec4V V21 = V4Mul(V19, V2); + const Vec4V V23 = V4Mul(V21, V2); + + const Vec4V sinCoefficients0 = V4LoadA(g_PXSinCoefficients0.f); + const Vec4V sinCoefficients1 = V4LoadA(g_PXSinCoefficients1.f); + const Vec4V sinCoefficients2 = V4LoadA(g_PXSinCoefficients2.f); + + const FloatV S1 = V4GetY(sinCoefficients0); + const FloatV S2 = V4GetZ(sinCoefficients0); + const FloatV S3 = V4GetW(sinCoefficients0); + const FloatV S4 = V4GetX(sinCoefficients1); + const FloatV S5 = V4GetY(sinCoefficients1); + const FloatV S6 = V4GetZ(sinCoefficients1); + const FloatV S7 = V4GetW(sinCoefficients1); + const FloatV S8 = V4GetX(sinCoefficients2); + const FloatV S9 = V4GetY(sinCoefficients2); + const FloatV S10 = V4GetZ(sinCoefficients2); + const FloatV S11 = V4GetW(sinCoefficients2); + + Vec4V Result; + Result = V4ScaleAdd(V3, S1, V1); + Result = V4ScaleAdd(V5, S2, Result); + Result = V4ScaleAdd(V7, S3, Result); + Result = V4ScaleAdd(V9, S4, Result); + Result = V4ScaleAdd(V11, S5, Result); + Result = V4ScaleAdd(V13, S6, Result); + Result = V4ScaleAdd(V15, S7, Result); + Result = V4ScaleAdd(V17, S8, Result); + Result = V4ScaleAdd(V19, S9, Result); + Result = V4ScaleAdd(V21, S10, Result); + Result = V4ScaleAdd(V23, S11, Result); + + return Result; +} + +PX_FORCE_INLINE Vec4V V4Cos(const Vec4V a) +{ + const Vec4V recipTwoPi = V4LoadA(g_PXReciprocalTwoPi.f); + const Vec4V twoPi = V4LoadA(g_PXTwoPi.f); + const Vec4V tmp = V4Mul(a, recipTwoPi); + const Vec4V b = V4Round(tmp); + const Vec4V V1 = V4NegMulSub(twoPi, b, a); + + // cos(V) ~= 1 - V^2 / 2! + V^4 / 4! - V^6 / 6! + V^8 / 8! - V^10 / 10! + V^12 / 12! - + // V^14 / 14! + V^16 / 16! - V^18 / 18! + V^20 / 20! - V^22 / 22! (for -PI <= V < PI) + const Vec4V V2 = V4Mul(V1, V1); + const Vec4V V4 = V4Mul(V2, V2); + const Vec4V V6 = V4Mul(V4, V2); + const Vec4V V8 = V4Mul(V4, V4); + const Vec4V V10 = V4Mul(V6, V4); + const Vec4V V12 = V4Mul(V6, V6); + const Vec4V V14 = V4Mul(V8, V6); + const Vec4V V16 = V4Mul(V8, V8); + const Vec4V V18 = V4Mul(V10, V8); + const Vec4V V20 = V4Mul(V10, V10); + const Vec4V V22 = V4Mul(V12, V10); + + const Vec4V cosCoefficients0 = V4LoadA(g_PXCosCoefficients0.f); + const Vec4V cosCoefficients1 = V4LoadA(g_PXCosCoefficients1.f); + const Vec4V cosCoefficients2 = V4LoadA(g_PXCosCoefficients2.f); + + const FloatV C1 = V4GetY(cosCoefficients0); + const FloatV C2 = V4GetZ(cosCoefficients0); + const FloatV C3 = V4GetW(cosCoefficients0); + const FloatV C4 = V4GetX(cosCoefficients1); + const FloatV C5 = V4GetY(cosCoefficients1); + const FloatV C6 = V4GetZ(cosCoefficients1); + const FloatV C7 = V4GetW(cosCoefficients1); + const FloatV C8 = V4GetX(cosCoefficients2); + const FloatV C9 = V4GetY(cosCoefficients2); + const FloatV C10 = V4GetZ(cosCoefficients2); + const FloatV C11 = V4GetW(cosCoefficients2); + + Vec4V Result; + Result = V4ScaleAdd(V2, C1, V4One()); + Result = V4ScaleAdd(V4, C2, Result); + Result = V4ScaleAdd(V6, C3, Result); + Result = V4ScaleAdd(V8, C4, Result); + Result = V4ScaleAdd(V10, C5, Result); + Result = V4ScaleAdd(V12, C6, Result); + Result = V4ScaleAdd(V14, C7, Result); + Result = V4ScaleAdd(V16, C8, Result); + Result = V4ScaleAdd(V18, C9, Result); + Result = V4ScaleAdd(V20, C10, Result); + Result = V4ScaleAdd(V22, C11, Result); + + return Result; +} + +PX_FORCE_INLINE void V4Transpose(Vec4V& col0, Vec4V& col1, Vec4V& col2, Vec4V& col3) +{ + const float32x4x2_t v0v1 = vzipq_f32(col0, col2); + const float32x4x2_t v2v3 = vzipq_f32(col1, col3); + const float32x4x2_t zip0 = vzipq_f32(v0v1.val[0], v2v3.val[0]); + const float32x4x2_t zip1 = vzipq_f32(v0v1.val[1], v2v3.val[1]); + col0 = zip0.val[0]; + col1 = zip0.val[1]; + col2 = zip1.val[0]; + col3 = zip1.val[1]; +} + +////////////////////////////////// +// VEC4V +////////////////////////////////// + +PX_FORCE_INLINE BoolV BFFFF() +{ + return vmovq_n_u32(0); +} + +PX_FORCE_INLINE BoolV BFFFT() +{ + const uint32x2_t zeros = vmov_n_u32(0); + const uint32x2_t ones = vmov_n_u32(0xffffFFFF); + const uint32x2_t zo = vext_u32(zeros, ones, 1); + return vcombine_u32(zeros, zo); +} + +PX_FORCE_INLINE BoolV BFFTF() +{ + const uint32x2_t zeros = vmov_n_u32(0); + const uint32x2_t ones = vmov_n_u32(0xffffFFFF); + const uint32x2_t oz = vext_u32(ones, zeros, 1); + return vcombine_u32(zeros, oz); +} + +PX_FORCE_INLINE BoolV BFFTT() +{ + const uint32x2_t zeros = vmov_n_u32(0); + const uint32x2_t ones = vmov_n_u32(0xffffFFFF); + return vcombine_u32(zeros, ones); +} + +PX_FORCE_INLINE BoolV BFTFF() +{ + const uint32x2_t zeros = vmov_n_u32(0); + const uint32x2_t ones = vmov_n_u32(0xffffFFFF); + const uint32x2_t zo = vext_u32(zeros, ones, 1); + return vcombine_u32(zo, zeros); +} + +PX_FORCE_INLINE BoolV BFTFT() +{ + const uint32x2_t zeros = vmov_n_u32(0); + const uint32x2_t ones = vmov_n_u32(0xffffFFFF); + const uint32x2_t zo = vext_u32(zeros, ones, 1); + return vcombine_u32(zo, zo); +} + +PX_FORCE_INLINE BoolV BFTTF() +{ + const uint32x2_t zeros = vmov_n_u32(0); + const uint32x2_t ones = vmov_n_u32(0xffffFFFF); + const uint32x2_t zo = vext_u32(zeros, ones, 1); + const uint32x2_t oz = vext_u32(ones, zeros, 1); + return vcombine_u32(zo, oz); +} + +PX_FORCE_INLINE BoolV BFTTT() +{ + const uint32x2_t zeros = vmov_n_u32(0); + const uint32x2_t ones = vmov_n_u32(0xffffFFFF); + const uint32x2_t zo = vext_u32(zeros, ones, 1); + return vcombine_u32(zo, ones); +} + +PX_FORCE_INLINE BoolV BTFFF() +{ + const uint32x2_t zeros = vmov_n_u32(0); + const uint32x2_t ones = vmov_n_u32(0xffffFFFF); + // const uint32x2_t zo = vext_u32(zeros, ones, 1); + const uint32x2_t oz = vext_u32(ones, zeros, 1); + return vcombine_u32(oz, zeros); +} + +PX_FORCE_INLINE BoolV BTFFT() +{ + const uint32x2_t zeros = vmov_n_u32(0); + const uint32x2_t ones = vmov_n_u32(0xffffFFFF); + const uint32x2_t zo = vext_u32(zeros, ones, 1); + const uint32x2_t oz = vext_u32(ones, zeros, 1); + return vcombine_u32(oz, zo); +} + +PX_FORCE_INLINE BoolV BTFTF() +{ + const uint32x2_t zeros = vmov_n_u32(0); + const uint32x2_t ones = vmov_n_u32(0xffffFFFF); + const uint32x2_t oz = vext_u32(ones, zeros, 1); + return vcombine_u32(oz, oz); +} + +PX_FORCE_INLINE BoolV BTFTT() +{ + const uint32x2_t zeros = vmov_n_u32(0); + const uint32x2_t ones = vmov_n_u32(0xffffFFFF); + const uint32x2_t oz = vext_u32(ones, zeros, 1); + return vcombine_u32(oz, ones); +} + +PX_FORCE_INLINE BoolV BTTFF() +{ + const uint32x2_t zeros = vmov_n_u32(0); + const uint32x2_t ones = vmov_n_u32(0xffffFFFF); + return vcombine_u32(ones, zeros); +} + +PX_FORCE_INLINE BoolV BTTFT() +{ + const uint32x2_t zeros = vmov_n_u32(0); + const uint32x2_t ones = vmov_n_u32(0xffffFFFF); + const uint32x2_t zo = vext_u32(zeros, ones, 1); + return vcombine_u32(ones, zo); +} + +PX_FORCE_INLINE BoolV BTTTF() +{ + const uint32x2_t zeros = vmov_n_u32(0); + const uint32x2_t ones = vmov_n_u32(0xffffFFFF); + const uint32x2_t oz = vext_u32(ones, zeros, 1); + return vcombine_u32(ones, oz); +} + +PX_FORCE_INLINE BoolV BTTTT() +{ + return vmovq_n_u32(0xffffFFFF); +} + +PX_FORCE_INLINE BoolV BXMask() +{ + return BTFFF(); +} + +PX_FORCE_INLINE BoolV BYMask() +{ + return BFTFF(); +} + +PX_FORCE_INLINE BoolV BZMask() +{ + return BFFTF(); +} + +PX_FORCE_INLINE BoolV BWMask() +{ + return BFFFT(); +} + +PX_FORCE_INLINE BoolV BGetX(const BoolV f) +{ + const uint32x2_t fLow = vget_low_u32(f); + return vdupq_lane_u32(fLow, 0); +} + +PX_FORCE_INLINE BoolV BGetY(const BoolV f) +{ + const uint32x2_t fLow = vget_low_u32(f); + return vdupq_lane_u32(fLow, 1); +} + +PX_FORCE_INLINE BoolV BGetZ(const BoolV f) +{ + const uint32x2_t fHigh = vget_high_u32(f); + return vdupq_lane_u32(fHigh, 0); +} + +PX_FORCE_INLINE BoolV BGetW(const BoolV f) +{ + const uint32x2_t fHigh = vget_high_u32(f); + return vdupq_lane_u32(fHigh, 1); +} + +PX_FORCE_INLINE BoolV BSetX(const BoolV v, const BoolV f) +{ + return vbslq_u32(BFTTT(), v, f); +} + +PX_FORCE_INLINE BoolV BSetY(const BoolV v, const BoolV f) +{ + return vbslq_u32(BTFTT(), v, f); +} + +PX_FORCE_INLINE BoolV BSetZ(const BoolV v, const BoolV f) +{ + return vbslq_u32(BTTFT(), v, f); +} + +PX_FORCE_INLINE BoolV BSetW(const BoolV v, const BoolV f) +{ + return vbslq_u32(BTTTF(), v, f); +} + +PX_FORCE_INLINE BoolV BAnd(const BoolV a, const BoolV b) +{ + return vandq_u32(a, b); +} + +PX_FORCE_INLINE BoolV BNot(const BoolV a) +{ + return vmvnq_u32(a); +} + +PX_FORCE_INLINE BoolV BAndNot(const BoolV a, const BoolV b) +{ + // return vbicq_u32(a, b); + return vandq_u32(a, vmvnq_u32(b)); +} + +PX_FORCE_INLINE BoolV BOr(const BoolV a, const BoolV b) +{ + return vorrq_u32(a, b); +} + +PX_FORCE_INLINE BoolV BAllTrue4(const BoolV a) +{ + const uint32x2_t allTrue = vmov_n_u32(0xffffFFFF); + const uint16x4_t dHigh = vget_high_u16(vreinterpretq_u16_u32(a)); + const uint16x4_t dLow = vmovn_u32(a); + uint16x8_t combined = vcombine_u16(dLow, dHigh); + const uint32x2_t finalReduce = vreinterpret_u32_u8(vmovn_u16(combined)); + const uint32x2_t result = vceq_u32(finalReduce, allTrue); + return vdupq_lane_u32(result, 0); +} + +PX_FORCE_INLINE BoolV BAnyTrue4(const BoolV a) +{ + const uint32x2_t allTrue = vmov_n_u32(0xffffFFFF); + const uint16x4_t dHigh = vget_high_u16(vreinterpretq_u16_u32(a)); + const uint16x4_t dLow = vmovn_u32(a); + uint16x8_t combined = vcombine_u16(dLow, dHigh); + const uint32x2_t finalReduce = vreinterpret_u32_u8(vmovn_u16(combined)); + const uint32x2_t result = vtst_u32(finalReduce, allTrue); + return vdupq_lane_u32(result, 0); +} + +PX_FORCE_INLINE BoolV BAllTrue3(const BoolV a) +{ + const uint32x2_t allTrue3 = vmov_n_u32(0x00ffFFFF); + const uint16x4_t dHigh = vget_high_u16(vreinterpretq_u16_u32(a)); + const uint16x4_t dLow = vmovn_u32(a); + uint16x8_t combined = vcombine_u16(dLow, dHigh); + const uint32x2_t finalReduce = vreinterpret_u32_u8(vmovn_u16(combined)); + const uint32x2_t result = vceq_u32(vand_u32(finalReduce, allTrue3), allTrue3); + return vdupq_lane_u32(result, 0); +} + +PX_FORCE_INLINE BoolV BAnyTrue3(const BoolV a) +{ + const uint32x2_t allTrue3 = vmov_n_u32(0x00ffFFFF); + const uint16x4_t dHigh = vget_high_u16(vreinterpretq_u16_u32(a)); + const uint16x4_t dLow = vmovn_u32(a); + uint16x8_t combined = vcombine_u16(dLow, dHigh); + const uint32x2_t finalReduce = vreinterpret_u32_u8(vmovn_u16(combined)); + const uint32x2_t result = vtst_u32(vand_u32(finalReduce, allTrue3), allTrue3); + return vdupq_lane_u32(result, 0); +} + +PX_FORCE_INLINE PxU32 BAllEq(const BoolV a, const BoolV b) +{ + const BoolV bTest = vceqq_u32(a, b); + return internalUnitNeonSimd::BAllTrue4_R(bTest); +} + +PX_FORCE_INLINE PxU32 BAllEqTTTT(const BoolV a) +{ + return BAllEq(a, BTTTT()); +} + +PX_FORCE_INLINE PxU32 BAllEqFFFF(const BoolV a) +{ + return BAllEq(a, BFFFF()); +} + +PX_FORCE_INLINE PxU32 BGetBitMask(const BoolV a) +{ + static PX_ALIGN(16, const PxU32) bitMaskData[4] = { 1, 2, 4, 8 }; + const uint32x4_t bitMask = *(reinterpret_cast(bitMaskData)); + const uint32x4_t t0 = vandq_u32(a, bitMask); + const uint32x2_t t1 = vpadd_u32(vget_low_u32(t0), vget_high_u32(t0)); // Pairwise add (0 + 1), (2 + 3) + return PxU32(vget_lane_u32(vpadd_u32(t1, t1), 0)); +} + +////////////////////////////////// +// MAT33V +////////////////////////////////// + +PX_FORCE_INLINE Vec3V M33MulV3(const Mat33V& a, const Vec3V b) +{ + const FloatV x = V3GetX(b); + const FloatV y = V3GetY(b); + const FloatV z = V3GetZ(b); + const Vec3V v0 = V3Scale(a.col0, x); + const Vec3V v1 = V3Scale(a.col1, y); + const Vec3V v2 = V3Scale(a.col2, z); + const Vec3V v0PlusV1 = V3Add(v0, v1); + return V3Add(v0PlusV1, v2); +} + +PX_FORCE_INLINE Vec3V M33TrnspsMulV3(const Mat33V& a, const Vec3V b) +{ + const FloatV x = V3Dot(a.col0, b); + const FloatV y = V3Dot(a.col1, b); + const FloatV z = V3Dot(a.col2, b); + return V3Merge(x, y, z); +} + +PX_FORCE_INLINE Vec3V M33MulV3AddV3(const Mat33V& A, const Vec3V b, const Vec3V c) +{ + const FloatV x = V3GetX(b); + const FloatV y = V3GetY(b); + const FloatV z = V3GetZ(b); + Vec3V result = V3ScaleAdd(A.col0, x, c); + result = V3ScaleAdd(A.col1, y, result); + return V3ScaleAdd(A.col2, z, result); +} + +PX_FORCE_INLINE Mat33V M33MulM33(const Mat33V& a, const Mat33V& b) +{ + return Mat33V(M33MulV3(a, b.col0), M33MulV3(a, b.col1), M33MulV3(a, b.col2)); +} + +PX_FORCE_INLINE Mat33V M33Add(const Mat33V& a, const Mat33V& b) +{ + return Mat33V(V3Add(a.col0, b.col0), V3Add(a.col1, b.col1), V3Add(a.col2, b.col2)); +} + +PX_FORCE_INLINE Mat33V M33Scale(const Mat33V& a, const FloatV& b) +{ + return Mat33V(V3Scale(a.col0, b), V3Scale(a.col1, b), V3Scale(a.col2, b)); +} + +PX_FORCE_INLINE Mat33V M33Inverse(const Mat33V& a) +{ + const float32x2_t zeros = vreinterpret_f32_u32(vmov_n_u32(0)); + const BoolV btttf = BTTTF(); + + const Vec3V cross01 = V3Cross(a.col0, a.col1); + const Vec3V cross12 = V3Cross(a.col1, a.col2); + const Vec3V cross20 = V3Cross(a.col2, a.col0); + const FloatV dot = V3Dot(cross01, a.col2); + const FloatV invDet = FRecipFast(dot); + + const float32x4x2_t merge = vzipq_f32(cross12, cross01); + const float32x4_t mergeh = merge.val[0]; + const float32x4_t mergel = merge.val[1]; + + // const Vec3V colInv0 = XMVectorPermute(mergeh,cross20,PxPermuteControl(0,4,1,7)); + const float32x4_t colInv0_xxyy = vzipq_f32(mergeh, cross20).val[0]; + const float32x4_t colInv0 = vreinterpretq_f32_u32(vandq_u32(vreinterpretq_u32_f32(colInv0_xxyy), btttf)); + + // const Vec3V colInv1 = XMVectorPermute(mergeh,cross20,PxPermuteControl(2,5,3,7)); + const float32x2_t zw0 = vget_high_f32(mergeh); + const float32x2_t xy1 = vget_low_f32(cross20); + const float32x2_t yzero1 = vext_f32(xy1, zeros, 1); + const float32x2x2_t merge1 = vzip_f32(zw0, yzero1); + const float32x4_t colInv1 = vcombine_f32(merge1.val[0], merge1.val[1]); + + // const Vec3V colInv2 = XMVectorPermute(mergel,cross20,PxPermuteControl(0,6,1,7)); + const float32x2_t x0y0 = vget_low_f32(mergel); + const float32x2_t z1w1 = vget_high_f32(cross20); + const float32x2x2_t merge2 = vzip_f32(x0y0, z1w1); + const float32x4_t colInv2 = vcombine_f32(merge2.val[0], merge2.val[1]); + + return Mat33V(vmulq_lane_f32(colInv0, invDet, 0), vmulq_lane_f32(colInv1, invDet, 0), + vmulq_lane_f32(colInv2, invDet, 0)); +} + +PX_FORCE_INLINE Mat33V M33Trnsps(const Mat33V& a) +{ + return Mat33V(V3Merge(V3GetX(a.col0), V3GetX(a.col1), V3GetX(a.col2)), + V3Merge(V3GetY(a.col0), V3GetY(a.col1), V3GetY(a.col2)), + V3Merge(V3GetZ(a.col0), V3GetZ(a.col1), V3GetZ(a.col2))); +} + +PX_FORCE_INLINE Mat33V M33Identity() +{ + return Mat33V(V3UnitX(), V3UnitY(), V3UnitZ()); +} + +PX_FORCE_INLINE Mat33V M33Sub(const Mat33V& a, const Mat33V& b) +{ + return Mat33V(V3Sub(a.col0, b.col0), V3Sub(a.col1, b.col1), V3Sub(a.col2, b.col2)); +} + +PX_FORCE_INLINE Mat33V M33Neg(const Mat33V& a) +{ + return Mat33V(V3Neg(a.col0), V3Neg(a.col1), V3Neg(a.col2)); +} + +PX_FORCE_INLINE Mat33V M33Abs(const Mat33V& a) +{ + return Mat33V(V3Abs(a.col0), V3Abs(a.col1), V3Abs(a.col2)); +} + +PX_FORCE_INLINE Mat33V PromoteVec3V(const Vec3V v) +{ + const BoolV bTFFF = BTFFF(); + const BoolV bFTFF = BFTFF(); + const BoolV bFFTF = BTFTF(); + + const Vec3V zero = V3Zero(); + + return Mat33V(V3Sel(bTFFF, v, zero), V3Sel(bFTFF, v, zero), V3Sel(bFFTF, v, zero)); +} + +PX_FORCE_INLINE Mat33V M33Diagonal(const Vec3VArg d) +{ + const Vec3V x = V3Mul(V3UnitX(), d); + const Vec3V y = V3Mul(V3UnitY(), d); + const Vec3V z = V3Mul(V3UnitZ(), d); + return Mat33V(x, y, z); +} + +////////////////////////////////// +// MAT34V +////////////////////////////////// + +PX_FORCE_INLINE Vec3V M34MulV3(const Mat34V& a, const Vec3V b) +{ + const FloatV x = V3GetX(b); + const FloatV y = V3GetY(b); + const FloatV z = V3GetZ(b); + const Vec3V v0 = V3Scale(a.col0, x); + const Vec3V v1 = V3Scale(a.col1, y); + const Vec3V v2 = V3Scale(a.col2, z); + const Vec3V v0PlusV1 = V3Add(v0, v1); + const Vec3V v0PlusV1Plusv2 = V3Add(v0PlusV1, v2); + return V3Add(v0PlusV1Plusv2, a.col3); +} + +PX_FORCE_INLINE Vec3V M34Mul33V3(const Mat34V& a, const Vec3V b) +{ + const FloatV x = V3GetX(b); + const FloatV y = V3GetY(b); + const FloatV z = V3GetZ(b); + const Vec3V v0 = V3Scale(a.col0, x); + const Vec3V v1 = V3Scale(a.col1, y); + const Vec3V v2 = V3Scale(a.col2, z); + const Vec3V v0PlusV1 = V3Add(v0, v1); + return V3Add(v0PlusV1, v2); +} + +PX_FORCE_INLINE Vec3V M34TrnspsMul33V3(const Mat34V& a, const Vec3V b) +{ + const FloatV x = V3Dot(a.col0, b); + const FloatV y = V3Dot(a.col1, b); + const FloatV z = V3Dot(a.col2, b); + return V3Merge(x, y, z); +} + +PX_FORCE_INLINE Mat34V M34MulM34(const Mat34V& a, const Mat34V& b) +{ + return Mat34V(M34Mul33V3(a, b.col0), M34Mul33V3(a, b.col1), M34Mul33V3(a, b.col2), M34MulV3(a, b.col3)); +} + +PX_FORCE_INLINE Mat33V M34MulM33(const Mat34V& a, const Mat33V& b) +{ + return Mat33V(M34Mul33V3(a, b.col0), M34Mul33V3(a, b.col1), M34Mul33V3(a, b.col2)); +} + +PX_FORCE_INLINE Mat33V M34Mul33MM34(const Mat34V& a, const Mat34V& b) +{ + return Mat33V(M34Mul33V3(a, b.col0), M34Mul33V3(a, b.col1), M34Mul33V3(a, b.col2)); +} + +PX_FORCE_INLINE Mat34V M34Add(const Mat34V& a, const Mat34V& b) +{ + return Mat34V(V3Add(a.col0, b.col0), V3Add(a.col1, b.col1), V3Add(a.col2, b.col2), V3Add(a.col3, b.col3)); +} + +PX_FORCE_INLINE Mat33V M34Trnsps33(const Mat34V& a) +{ + return Mat33V(V3Merge(V3GetX(a.col0), V3GetX(a.col1), V3GetX(a.col2)), + V3Merge(V3GetY(a.col0), V3GetY(a.col1), V3GetY(a.col2)), + V3Merge(V3GetZ(a.col0), V3GetZ(a.col1), V3GetZ(a.col2))); +} + +////////////////////////////////// +// MAT44V +////////////////////////////////// + +PX_FORCE_INLINE Vec4V M44MulV4(const Mat44V& a, const Vec4V b) +{ + const FloatV x = V4GetX(b); + const FloatV y = V4GetY(b); + const FloatV z = V4GetZ(b); + const FloatV w = V4GetW(b); + + const Vec4V v0 = V4Scale(a.col0, x); + const Vec4V v1 = V4Scale(a.col1, y); + const Vec4V v2 = V4Scale(a.col2, z); + const Vec4V v3 = V4Scale(a.col3, w); + const Vec4V v0PlusV1 = V4Add(v0, v1); + const Vec4V v0PlusV1Plusv2 = V4Add(v0PlusV1, v2); + return V4Add(v0PlusV1Plusv2, v3); +} + +PX_FORCE_INLINE Vec4V M44TrnspsMulV4(const Mat44V& a, const Vec4V b) +{ + return V4Merge(V4Dot(a.col0, b), V4Dot(a.col1, b), V4Dot(a.col2, b), V4Dot(a.col3, b)); +} + +PX_FORCE_INLINE Mat44V M44MulM44(const Mat44V& a, const Mat44V& b) +{ + return Mat44V(M44MulV4(a, b.col0), M44MulV4(a, b.col1), M44MulV4(a, b.col2), M44MulV4(a, b.col3)); +} + +PX_FORCE_INLINE Mat44V M44Add(const Mat44V& a, const Mat44V& b) +{ + return Mat44V(V4Add(a.col0, b.col0), V4Add(a.col1, b.col1), V4Add(a.col2, b.col2), V4Add(a.col3, b.col3)); +} + +PX_FORCE_INLINE Mat44V M44Trnsps(const Mat44V& a) +{ + // asm volatile( + // "vzip.f32 %q0, %q2 \n\t" + // "vzip.f32 %q1, %q3 \n\t" + // "vzip.f32 %q0, %q1 \n\t" + // "vzip.f32 %q2, %q3 \n\t" + // : "+w" (a.col0), "+w" (a.col1), "+w" (a.col2), "+w" a.col3)); + + const float32x4x2_t v0v1 = vzipq_f32(a.col0, a.col2); + const float32x4x2_t v2v3 = vzipq_f32(a.col1, a.col3); + const float32x4x2_t zip0 = vzipq_f32(v0v1.val[0], v2v3.val[0]); + const float32x4x2_t zip1 = vzipq_f32(v0v1.val[1], v2v3.val[1]); + + return Mat44V(zip0.val[0], zip0.val[1], zip1.val[0], zip1.val[1]); +} + +PX_FORCE_INLINE Mat44V M44Inverse(const Mat44V& a) +{ + float32x4_t minor0, minor1, minor2, minor3; + float32x4_t row0, row1, row2, row3; + float32x4_t det, tmp1; + + tmp1 = vmovq_n_f32(0.0f); + row1 = vmovq_n_f32(0.0f); + row3 = vmovq_n_f32(0.0f); + + row0 = a.col0; + row1 = vextq_f32(a.col1, a.col1, 2); + row2 = a.col2; + row3 = vextq_f32(a.col3, a.col3, 2); + + tmp1 = vmulq_f32(row2, row3); + tmp1 = vrev64q_f32(tmp1); + minor0 = vmulq_f32(row1, tmp1); + minor1 = vmulq_f32(row0, tmp1); + tmp1 = vextq_f32(tmp1, tmp1, 2); + minor0 = vsubq_f32(vmulq_f32(row1, tmp1), minor0); + minor1 = vsubq_f32(vmulq_f32(row0, tmp1), minor1); + minor1 = vextq_f32(minor1, minor1, 2); + + tmp1 = vmulq_f32(row1, row2); + tmp1 = vrev64q_f32(tmp1); + minor0 = vaddq_f32(vmulq_f32(row3, tmp1), minor0); + minor3 = vmulq_f32(row0, tmp1); + tmp1 = vextq_f32(tmp1, tmp1, 2); + minor0 = vsubq_f32(minor0, vmulq_f32(row3, tmp1)); + minor3 = vsubq_f32(vmulq_f32(row0, tmp1), minor3); + minor3 = vextq_f32(minor3, minor3, 2); + + tmp1 = vmulq_f32(vextq_f32(row1, row1, 2), row3); + tmp1 = vrev64q_f32(tmp1); + row2 = vextq_f32(row2, row2, 2); + minor0 = vaddq_f32(vmulq_f32(row2, tmp1), minor0); + minor2 = vmulq_f32(row0, tmp1); + tmp1 = vextq_f32(tmp1, tmp1, 2); + minor0 = vsubq_f32(minor0, vmulq_f32(row2, tmp1)); + minor2 = vsubq_f32(vmulq_f32(row0, tmp1), minor2); + minor2 = vextq_f32(minor2, minor2, 2); + + tmp1 = vmulq_f32(row0, row1); + tmp1 = vrev64q_f32(tmp1); + minor2 = vaddq_f32(vmulq_f32(row3, tmp1), minor2); + minor3 = vsubq_f32(vmulq_f32(row2, tmp1), minor3); + tmp1 = vextq_f32(tmp1, tmp1, 2); + minor2 = vsubq_f32(vmulq_f32(row3, tmp1), minor2); + minor3 = vsubq_f32(minor3, vmulq_f32(row2, tmp1)); + + tmp1 = vmulq_f32(row0, row3); + tmp1 = vrev64q_f32(tmp1); + minor1 = vsubq_f32(minor1, vmulq_f32(row2, tmp1)); + minor2 = vaddq_f32(vmulq_f32(row1, tmp1), minor2); + tmp1 = vextq_f32(tmp1, tmp1, 2); + minor1 = vaddq_f32(vmulq_f32(row2, tmp1), minor1); + minor2 = vsubq_f32(minor2, vmulq_f32(row1, tmp1)); + + tmp1 = vmulq_f32(row0, row2); + tmp1 = vrev64q_f32(tmp1); + minor1 = vaddq_f32(vmulq_f32(row3, tmp1), minor1); + minor3 = vsubq_f32(minor3, vmulq_f32(row1, tmp1)); + tmp1 = vextq_f32(tmp1, tmp1, 2); + minor1 = vsubq_f32(minor1, vmulq_f32(row3, tmp1)); + minor3 = vaddq_f32(vmulq_f32(row1, tmp1), minor3); + + det = vmulq_f32(row0, minor0); + det = vaddq_f32(vextq_f32(det, det, 2), det); + det = vaddq_f32(vrev64q_f32(det), det); + det = vdupq_lane_f32(VRECIPE(vget_low_f32(det)), 0); + + minor0 = vmulq_f32(det, minor0); + minor1 = vmulq_f32(det, minor1); + minor2 = vmulq_f32(det, minor2); + minor3 = vmulq_f32(det, minor3); + Mat44V invTrans(minor0, minor1, minor2, minor3); + return M44Trnsps(invTrans); +} + +PX_FORCE_INLINE Vec4V V4LoadXYZW(const PxF32& x, const PxF32& y, const PxF32& z, const PxF32& w) +{ + const float32x4_t ret = { x, y, z, w }; + return ret; +} + +/* +PX_FORCE_INLINE VecU16V V4U32PK(VecU32V a, VecU32V b) +{ + return vcombine_u16(vqmovn_u32(a), vqmovn_u32(b)); +} +*/ + +PX_FORCE_INLINE VecU32V V4U32Sel(const BoolV c, const VecU32V a, const VecU32V b) +{ + return vbslq_u32(c, a, b); +} + +PX_FORCE_INLINE VecU32V V4U32or(VecU32V a, VecU32V b) +{ + return vorrq_u32(a, b); +} + +PX_FORCE_INLINE VecU32V V4U32xor(VecU32V a, VecU32V b) +{ + return veorq_u32(a, b); +} + +PX_FORCE_INLINE VecU32V V4U32and(VecU32V a, VecU32V b) +{ + return vandq_u32(a, b); +} + +PX_FORCE_INLINE VecU32V V4U32Andc(VecU32V a, VecU32V b) +{ + // return vbicq_u32(a, b); // creates gcc compiler bug in RTreeQueries.cpp + return vandq_u32(a, vmvnq_u32(b)); +} + +/* +PX_FORCE_INLINE VecU16V V4U16Or(VecU16V a, VecU16V b) +{ + return vorrq_u16(a, b); +} +*/ + +/* +PX_FORCE_INLINE VecU16V V4U16And(VecU16V a, VecU16V b) +{ + return vandq_u16(a, b); +} +*/ +/* +PX_FORCE_INLINE VecU16V V4U16Andc(VecU16V a, VecU16V b) +{ + return vbicq_u16(a, b); +} +*/ + +PX_FORCE_INLINE VecI32V I4LoadXYZW(const PxI32& x, const PxI32& y, const PxI32& z, const PxI32& w) +{ + const int32x4_t ret = { x, y, z, w }; + return ret; +} + +PX_FORCE_INLINE VecI32V I4Load(const PxI32 i) +{ + return vdupq_n_s32(i); +} + +PX_FORCE_INLINE VecI32V I4LoadU(const PxI32* i) +{ + return vld1q_s32(i); +} + +PX_FORCE_INLINE VecI32V I4LoadA(const PxI32* i) +{ + return vld1q_s32(i); +} + +PX_FORCE_INLINE VecI32V VecI32V_Add(const VecI32VArg a, const VecI32VArg b) +{ + return vaddq_s32(a, b); +} + +PX_FORCE_INLINE VecI32V VecI32V_Sub(const VecI32VArg a, const VecI32VArg b) +{ + return vsubq_s32(a, b); +} + +PX_FORCE_INLINE BoolV VecI32V_IsGrtr(const VecI32VArg a, const VecI32VArg b) +{ + return vcgtq_s32(a, b); +} + +PX_FORCE_INLINE BoolV VecI32V_IsEq(const VecI32VArg a, const VecI32VArg b) +{ + return vceqq_s32(a, b); +} + +PX_FORCE_INLINE VecI32V V4I32Sel(const BoolV c, const VecI32V a, const VecI32V b) +{ + return vbslq_s32(c, a, b); +} + +PX_FORCE_INLINE VecI32V VecI32V_Zero() +{ + return vdupq_n_s32(0); +} + +PX_FORCE_INLINE VecI32V VecI32V_One() +{ + return vdupq_n_s32(1); +} + +PX_FORCE_INLINE VecI32V VecI32V_Two() +{ + return vdupq_n_s32(2); +} + +PX_FORCE_INLINE VecI32V VecI32V_MinusOne() +{ + return vdupq_n_s32(-1); +} + +PX_FORCE_INLINE VecU32V U4Zero() +{ + return U4Load(0); +} + +PX_FORCE_INLINE VecU32V U4One() +{ + return U4Load(1); +} + +PX_FORCE_INLINE VecU32V U4Two() +{ + return U4Load(2); +} + +PX_FORCE_INLINE VecShiftV VecI32V_PrepareShift(const VecI32VArg shift) +{ + return shift; +} + +PX_FORCE_INLINE VecI32V VecI32V_LeftShift(const VecI32VArg a, const VecShiftVArg count) +{ + return vshlq_s32(a, count); +} + +PX_FORCE_INLINE VecI32V VecI32V_RightShift(const VecI32VArg a, const VecShiftVArg count) +{ + return vshlq_s32(a, VecI32V_Sub(I4Load(0), count)); +} + +PX_FORCE_INLINE VecI32V VecI32V_LeftShift(const VecI32VArg a, const PxU32 count) +{ + const int32x4_t shiftCount = { (PxI32)count, (PxI32)count, (PxI32)count, (PxI32)count }; + return vshlq_s32(a, shiftCount); +} + +PX_FORCE_INLINE VecI32V VecI32V_RightShift(const VecI32VArg a, const PxU32 count) +{ + const int32x4_t shiftCount = { -(PxI32)count, -(PxI32)count, -(PxI32)count, -(PxI32)count }; + return vshlq_s32(a, shiftCount); +} + +PX_FORCE_INLINE VecI32V VecI32V_And(const VecI32VArg a, const VecI32VArg b) +{ + return vandq_s32(a, b); +} + +PX_FORCE_INLINE VecI32V VecI32V_Or(const VecI32VArg a, const VecI32VArg b) +{ + return vorrq_s32(a, b); +} + +PX_FORCE_INLINE VecI32V VecI32V_GetX(const VecI32VArg f) +{ + const int32x2_t fLow = vget_low_s32(f); + return vdupq_lane_s32(fLow, 0); +} + +PX_FORCE_INLINE VecI32V VecI32V_GetY(const VecI32VArg f) +{ + const int32x2_t fLow = vget_low_s32(f); + return vdupq_lane_s32(fLow, 1); +} + +PX_FORCE_INLINE VecI32V VecI32V_GetZ(const VecI32VArg f) +{ + const int32x2_t fHigh = vget_high_s32(f); + return vdupq_lane_s32(fHigh, 0); +} + +PX_FORCE_INLINE VecI32V VecI32V_GetW(const VecI32VArg f) +{ + const int32x2_t fHigh = vget_high_s32(f); + return vdupq_lane_s32(fHigh, 1); +} + +PX_FORCE_INLINE VecI32V VecI32V_Sel(const BoolV c, const VecI32VArg a, const VecI32VArg b) +{ + return vbslq_s32(c, a, b); +} + +PX_FORCE_INLINE void PxI32_From_VecI32V(const VecI32VArg a, PxI32* i) +{ + *i = vgetq_lane_s32(a, 0); +} + +PX_FORCE_INLINE VecI32V VecI32V_Merge(const VecI32VArg a, const VecI32VArg b, const VecI32VArg c, const VecI32VArg d) +{ + const int32x2_t aLow = vget_low_s32(a); + const int32x2_t bLow = vget_low_s32(b); + const int32x2_t cLow = vget_low_s32(c); + const int32x2_t dLow = vget_low_s32(d); + + const int32x2_t low = vext_s32(aLow, bLow, 1); + const int32x2_t high = vext_s32(cLow, dLow, 1); + + return vcombine_s32(low, high); +} + +PX_FORCE_INLINE VecI32V VecI32V_From_BoolV(const BoolVArg a) +{ + return vreinterpretq_s32_u32(a); +} + +PX_FORCE_INLINE VecU32V VecU32V_From_BoolV(const BoolVArg a) +{ + return a; +} + +/* +template PX_FORCE_INLINE VecI32V V4ISplat() +{ + return vdupq_n_s32(a); +} + +template PX_FORCE_INLINE VecU32V V4USplat() +{ + return vdupq_n_u32(a); +} +*/ + +/* +PX_FORCE_INLINE void V4U16StoreAligned(VecU16V val, VecU16V* address) +{ + vst1q_u16((uint16_t*)address, val); +} +*/ + +PX_FORCE_INLINE void V4U32StoreAligned(VecU32V val, VecU32V* address) +{ + vst1q_u32(reinterpret_cast(address), val); +} + +PX_FORCE_INLINE Vec4V V4LoadAligned(Vec4V* addr) +{ + return vld1q_f32(reinterpret_cast(addr)); +} + +PX_FORCE_INLINE Vec4V V4LoadUnaligned(Vec4V* addr) +{ + return vld1q_f32(reinterpret_cast(addr)); +} + +PX_FORCE_INLINE Vec4V V4Andc(const Vec4V a, const VecU32V b) +{ + return vreinterpretq_f32_u32(V4U32Andc(vreinterpretq_u32_f32(a), b)); +} + +PX_FORCE_INLINE VecU32V V4IsGrtrV32u(const Vec4V a, const Vec4V b) +{ + return V4IsGrtr(a, b); +} + +PX_FORCE_INLINE VecU16V V4U16LoadAligned(VecU16V* addr) +{ + return vld1q_u16(reinterpret_cast(addr)); +} + +PX_FORCE_INLINE VecU16V V4U16LoadUnaligned(VecU16V* addr) +{ + return vld1q_u16(reinterpret_cast(addr)); +} + +PX_FORCE_INLINE VecU16V V4U16CompareGt(VecU16V a, VecU16V b) +{ + return vcgtq_u16(a, b); +} + +PX_FORCE_INLINE VecU16V V4I16CompareGt(VecI16V a, VecI16V b) +{ + return vcgtq_s16(a, b); +} + +PX_FORCE_INLINE Vec4V Vec4V_From_VecU32V(VecU32V a) +{ + return vcvtq_f32_u32(a); +} + +PX_FORCE_INLINE Vec4V Vec4V_From_VecI32V(VecI32V a) +{ + return vcvtq_f32_s32(a); +} + +PX_FORCE_INLINE VecI32V VecI32V_From_Vec4V(Vec4V a) +{ + return vcvtq_s32_f32(a); +} + +PX_FORCE_INLINE Vec4V Vec4V_ReinterpretFrom_VecU32V(VecU32V a) +{ + return vreinterpretq_f32_u32(a); +} + +PX_FORCE_INLINE Vec4V Vec4V_ReinterpretFrom_VecI32V(VecI32V a) +{ + return vreinterpretq_f32_s32(a); +} + +PX_FORCE_INLINE VecU32V VecU32V_ReinterpretFrom_Vec4V(Vec4V a) +{ + return vreinterpretq_u32_f32(a); +} + +PX_FORCE_INLINE VecI32V VecI32V_ReinterpretFrom_Vec4V(Vec4V a) +{ + return vreinterpretq_s32_f32(a); +} + +#if !PX_SWITCH +template +PX_FORCE_INLINE BoolV BSplatElement(BoolV a) +{ + if(index < 2) + { + return vdupq_lane_u32(vget_low_u32(a), index); + } + else if(index == 2) + { + return vdupq_lane_u32(vget_high_u32(a), 0); + } + else if(index == 3) + { + return vdupq_lane_u32(vget_high_u32(a), 1); + } +} +#else +//workaround for template compile issue +template PX_FORCE_INLINE BoolV BSplatElement(BoolV a); +template<> PX_FORCE_INLINE BoolV BSplatElement<0>(BoolV a) { return vdupq_lane_u32(vget_low_u32(a), 0); } +template<> PX_FORCE_INLINE BoolV BSplatElement<1>(BoolV a) { return vdupq_lane_u32(vget_low_u32(a), 1); } +template<> PX_FORCE_INLINE BoolV BSplatElement<2>(BoolV a) { return vdupq_lane_u32(vget_high_u32(a), 0); } +template<> PX_FORCE_INLINE BoolV BSplatElement<3>(BoolV a) { return vdupq_lane_u32(vget_high_u32(a), 1); } +#endif + +#if !PX_SWITCH +template +PX_FORCE_INLINE VecU32V V4U32SplatElement(VecU32V a) +{ + if(index < 2) + { + return vdupq_lane_u32(vget_low_u32(a), index); + } + else if(index == 2) + { + return vdupq_lane_u32(vget_high_u32(a), 0); + } + else if(index == 3) + { + return vdupq_lane_u32(vget_high_u32(a), 1); + } +} +#else +//workaround for template compile issue +template PX_FORCE_INLINE VecU32V V4U32SplatElement(VecU32V a); +template <> PX_FORCE_INLINE VecU32V V4U32SplatElement<0>(VecU32V a) { return vdupq_lane_u32(vget_low_u32(a), 0); } +template <> PX_FORCE_INLINE VecU32V V4U32SplatElement<1>(VecU32V a) { return vdupq_lane_u32(vget_low_u32(a), 1); } +template <> PX_FORCE_INLINE VecU32V V4U32SplatElement<2>(VecU32V a) { return vdupq_lane_u32(vget_high_u32(a), 0); } +template <> PX_FORCE_INLINE VecU32V V4U32SplatElement<3>(VecU32V a) { return vdupq_lane_u32(vget_high_u32(a), 1); } +#endif + +#if !PX_SWITCH +template +PX_FORCE_INLINE Vec4V V4SplatElement(Vec4V a) +{ + if(index == 0) + { + return vdupq_lane_f32(vget_low_f32(a), 0); + } + else if (index == 1) + { + return vdupq_lane_f32(vget_low_f32(a), 1); + } + else if(index == 2) + { + return vdupq_lane_f32(vget_high_f32(a), 0); + } + else if(index == 3) + { + return vdupq_lane_f32(vget_high_f32(a), 1); + } +} +#else +//workaround for template compile issue +template PX_FORCE_INLINE Vec4V V4SplatElement(Vec4V a); +template <> PX_FORCE_INLINE Vec4V V4SplatElement<0>(Vec4V a) { return vdupq_lane_f32(vget_low_f32(a), 0); } +template <> PX_FORCE_INLINE Vec4V V4SplatElement<1>(Vec4V a) { return vdupq_lane_f32(vget_low_f32(a), 1); } +template <> PX_FORCE_INLINE Vec4V V4SplatElement<2>(Vec4V a) { return vdupq_lane_f32(vget_high_f32(a), 0); } +template <> PX_FORCE_INLINE Vec4V V4SplatElement<3>(Vec4V a) { return vdupq_lane_f32(vget_high_f32(a), 1); } +#endif + +PX_FORCE_INLINE VecU32V U4LoadXYZW(PxU32 x, PxU32 y, PxU32 z, PxU32 w) +{ + const uint32x4_t ret = { x, y, z, w }; + return ret; +} + +PX_FORCE_INLINE VecU32V U4Load(const PxU32 i) +{ + return vdupq_n_u32(i); +} + +PX_FORCE_INLINE VecU32V U4LoadU(const PxU32* i) +{ + return vld1q_u32(i); +} + +PX_FORCE_INLINE VecU32V U4LoadA(const PxU32* i) +{ + return vld1q_u32(i); +} + +PX_FORCE_INLINE Vec4V V4Ceil(const Vec4V in) +{ + const float32x4_t ones = vdupq_n_f32(1.0f); + const float32x4_t rdToZero = vcvtq_f32_s32(vcvtq_s32_f32(in)); + const float32x4_t rdToZeroPlusOne = vaddq_f32(rdToZero, ones); + const uint32x4_t gt = vcgtq_f32(in, rdToZero); + return vbslq_f32(gt, rdToZeroPlusOne, rdToZero); +} + +PX_FORCE_INLINE Vec4V V4Floor(const Vec4V in) +{ + const float32x4_t ones = vdupq_n_f32(1.0f); + const float32x4_t rdToZero = vcvtq_f32_s32(vcvtq_s32_f32(in)); + const float32x4_t rdToZeroMinusOne = vsubq_f32(rdToZero, ones); + const uint32x4_t lt = vcltq_f32(in, rdToZero); + return vbslq_f32(lt, rdToZeroMinusOne, rdToZero); +} + +PX_FORCE_INLINE VecU32V V4ConvertToU32VSaturate(const Vec4V in, PxU32 power) +{ + PX_ASSERT(power == 0 && "Non-zero power not supported in convertToU32VSaturate"); + PX_UNUSED(power); // prevent warning in release builds + + return vcvtq_u32_f32(in); +} + +PX_FORCE_INLINE void QuatGetMat33V(const QuatVArg q, Vec3V& column0, Vec3V& column1, Vec3V& column2) +{ + const FloatV one = FOne(); + const FloatV x = V4GetX(q); + const FloatV y = V4GetY(q); + const FloatV z = V4GetZ(q); + const FloatV w = V4GetW(q); + + const FloatV x2 = FAdd(x, x); + const FloatV y2 = FAdd(y, y); + const FloatV z2 = FAdd(z, z); + + const FloatV xx = FMul(x2, x); + const FloatV yy = FMul(y2, y); + const FloatV zz = FMul(z2, z); + + const FloatV xy = FMul(x2, y); + const FloatV xz = FMul(x2, z); + const FloatV xw = FMul(x2, w); + + const FloatV yz = FMul(y2, z); + const FloatV yw = FMul(y2, w); + const FloatV zw = FMul(z2, w); + + const FloatV v = FSub(one, xx); + + column0 = V3Merge(FSub(FSub(one, yy), zz), FAdd(xy, zw), FSub(xz, yw)); + column1 = V3Merge(FSub(xy, zw), FSub(v, zz), FAdd(yz, xw)); + column2 = V3Merge(FAdd(xz, yw), FSub(yz, xw), FSub(v, yy)); +} + +} // namespace aos +} // namespace physx + +#endif // PXFOUNDATION_PXUNIXNEONINLINEAOS_H diff --git a/Source/ThirdParty/PhysX/foundation/unix/sse2/PxUnixSse2AoS.h b/Source/ThirdParty/PhysX/foundation/unix/sse2/PxUnixSse2AoS.h new file mode 100644 index 000000000..d7761a150 --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/unix/sse2/PxUnixSse2AoS.h @@ -0,0 +1,187 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PXFOUNDATION_PXUNIXSSE2AOS_H +#define PXFOUNDATION_PXUNIXSSE2AOS_H + +// no includes here! this file should be included from PxcVecMath.h only!!! + +#if !COMPILE_VECTOR_INTRINSICS +#error Vector intrinsics should not be included when using scalar implementation. +#endif + +namespace physx +{ +namespace aos +{ + +#if PX_EMSCRIPTEN +typedef int8_t __int8_t; +typedef int16_t __int16_t; +typedef int32_t __int32_t; +typedef int64_t __int64_t; +typedef uint16_t __uint16_t; +typedef uint32_t __uint32_t; +typedef uint64_t __uint64_t; +#endif + +typedef union UnionM128 +{ + UnionM128() + { + } + UnionM128(__m128 in) + { + m128 = in; + } + + UnionM128(__m128i in) + { + m128i = in; + } + + operator __m128() + { + return m128; + } + + operator const __m128() const + { + return m128; + } + + float m128_f32[4]; + __int8_t m128_i8[16]; + __int16_t m128_i16[8]; + __int32_t m128_i32[4]; + __int64_t m128_i64[2]; + __uint16_t m128_u16[8]; + __uint32_t m128_u32[4]; + __uint64_t m128_u64[2]; + __m128 m128; + __m128i m128i; +} UnionM128; + +typedef __m128 FloatV; +typedef __m128 Vec3V; +typedef __m128 Vec4V; +typedef __m128 BoolV; +typedef __m128 QuatV; +typedef __m128i VecI32V; +typedef UnionM128 VecU32V; +typedef UnionM128 VecU16V; +typedef UnionM128 VecI16V; +typedef UnionM128 VecU8V; + +#define FloatVArg FloatV & +#define Vec3VArg Vec3V & +#define Vec4VArg Vec4V & +#define BoolVArg BoolV & +#define VecU32VArg VecU32V & +#define VecI32VArg VecI32V & +#define VecU16VArg VecU16V & +#define VecI16VArg VecI16V & +#define VecU8VArg VecU8V & +#define QuatVArg QuatV & + +// Optimization for situations in which you cross product multiple vectors with the same vector. +// Avoids 2X shuffles per product +struct VecCrossV +{ + Vec3V mL1; + Vec3V mR1; +}; + +struct VecShiftV +{ + VecI32V shift; +}; +#define VecShiftVArg VecShiftV & + +PX_ALIGN_PREFIX(16) +struct Mat33V +{ + Mat33V() + { + } + Mat33V(const Vec3V& c0, const Vec3V& c1, const Vec3V& c2) : col0(c0), col1(c1), col2(c2) + { + } + Vec3V PX_ALIGN(16, col0); + Vec3V PX_ALIGN(16, col1); + Vec3V PX_ALIGN(16, col2); +} PX_ALIGN_SUFFIX(16); + +PX_ALIGN_PREFIX(16) +struct Mat34V +{ + Mat34V() + { + } + Mat34V(const Vec3V& c0, const Vec3V& c1, const Vec3V& c2, const Vec3V& c3) : col0(c0), col1(c1), col2(c2), col3(c3) + { + } + Vec3V PX_ALIGN(16, col0); + Vec3V PX_ALIGN(16, col1); + Vec3V PX_ALIGN(16, col2); + Vec3V PX_ALIGN(16, col3); +} PX_ALIGN_SUFFIX(16); + +PX_ALIGN_PREFIX(16) +struct Mat43V +{ + Mat43V() + { + } + Mat43V(const Vec4V& c0, const Vec4V& c1, const Vec4V& c2) : col0(c0), col1(c1), col2(c2) + { + } + Vec4V PX_ALIGN(16, col0); + Vec4V PX_ALIGN(16, col1); + Vec4V PX_ALIGN(16, col2); +} PX_ALIGN_SUFFIX(16); + +PX_ALIGN_PREFIX(16) +struct Mat44V +{ + Mat44V() + { + } + Mat44V(const Vec4V& c0, const Vec4V& c1, const Vec4V& c2, const Vec4V& c3) : col0(c0), col1(c1), col2(c2), col3(c3) + { + } + Vec4V PX_ALIGN(16, col0); + Vec4V PX_ALIGN(16, col1); + Vec4V PX_ALIGN(16, col2); + Vec4V PX_ALIGN(16, col3); +} PX_ALIGN_SUFFIX(16); + +} // namespace aos +} // namespace physx + +#endif // PXFOUNDATION_PXUNIXSSE2AOS_H diff --git a/Source/ThirdParty/PhysX/foundation/unix/sse2/PxUnixSse2InlineAoS.h b/Source/ThirdParty/PhysX/foundation/unix/sse2/PxUnixSse2InlineAoS.h new file mode 100644 index 000000000..ac776942a --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/unix/sse2/PxUnixSse2InlineAoS.h @@ -0,0 +1,3274 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PXFOUNDATION_PXUNIXSSE2INLINEAOS_H +#define PXFOUNDATION_PXUNIXSSE2INLINEAOS_H + +#if !COMPILE_VECTOR_INTRINSICS +#error Vector intrinsics should not be included when using scalar implementation. +#endif + +#ifdef __SSE4_2__ +#include "smmintrin.h" +#endif + +#include "../../PxVecMathSSE.h" + +namespace physx +{ +namespace aos +{ + +#define PX_FPCLASS_SNAN 0x0001 /* signaling NaN */ +#define PX_FPCLASS_QNAN 0x0002 /* quiet NaN */ +#define PX_FPCLASS_NINF 0x0004 /* negative infinity */ +#define PX_FPCLASS_PINF 0x0200 /* positive infinity */ + +PX_FORCE_INLINE __m128 m128_I2F(__m128i n) +{ + return _mm_castsi128_ps(n); +} +PX_FORCE_INLINE __m128i m128_F2I(__m128 n) +{ + return _mm_castps_si128(n); +} + +////////////////////////////////////////////////////////////////////// +//Test that Vec3V and FloatV are legal +////////////////////////////////////////////////////////////////////// + +#define FLOAT_COMPONENTS_EQUAL_THRESHOLD 0.01f +PX_FORCE_INLINE static bool isValidFloatV(const FloatV a) +{ + const PxF32 x = V4ReadX(a); + const PxF32 y = V4ReadY(a); + const PxF32 z = V4ReadZ(a); + const PxF32 w = V4ReadW(a); + + return (x == y && x == z && x == w); + + /*if ( + (PxAbs(x - y) < FLOAT_COMPONENTS_EQUAL_THRESHOLD) && + (PxAbs(x - z) < FLOAT_COMPONENTS_EQUAL_THRESHOLD) && + (PxAbs(x - w) < FLOAT_COMPONENTS_EQUAL_THRESHOLD) + ) + { + return true; + } + + if ( + (PxAbs((x - y) / x) < FLOAT_COMPONENTS_EQUAL_THRESHOLD) && + (PxAbs((x - z) / x) < FLOAT_COMPONENTS_EQUAL_THRESHOLD) && + (PxAbs((x - w) / x) < FLOAT_COMPONENTS_EQUAL_THRESHOLD) + ) + { + return true; + } + + return false;*/ +} + +PX_FORCE_INLINE bool isValidVec3V(const Vec3V a) +{ + PX_ALIGN(16, PxF32 f[4]); + V4StoreA(a, f); + return (f[3] == 0.0f); +} + +PX_FORCE_INLINE bool isFiniteLength(const Vec3V a) +{ + return !FAllEq(V4LengthSq(a), FZero()); +} + +PX_FORCE_INLINE bool isAligned16(void* a) +{ + return(0 == (size_t(a) & 0x0f)); +} + +//ASSERT_FINITELENGTH is deactivated because there is a lot of code that calls a simd normalisation function with zero length but then ignores the result. + +#if PX_DEBUG +#define ASSERT_ISVALIDVEC3V(a) PX_ASSERT(isValidVec3V(a)) +#define ASSERT_ISVALIDFLOATV(a) PX_ASSERT(isValidFloatV(a)) +#define ASSERT_ISALIGNED16(a) PX_ASSERT(isAligned16(reinterpret_cast(a))) +#define ASSERT_ISFINITELENGTH(a) //PX_ASSERT(isFiniteLength(a)) +#else +#define ASSERT_ISVALIDVEC3V(a) +#define ASSERT_ISVALIDFLOATV(a) +#define ASSERT_ISALIGNED16(a) +#define ASSERT_ISFINITELENGTH(a) +#endif + + +namespace internalUnitSSE2Simd +{ +PX_FORCE_INLINE PxU32 BAllTrue4_R(const BoolV a) +{ + const PxI32 moveMask = _mm_movemask_ps(a); + return PxU32(moveMask == 0xf); +} + +PX_FORCE_INLINE PxU32 BAllTrue3_R(const BoolV a) +{ + const PxI32 moveMask = _mm_movemask_ps(a); + return PxU32((moveMask & 0x7) == 0x7); +} + +PX_FORCE_INLINE PxU32 BAnyTrue4_R(const BoolV a) +{ + const PxI32 moveMask = _mm_movemask_ps(a); + return PxU32(moveMask != 0x0); +} + +PX_FORCE_INLINE PxU32 BAnyTrue3_R(const BoolV a) +{ + const PxI32 moveMask = _mm_movemask_ps(a); + return PxU32((moveMask & 0x7) != 0x0); +} + +PX_FORCE_INLINE PxU32 FiniteTestEq(const Vec4V a, const Vec4V b) +{ + // This is a bit of a bodge. + //_mm_comieq_ss returns 1 if either value is nan so we need to re-cast a and b with true encoded as a non-nan + // number. + // There must be a better way of doing this in sse. + const BoolV one = FOne(); + const BoolV zero = FZero(); + const BoolV a1 = V4Sel(a, one, zero); + const BoolV b1 = V4Sel(b, one, zero); + return ( + _mm_comieq_ss(a1, b1) && + _mm_comieq_ss(_mm_shuffle_ps(a1, a1, _MM_SHUFFLE(1, 1, 1, 1)), _mm_shuffle_ps(b1, b1, _MM_SHUFFLE(1, 1, 1, 1))) && + _mm_comieq_ss(_mm_shuffle_ps(a1, a1, _MM_SHUFFLE(2, 2, 2, 2)), _mm_shuffle_ps(b1, b1, _MM_SHUFFLE(2, 2, 2, 2))) && + _mm_comieq_ss(_mm_shuffle_ps(a1, a1, _MM_SHUFFLE(3, 3, 3, 3)), _mm_shuffle_ps(b1, b1, _MM_SHUFFLE(3, 3, 3, 3)))); +} + +#if !PX_EMSCRIPTEN +#if PX_CLANG +#if PX_LINUX +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wglobal-constructors" +#endif +#endif +const PX_ALIGN(16, PxF32 gMaskXYZ[4]) = { physx::PxUnionCast(0xffffffff), physx::PxUnionCast(0xffffffff), + physx::PxUnionCast(0xffffffff), 0 }; +#if PX_CLANG +#if PX_LINUX +#pragma clang diagnostic pop +#endif +#endif +#else +// emscripten doesn't like the PxUnionCast data structure +// the following is what windows and xbox does -- using these for emscripten +const PX_ALIGN(16, PxU32 gMaskXYZ[4]) = { 0xffffffff, 0xffffffff, 0xffffffff, 0 }; +#endif +} + +namespace vecMathTests +{ +// PT: this function returns an invalid Vec3V (W!=0.0f) just for unit-testing 'isValidVec3V' +PX_FORCE_INLINE Vec3V getInvalidVec3V() +{ + const float f = 1.0f; + return _mm_load1_ps(&f); +} + +PX_FORCE_INLINE bool allElementsEqualFloatV(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return _mm_comieq_ss(a, b) != 0; +} + +PX_FORCE_INLINE bool allElementsEqualVec3V(const Vec3V a, const Vec3V b) +{ + return V3AllEq(a, b) != 0; +} + +PX_FORCE_INLINE bool allElementsEqualVec4V(const Vec4V a, const Vec4V b) +{ + return V4AllEq(a, b) != 0; +} + +PX_FORCE_INLINE bool allElementsEqualBoolV(const BoolV a, const BoolV b) +{ + return internalUnitSSE2Simd::BAllTrue4_R(VecI32V_IsEq(m128_F2I(a), m128_F2I(b))) != 0; +} + +PX_FORCE_INLINE bool allElementsEqualVecU32V(const VecU32V a, const VecU32V b) +{ + return internalUnitSSE2Simd::BAllTrue4_R(V4IsEqU32(a, b)) != 0; +} + +PX_FORCE_INLINE bool allElementsEqualVecI32V(const VecI32V a, const VecI32V b) +{ + BoolV c = m128_I2F(_mm_cmpeq_epi32(a, b)); + return internalUnitSSE2Simd::BAllTrue4_R(c) != 0; +} + +#define VECMATH_AOS_EPSILON (1e-3f) + +PX_FORCE_INLINE bool allElementsNearEqualFloatV(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + const FloatV c = FSub(a, b); + const FloatV minError = FLoad(-VECMATH_AOS_EPSILON); + const FloatV maxError = FLoad(VECMATH_AOS_EPSILON); + return _mm_comigt_ss(c, minError) && _mm_comilt_ss(c, maxError); +} + +PX_FORCE_INLINE bool allElementsNearEqualVec3V(const Vec3V a, const Vec3V b) +{ + const Vec3V c = V3Sub(a, b); + const Vec3V minError = V3Load(-VECMATH_AOS_EPSILON); + const Vec3V maxError = V3Load(VECMATH_AOS_EPSILON); + return (_mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(0, 0, 0, 0)), minError) && + _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(0, 0, 0, 0)), maxError) && + _mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(1, 1, 1, 1)), minError) && + _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(1, 1, 1, 1)), maxError) && + _mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(2, 2, 2, 2)), minError) && + _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(2, 2, 2, 2)), maxError)); +} + +PX_FORCE_INLINE bool allElementsNearEqualVec4V(const Vec4V a, const Vec4V b) +{ + const Vec4V c = V4Sub(a, b); + const Vec4V minError = V4Load(-VECMATH_AOS_EPSILON); + const Vec4V maxError = V4Load(VECMATH_AOS_EPSILON); + return (_mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(0, 0, 0, 0)), minError) && + _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(0, 0, 0, 0)), maxError) && + _mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(1, 1, 1, 1)), minError) && + _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(1, 1, 1, 1)), maxError) && + _mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(2, 2, 2, 2)), minError) && + _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(2, 2, 2, 2)), maxError) && + _mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(3, 3, 3, 3)), minError) && + _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(3, 3, 3, 3)), maxError)); +} +} + +///////////////////////////////////////////////////////////////////// +////FUNCTIONS USED ONLY FOR ASSERTS IN VECTORISED IMPLEMENTATIONS +///////////////////////////////////////////////////////////////////// + +PX_FORCE_INLINE bool isFiniteFloatV(const FloatV a) +{ + PxF32 badNumber = + physx::PxUnionCast(PX_FPCLASS_SNAN | PX_FPCLASS_QNAN | PX_FPCLASS_NINF | PX_FPCLASS_PINF); + const FloatV vBadNum = FLoad(badNumber); + const BoolV vMask = BAnd(vBadNum, a); + return internalUnitSSE2Simd::FiniteTestEq(vMask, BFFFF()) == 1; +} + +PX_FORCE_INLINE bool isFiniteVec3V(const Vec3V a) +{ + PxF32 badNumber = + physx::PxUnionCast(PX_FPCLASS_SNAN | PX_FPCLASS_QNAN | PX_FPCLASS_NINF | PX_FPCLASS_PINF); + const Vec3V vBadNum = V3Load(badNumber); + const BoolV vMask = BAnd(BAnd(vBadNum, a), BTTTF()); + return internalUnitSSE2Simd::FiniteTestEq(vMask, BFFFF()) == 1; +} + +PX_FORCE_INLINE bool isFiniteVec4V(const Vec4V a) +{ + /*Vec4V a; + PX_ALIGN(16, PxF32 f[4]); + F32Array_Aligned_From_Vec4V(a, f); + return PxIsFinite(f[0]) + && PxIsFinite(f[1]) + && PxIsFinite(f[2]) + && PxIsFinite(f[3]);*/ + + PxF32 badNumber = + physx::PxUnionCast(PX_FPCLASS_SNAN | PX_FPCLASS_QNAN | PX_FPCLASS_NINF | PX_FPCLASS_PINF); + const Vec4V vBadNum = V4Load(badNumber); + const BoolV vMask = BAnd(vBadNum, a); + + return internalUnitSSE2Simd::FiniteTestEq(vMask, BFFFF()) == 1; +} + +PX_FORCE_INLINE bool hasZeroElementinFloatV(const FloatV a) +{ + ASSERT_ISVALIDFLOATV(a); + return _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)), FZero()) ? true : false; +} + +PX_FORCE_INLINE bool hasZeroElementInVec3V(const Vec3V a) +{ + return (_mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)), FZero()) || + _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)), FZero()) || + _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)), FZero())); +} + +PX_FORCE_INLINE bool hasZeroElementInVec4V(const Vec4V a) +{ + return (_mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)), FZero()) || + _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)), FZero()) || + _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)), FZero()) || + _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 3, 3, 3)), FZero())); +} + +///////////////////////////////////////////////////////////////////// +////VECTORISED FUNCTION IMPLEMENTATIONS +///////////////////////////////////////////////////////////////////// + +PX_FORCE_INLINE FloatV FLoad(const PxF32 f) +{ + return _mm_load1_ps(&f); +} + +PX_FORCE_INLINE Vec3V V3Load(const PxF32 f) +{ + return _mm_set_ps(0.0f, f, f, f); +} + +PX_FORCE_INLINE Vec4V V4Load(const PxF32 f) +{ + return _mm_load1_ps(&f); +} + +PX_FORCE_INLINE BoolV BLoad(const bool f) +{ + const PxU32 i = PxU32(-PxI32(f)); + return _mm_load1_ps(reinterpret_cast(&i)); +} + +PX_FORCE_INLINE Vec3V V3LoadA(const PxVec3& f) +{ + ASSERT_ISALIGNED16(const_cast(&f)); +#if !PX_EMSCRIPTEN + return _mm_and_ps(reinterpret_cast(f), V4LoadA(internalUnitSSE2Simd::gMaskXYZ)); +#else + return _mm_and_ps((Vec3V&)f, (VecI32V&)internalUnitSSE2Simd::gMaskXYZ); +#endif +} + +PX_FORCE_INLINE Vec3V V3LoadU(const PxVec3& f) +{ + return _mm_set_ps(0.0f, f.z, f.y, f.x); +} + +PX_FORCE_INLINE Vec3V V3LoadUnsafeA(const PxVec3& f) +{ + ASSERT_ISALIGNED16(const_cast(&f)); + return _mm_set_ps(0.0f, f.z, f.y, f.x); +} + +PX_FORCE_INLINE Vec3V V3LoadA(const PxF32* const f) +{ + ASSERT_ISALIGNED16(const_cast(f)); +#if !PX_EMSCRIPTEN + return _mm_and_ps(V4LoadA(f), V4LoadA(internalUnitSSE2Simd::gMaskXYZ)); +#else + return _mm_and_ps((Vec3V&)*f, (VecI32V&)internalUnitSSE2Simd::gMaskXYZ); +#endif +} + +PX_FORCE_INLINE Vec3V V3LoadU(const PxF32* const i) +{ + return _mm_set_ps(0.0f, i[2], i[1], i[0]); +} + +PX_FORCE_INLINE Vec3V Vec3V_From_Vec4V(Vec4V v) +{ + return V4ClearW(v); +} + +PX_FORCE_INLINE Vec3V Vec3V_From_Vec4V_WUndefined(const Vec4V v) +{ + return v; +} + +PX_FORCE_INLINE Vec4V Vec4V_From_Vec3V(Vec3V f) +{ + ASSERT_ISVALIDVEC3V(f); + return f; // ok if it is implemented as the same type. +} + +PX_FORCE_INLINE Vec4V Vec4V_From_PxVec3_WUndefined(const PxVec3& f) +{ + return _mm_set_ps(0.0f, f.z, f.y, f.x); +} + +PX_FORCE_INLINE Vec4V Vec4V_From_FloatV(FloatV f) +{ + return f; +} + +PX_FORCE_INLINE Vec3V Vec3V_From_FloatV(FloatV f) +{ + ASSERT_ISVALIDFLOATV(f); + return Vec3V_From_Vec4V(Vec4V_From_FloatV(f)); +} + +PX_FORCE_INLINE Vec3V Vec3V_From_FloatV_WUndefined(FloatV f) +{ + ASSERT_ISVALIDVEC3V(f); + return Vec3V_From_Vec4V_WUndefined(Vec4V_From_FloatV(f)); +} + +PX_FORCE_INLINE Mat33V Mat33V_From_PxMat33(const PxMat33& m) +{ + return Mat33V(V3LoadU(m.column0), V3LoadU(m.column1), V3LoadU(m.column2)); +} + +PX_FORCE_INLINE void PxMat33_From_Mat33V(const Mat33V& m, PxMat33& out) +{ + V3StoreU(m.col0, out.column0); + V3StoreU(m.col1, out.column1); + V3StoreU(m.col2, out.column2); +} + +PX_FORCE_INLINE Vec4V V4LoadA(const PxF32* const f) +{ + ASSERT_ISALIGNED16(const_cast(f)); + return _mm_load_ps(f); +} + +PX_FORCE_INLINE void V4StoreA(Vec4V a, PxF32* f) +{ + ASSERT_ISALIGNED16(f); + _mm_store_ps(f, a); +} + +PX_FORCE_INLINE void V4StoreU(const Vec4V a, PxF32* f) +{ + _mm_storeu_ps(f, a); +} + +PX_FORCE_INLINE void BStoreA(const BoolV a, PxU32* f) +{ + ASSERT_ISALIGNED16(f); + _mm_store_ps(reinterpret_cast(f), a); +} + +PX_FORCE_INLINE void U4StoreA(const VecU32V uv, PxU32* u) +{ + ASSERT_ISALIGNED16(u); + _mm_store_ps(reinterpret_cast(u), uv); +} + +PX_FORCE_INLINE VecI32V I4LoadXYZW(const PxI32& x, const PxI32& y, const PxI32& z, const PxI32& w) +{ + return _mm_set_epi32(w, z, y, x); +} + +PX_FORCE_INLINE void I4StoreA(const VecI32V iv, PxI32* i) +{ + ASSERT_ISALIGNED16(i); + _mm_store_ps(reinterpret_cast(i), m128_I2F(iv)); +} + +PX_FORCE_INLINE Vec4V V4LoadU(const PxF32* const f) +{ + return _mm_loadu_ps(f); +} + +PX_FORCE_INLINE BoolV BLoad(const bool* const f) +{ + const PX_ALIGN(16, PxI32) b[4] = { -PxI32(f[0]), -PxI32(f[1]), -PxI32(f[2]), -PxI32(f[3]) }; + return _mm_load_ps(reinterpret_cast(&b)); +} + +PX_FORCE_INLINE void FStore(const FloatV a, PxF32* PX_RESTRICT f) +{ + ASSERT_ISVALIDFLOATV(a); + _mm_store_ss(f, a); +} + +PX_FORCE_INLINE void V3StoreA(const Vec3V a, PxVec3& f) +{ + ASSERT_ISALIGNED16(&f); + PX_ALIGN(16, PxF32) f2[4]; + _mm_store_ps(f2, a); + f = PxVec3(f2[0], f2[1], f2[2]); +} + +PX_FORCE_INLINE void V3StoreU(const Vec3V a, PxVec3& f) +{ + PX_ALIGN(16, PxF32) f2[4]; + _mm_store_ps(f2, a); + f = PxVec3(f2[0], f2[1], f2[2]); +} + +PX_FORCE_INLINE void Store_From_BoolV(const BoolV b, PxU32* b2) +{ + _mm_store_ss(reinterpret_cast(b2), b); +} + +PX_FORCE_INLINE VecU32V U4Load(const PxU32 i) +{ + return _mm_load1_ps(reinterpret_cast(&i)); +} + +PX_FORCE_INLINE VecU32V U4LoadU(const PxU32* i) +{ + return _mm_loadu_ps(reinterpret_cast(i)); +} + +PX_FORCE_INLINE VecU32V U4LoadA(const PxU32* i) +{ + ASSERT_ISALIGNED16(const_cast(i)); + return _mm_load_ps(reinterpret_cast(i)); +} + +////////////////////////////////// +// FLOATV +////////////////////////////////// + +PX_FORCE_INLINE FloatV FZero() +{ + return FLoad(0.0f); +} + +PX_FORCE_INLINE FloatV FOne() +{ + return FLoad(1.0f); +} + +PX_FORCE_INLINE FloatV FHalf() +{ + return FLoad(0.5f); +} + +PX_FORCE_INLINE FloatV FEps() +{ + return FLoad(PX_EPS_REAL); +} + +PX_FORCE_INLINE FloatV FEps6() +{ + return FLoad(1e-6f); +} + +PX_FORCE_INLINE FloatV FMax() +{ + return FLoad(PX_MAX_REAL); +} + +PX_FORCE_INLINE FloatV FNegMax() +{ + return FLoad(-PX_MAX_REAL); +} + +PX_FORCE_INLINE FloatV IZero() +{ + const PxU32 zero = 0; + return _mm_load1_ps(reinterpret_cast(&zero)); +} + +PX_FORCE_INLINE FloatV IOne() +{ + const PxU32 one = 1; + return _mm_load1_ps(reinterpret_cast(&one)); +} + +PX_FORCE_INLINE FloatV ITwo() +{ + const PxU32 two = 2; + return _mm_load1_ps(reinterpret_cast(&two)); +} + +PX_FORCE_INLINE FloatV IThree() +{ + const PxU32 three = 3; + return _mm_load1_ps(reinterpret_cast(&three)); +} + +PX_FORCE_INLINE FloatV IFour() +{ + PxU32 four = 4; + return _mm_load1_ps(reinterpret_cast(&four)); +} + +PX_FORCE_INLINE FloatV FNeg(const FloatV f) +{ + ASSERT_ISVALIDFLOATV(f); + return _mm_sub_ps(_mm_setzero_ps(), f); +} + +PX_FORCE_INLINE FloatV FAdd(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); +/* + if(!isValidFloatV(a)) + { +assert(false); + } + if(!isValidFloatV(b)) + { +assert(false); + } +*/ + return _mm_add_ps(a, b); +} + +PX_FORCE_INLINE FloatV FSub(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return _mm_sub_ps(a, b); +} + +PX_FORCE_INLINE FloatV FMul(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return _mm_mul_ps(a, b); +} + +PX_FORCE_INLINE FloatV FDiv(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return _mm_div_ps(a, b); +} + +PX_FORCE_INLINE FloatV FDivFast(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return _mm_mul_ps(a, _mm_rcp_ps(b)); +} + +PX_FORCE_INLINE FloatV FRecip(const FloatV a) +{ + ASSERT_ISVALIDFLOATV(a); + return _mm_div_ps(FOne(), a); +} + +PX_FORCE_INLINE FloatV FRecipFast(const FloatV a) +{ + ASSERT_ISVALIDFLOATV(a); + return _mm_rcp_ps(a); +} + +PX_FORCE_INLINE FloatV FRsqrt(const FloatV a) +{ + ASSERT_ISVALIDFLOATV(a); + return _mm_div_ps(FOne(), _mm_sqrt_ps(a)); +} + +PX_FORCE_INLINE FloatV FSqrt(const FloatV a) +{ + ASSERT_ISVALIDFLOATV(a); + return _mm_sqrt_ps(a); +} + +PX_FORCE_INLINE FloatV FRsqrtFast(const FloatV a) +{ + ASSERT_ISVALIDFLOATV(a); + return _mm_rsqrt_ps(a); +} + +PX_FORCE_INLINE FloatV FScaleAdd(const FloatV a, const FloatV b, const FloatV c) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + ASSERT_ISVALIDFLOATV(c); + return FAdd(FMul(a, b), c); +} + +PX_FORCE_INLINE FloatV FNegScaleSub(const FloatV a, const FloatV b, const FloatV c) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + ASSERT_ISVALIDFLOATV(c); + return FSub(c, FMul(a, b)); +} + +PX_FORCE_INLINE FloatV FAbs(const FloatV a) +{ + ASSERT_ISVALIDFLOATV(a); + PX_ALIGN(16, const PxU32) absMask[4] = { 0x7fFFffFF, 0x7fFFffFF, 0x7fFFffFF, 0x7fFFffFF }; + return _mm_and_ps(a, _mm_load_ps(reinterpret_cast(absMask))); +} + +PX_FORCE_INLINE FloatV FSel(const BoolV c, const FloatV a, const FloatV b) +{ + PX_ASSERT(vecMathTests::allElementsEqualBoolV(c,BTTTT()) || + vecMathTests::allElementsEqualBoolV(c,BFFFF())); + ASSERT_ISVALIDFLOATV(_mm_or_ps(_mm_andnot_ps(c, b), _mm_and_ps(c, a))); + return _mm_or_ps(_mm_andnot_ps(c, b), _mm_and_ps(c, a)); +} + +PX_FORCE_INLINE BoolV FIsGrtr(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return _mm_cmpgt_ps(a, b); +} + +PX_FORCE_INLINE BoolV FIsGrtrOrEq(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return _mm_cmpge_ps(a, b); +} + +PX_FORCE_INLINE BoolV FIsEq(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return _mm_cmpeq_ps(a, b); +} + +PX_FORCE_INLINE FloatV FMax(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return _mm_max_ps(a, b); +} + +PX_FORCE_INLINE FloatV FMin(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return _mm_min_ps(a, b); +} + +PX_FORCE_INLINE FloatV FClamp(const FloatV a, const FloatV minV, const FloatV maxV) +{ + ASSERT_ISVALIDFLOATV(minV); + ASSERT_ISVALIDFLOATV(maxV); + return _mm_max_ps(_mm_min_ps(a, maxV), minV); +} + +PX_FORCE_INLINE PxU32 FAllGrtr(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return PxU32(_mm_comigt_ss(a, b)); +} + +PX_FORCE_INLINE PxU32 FAllGrtrOrEq(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return PxU32(_mm_comige_ss(a, b)); +} + +PX_FORCE_INLINE PxU32 FAllEq(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return PxU32(_mm_comieq_ss(a, b)); +} + +PX_FORCE_INLINE FloatV FRound(const FloatV a) +{ + ASSERT_ISVALIDFLOATV(a); +#ifdef __SSE4_2__ + return _mm_round_ps(a, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC); +#else + // return _mm_round_ps(a, 0x0); + const FloatV half = FLoad(0.5f); + const __m128 signBit = _mm_cvtepi32_ps(_mm_srli_epi32(_mm_cvtps_epi32(a), 31)); + const FloatV aRound = FSub(FAdd(a, half), signBit); + __m128i tmp = _mm_cvttps_epi32(aRound); + return _mm_cvtepi32_ps(tmp); +#endif +} + +PX_FORCE_INLINE FloatV FSin(const FloatV a) +{ + ASSERT_ISVALIDFLOATV(a); + + // Modulo the range of the given angles such that -XM_2PI <= Angles < XM_2PI + const FloatV recipTwoPi = V4LoadA(g_PXReciprocalTwoPi.f); + const FloatV twoPi = V4LoadA(g_PXTwoPi.f); + const FloatV tmp = FMul(a, recipTwoPi); + const FloatV b = FRound(tmp); + const FloatV V1 = FNegScaleSub(twoPi, b, a); + + // sin(V) ~= V - V^3 / 3! + V^5 / 5! - V^7 / 7! + V^9 / 9! - V^11 / 11! + V^13 / 13! - + // V^15 / 15! + V^17 / 17! - V^19 / 19! + V^21 / 21! - V^23 / 23! (for -PI <= V < PI) + const FloatV V2 = FMul(V1, V1); + const FloatV V3 = FMul(V2, V1); + const FloatV V5 = FMul(V3, V2); + const FloatV V7 = FMul(V5, V2); + const FloatV V9 = FMul(V7, V2); + const FloatV V11 = FMul(V9, V2); + const FloatV V13 = FMul(V11, V2); + const FloatV V15 = FMul(V13, V2); + const FloatV V17 = FMul(V15, V2); + const FloatV V19 = FMul(V17, V2); + const FloatV V21 = FMul(V19, V2); + const FloatV V23 = FMul(V21, V2); + + const Vec4V sinCoefficients0 = V4LoadA(g_PXSinCoefficients0.f); + const Vec4V sinCoefficients1 = V4LoadA(g_PXSinCoefficients1.f); + const Vec4V sinCoefficients2 = V4LoadA(g_PXSinCoefficients2.f); + + const FloatV S1 = V4GetY(sinCoefficients0); + const FloatV S2 = V4GetZ(sinCoefficients0); + const FloatV S3 = V4GetW(sinCoefficients0); + const FloatV S4 = V4GetX(sinCoefficients1); + const FloatV S5 = V4GetY(sinCoefficients1); + const FloatV S6 = V4GetZ(sinCoefficients1); + const FloatV S7 = V4GetW(sinCoefficients1); + const FloatV S8 = V4GetX(sinCoefficients2); + const FloatV S9 = V4GetY(sinCoefficients2); + const FloatV S10 = V4GetZ(sinCoefficients2); + const FloatV S11 = V4GetW(sinCoefficients2); + + FloatV Result; + Result = FScaleAdd(S1, V3, V1); + Result = FScaleAdd(S2, V5, Result); + Result = FScaleAdd(S3, V7, Result); + Result = FScaleAdd(S4, V9, Result); + Result = FScaleAdd(S5, V11, Result); + Result = FScaleAdd(S6, V13, Result); + Result = FScaleAdd(S7, V15, Result); + Result = FScaleAdd(S8, V17, Result); + Result = FScaleAdd(S9, V19, Result); + Result = FScaleAdd(S10, V21, Result); + Result = FScaleAdd(S11, V23, Result); + + return Result; +} + +PX_FORCE_INLINE FloatV FCos(const FloatV a) +{ + ASSERT_ISVALIDFLOATV(a); + + // Modulo the range of the given angles such that -XM_2PI <= Angles < XM_2PI + const FloatV recipTwoPi = V4LoadA(g_PXReciprocalTwoPi.f); + const FloatV twoPi = V4LoadA(g_PXTwoPi.f); + const FloatV tmp = FMul(a, recipTwoPi); + const FloatV b = FRound(tmp); + const FloatV V1 = FNegScaleSub(twoPi, b, a); + + // cos(V) ~= 1 - V^2 / 2! + V^4 / 4! - V^6 / 6! + V^8 / 8! - V^10 / 10! + V^12 / 12! - + // V^14 / 14! + V^16 / 16! - V^18 / 18! + V^20 / 20! - V^22 / 22! (for -PI <= V < PI) + const FloatV V2 = FMul(V1, V1); + const FloatV V4 = FMul(V2, V2); + const FloatV V6 = FMul(V4, V2); + const FloatV V8 = FMul(V4, V4); + const FloatV V10 = FMul(V6, V4); + const FloatV V12 = FMul(V6, V6); + const FloatV V14 = FMul(V8, V6); + const FloatV V16 = FMul(V8, V8); + const FloatV V18 = FMul(V10, V8); + const FloatV V20 = FMul(V10, V10); + const FloatV V22 = FMul(V12, V10); + + const Vec4V cosCoefficients0 = V4LoadA(g_PXCosCoefficients0.f); + const Vec4V cosCoefficients1 = V4LoadA(g_PXCosCoefficients1.f); + const Vec4V cosCoefficients2 = V4LoadA(g_PXCosCoefficients2.f); + + const FloatV C1 = V4GetY(cosCoefficients0); + const FloatV C2 = V4GetZ(cosCoefficients0); + const FloatV C3 = V4GetW(cosCoefficients0); + const FloatV C4 = V4GetX(cosCoefficients1); + const FloatV C5 = V4GetY(cosCoefficients1); + const FloatV C6 = V4GetZ(cosCoefficients1); + const FloatV C7 = V4GetW(cosCoefficients1); + const FloatV C8 = V4GetX(cosCoefficients2); + const FloatV C9 = V4GetY(cosCoefficients2); + const FloatV C10 = V4GetZ(cosCoefficients2); + const FloatV C11 = V4GetW(cosCoefficients2); + + FloatV Result; + Result = FScaleAdd(C1, V2, V4One()); + Result = FScaleAdd(C2, V4, Result); + Result = FScaleAdd(C3, V6, Result); + Result = FScaleAdd(C4, V8, Result); + Result = FScaleAdd(C5, V10, Result); + Result = FScaleAdd(C6, V12, Result); + Result = FScaleAdd(C7, V14, Result); + Result = FScaleAdd(C8, V16, Result); + Result = FScaleAdd(C9, V18, Result); + Result = FScaleAdd(C10, V20, Result); + Result = FScaleAdd(C11, V22, Result); + + return Result; +} + +PX_FORCE_INLINE PxU32 FOutOfBounds(const FloatV a, const FloatV min, const FloatV max) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(min); + ASSERT_ISVALIDFLOATV(max); + const BoolV c = BOr(FIsGrtr(a, max), FIsGrtr(min, a)); + return !BAllEqFFFF(c); +} + +PX_FORCE_INLINE PxU32 FInBounds(const FloatV a, const FloatV min, const FloatV max) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(min); + ASSERT_ISVALIDFLOATV(max) + const BoolV c = BAnd(FIsGrtrOrEq(a, min), FIsGrtrOrEq(max, a)); + return BAllEqTTTT(c); +} + +PX_FORCE_INLINE PxU32 FOutOfBounds(const FloatV a, const FloatV bounds) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(bounds); + return FOutOfBounds(a, FNeg(bounds), bounds); +} + +PX_FORCE_INLINE PxU32 FInBounds(const FloatV a, const FloatV bounds) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(bounds); + return FInBounds(a, FNeg(bounds), bounds); +} + +////////////////////////////////// +// VEC3V +////////////////////////////////// + +PX_FORCE_INLINE Vec3V V3Splat(const FloatV f) +{ + ASSERT_ISVALIDFLOATV(f); + const __m128 zero = FZero(); + const __m128 fff0 = _mm_move_ss(f, zero); + return _mm_shuffle_ps(fff0, fff0, _MM_SHUFFLE(0, 1, 2, 3)); +} + +PX_FORCE_INLINE Vec3V V3Merge(const FloatVArg x, const FloatVArg y, const FloatVArg z) +{ + ASSERT_ISVALIDFLOATV(x); + ASSERT_ISVALIDFLOATV(y); + ASSERT_ISVALIDFLOATV(z); + // static on zero causes compiler crash on x64 debug_opt + const __m128 zero = FZero(); + const __m128 xy = _mm_move_ss(x, y); + const __m128 z0 = _mm_move_ss(zero, z); + + return _mm_shuffle_ps(xy, z0, _MM_SHUFFLE(1, 0, 0, 1)); +} + +PX_FORCE_INLINE Vec3V V3UnitX() +{ + const PX_ALIGN(16, PxF32) x[4] = { 1.0f, 0.0f, 0.0f, 0.0f }; + const __m128 x128 = _mm_load_ps(x); + return x128; +} + +PX_FORCE_INLINE Vec3V V3UnitY() +{ + const PX_ALIGN(16, PxF32) y[4] = { 0.0f, 1.0f, 0.0f, 0.0f }; + const __m128 y128 = _mm_load_ps(y); + return y128; +} + +PX_FORCE_INLINE Vec3V V3UnitZ() +{ + const PX_ALIGN(16, PxF32) z[4] = { 0.0f, 0.0f, 1.0f, 0.0f }; + const __m128 z128 = _mm_load_ps(z); + return z128; +} + +PX_FORCE_INLINE FloatV V3GetX(const Vec3V f) +{ + ASSERT_ISVALIDVEC3V(f); + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(0, 0, 0, 0)); +} + +PX_FORCE_INLINE FloatV V3GetY(const Vec3V f) +{ + ASSERT_ISVALIDVEC3V(f) + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(1, 1, 1, 1)); +} + +PX_FORCE_INLINE FloatV V3GetZ(const Vec3V f) +{ + ASSERT_ISVALIDVEC3V(f); + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(2, 2, 2, 2)); +} + +PX_FORCE_INLINE Vec3V V3SetX(const Vec3V v, const FloatV f) +{ + ASSERT_ISVALIDVEC3V(v); + ASSERT_ISVALIDFLOATV(f); + return V4Sel(BFTTT(), v, f); +} + +PX_FORCE_INLINE Vec3V V3SetY(const Vec3V v, const FloatV f) +{ + ASSERT_ISVALIDVEC3V(v); + ASSERT_ISVALIDFLOATV(f); + return V4Sel(BTFTT(), v, f); +} + +PX_FORCE_INLINE Vec3V V3SetZ(const Vec3V v, const FloatV f) +{ + ASSERT_ISVALIDVEC3V(v); + ASSERT_ISVALIDFLOATV(f); + return V4Sel(BTTFT(), v, f); +} + +PX_FORCE_INLINE Vec3V V3ColX(const Vec3V a, const Vec3V b, const Vec3V c) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + ASSERT_ISVALIDVEC3V(c); + Vec3V r = _mm_shuffle_ps(a, c, _MM_SHUFFLE(3, 0, 3, 0)); + return V3SetY(r, V3GetX(b)); +} + +PX_FORCE_INLINE Vec3V V3ColY(const Vec3V a, const Vec3V b, const Vec3V c) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + ASSERT_ISVALIDVEC3V(c) + Vec3V r = _mm_shuffle_ps(a, c, _MM_SHUFFLE(3, 1, 3, 1)); + return V3SetY(r, V3GetY(b)); +} + +PX_FORCE_INLINE Vec3V V3ColZ(const Vec3V a, const Vec3V b, const Vec3V c) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + ASSERT_ISVALIDVEC3V(c); + Vec3V r = _mm_shuffle_ps(a, c, _MM_SHUFFLE(3, 2, 3, 2)); + return V3SetY(r, V3GetZ(b)); +} + +PX_FORCE_INLINE Vec3V V3Zero() +{ + return V3Load(0.0f); +} + +PX_FORCE_INLINE Vec3V V3Eps() +{ + return V3Load(PX_EPS_REAL); +} +PX_FORCE_INLINE Vec3V V3One() +{ + return V3Load(1.0f); +} + +PX_FORCE_INLINE Vec3V V3Neg(const Vec3V f) +{ + ASSERT_ISVALIDVEC3V(f); + return _mm_sub_ps(_mm_setzero_ps(), f); +} + +PX_FORCE_INLINE Vec3V V3Add(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return _mm_add_ps(a, b); +} + +PX_FORCE_INLINE Vec3V V3Sub(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return _mm_sub_ps(a, b); +} + +PX_FORCE_INLINE Vec3V V3Scale(const Vec3V a, const FloatV b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDFLOATV(b); + return _mm_mul_ps(a, b); +} + +PX_FORCE_INLINE Vec3V V3Mul(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return _mm_mul_ps(a, b); +} + +PX_FORCE_INLINE Vec3V V3ScaleInv(const Vec3V a, const FloatV b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDFLOATV(b); + return _mm_div_ps(a, b); +} + +PX_FORCE_INLINE Vec3V V3Div(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return V4ClearW(_mm_div_ps(a, b)); +} + +PX_FORCE_INLINE Vec3V V3ScaleInvFast(const Vec3V a, const FloatV b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDFLOATV(b); + return _mm_mul_ps(a, _mm_rcp_ps(b)); +} + +PX_FORCE_INLINE Vec3V V3DivFast(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return V4ClearW(_mm_mul_ps(a, _mm_rcp_ps(b))); +} + +PX_FORCE_INLINE Vec3V V3Recip(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + const __m128 zero = V3Zero(); + const __m128 tttf = BTTTF(); + const __m128 recipA = _mm_div_ps(V3One(), a); + return V4Sel(tttf, recipA, zero); +} + +PX_FORCE_INLINE Vec3V V3RecipFast(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + const __m128 zero = V3Zero(); + const __m128 tttf = BTTTF(); + const __m128 recipA = _mm_rcp_ps(a); + return V4Sel(tttf, recipA, zero); +} + +PX_FORCE_INLINE Vec3V V3Rsqrt(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + const __m128 zero = V3Zero(); + const __m128 tttf = BTTTF(); + const __m128 recipA = _mm_div_ps(V3One(), _mm_sqrt_ps(a)); + return V4Sel(tttf, recipA, zero); +} + +PX_FORCE_INLINE Vec3V V3RsqrtFast(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + const __m128 zero = V3Zero(); + const __m128 tttf = BTTTF(); + const __m128 recipA = _mm_rsqrt_ps(a); + return V4Sel(tttf, recipA, zero); +} + +PX_FORCE_INLINE Vec3V V3ScaleAdd(const Vec3V a, const FloatV b, const Vec3V c) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDFLOATV(b); + ASSERT_ISVALIDVEC3V(c); + return V3Add(V3Scale(a, b), c); +} + +PX_FORCE_INLINE Vec3V V3NegScaleSub(const Vec3V a, const FloatV b, const Vec3V c) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDFLOATV(b); + ASSERT_ISVALIDVEC3V(c); + return V3Sub(c, V3Scale(a, b)); +} + +PX_FORCE_INLINE Vec3V V3MulAdd(const Vec3V a, const Vec3V b, const Vec3V c) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + ASSERT_ISVALIDVEC3V(c); + return V3Add(V3Mul(a, b), c); +} + +PX_FORCE_INLINE Vec3V V3NegMulSub(const Vec3V a, const Vec3V b, const Vec3V c) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + ASSERT_ISVALIDVEC3V(c); + return V3Sub(c, V3Mul(a, b)); +} + +PX_FORCE_INLINE Vec3V V3Abs(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + return V3Max(a, V3Neg(a)); +} + +PX_FORCE_INLINE FloatV V3Dot(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); +#ifdef __SSE4_2__ + return _mm_dp_ps(a, b, 0x7f); +#else + const __m128 t0 = _mm_mul_ps(a, b); // aw*bw | az*bz | ay*by | ax*bx + const __m128 t1 = _mm_shuffle_ps(t0, t0, _MM_SHUFFLE(1,0,3,2)); // ay*by | ax*bx | aw*bw | az*bz + const __m128 t2 = _mm_add_ps(t0, t1); // ay*by + aw*bw | ax*bx + az*bz | aw*bw + ay*by | az*bz + ax*bx + const __m128 t3 = _mm_shuffle_ps(t2, t2, _MM_SHUFFLE(2,3,0,1)); // ax*bx + az*bz | ay*by + aw*bw | az*bz + ax*bx | aw*bw + ay*by + return _mm_add_ps(t3, t2); // ax*bx + az*bz + ay*by + aw*bw + // ay*by + aw*bw + ax*bx + az*bz + // az*bz + ax*bx + aw*bw + ay*by + // aw*bw + ay*by + az*bz + ax*bx +#endif +} + +PX_FORCE_INLINE Vec3V V3Cross(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + const __m128 r1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 1, 0, 2)); // z,x,y,w + const __m128 r2 = _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 0, 2, 1)); // y,z,x,w + const __m128 l1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 2, 1)); // y,z,x,w + const __m128 l2 = _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 1, 0, 2)); // z,x,y,w + return _mm_sub_ps(_mm_mul_ps(l1, l2), _mm_mul_ps(r1, r2)); +} + +PX_FORCE_INLINE VecCrossV V3PrepareCross(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + VecCrossV v; + v.mR1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 1, 0, 2)); // z,x,y,w + v.mL1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 2, 1)); // y,z,x,w + return v; +} + +PX_FORCE_INLINE Vec3V V3Cross(const VecCrossV& a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(b); + const __m128 r2 = _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 0, 2, 1)); // y,z,x,w + const __m128 l2 = _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 1, 0, 2)); // z,x,y,w + return _mm_sub_ps(_mm_mul_ps(a.mL1, l2), _mm_mul_ps(a.mR1, r2)); +} + +PX_FORCE_INLINE Vec3V V3Cross(const Vec3V a, const VecCrossV& b) +{ + ASSERT_ISVALIDVEC3V(a); + const __m128 r2 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 2, 1)); // y,z,x,w + const __m128 l2 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 1, 0, 2)); // z,x,y,w + return _mm_sub_ps(_mm_mul_ps(b.mR1, r2), _mm_mul_ps(b.mL1, l2)); +} + +PX_FORCE_INLINE Vec3V V3Cross(const VecCrossV& a, const VecCrossV& b) +{ + return _mm_sub_ps(_mm_mul_ps(a.mL1, b.mR1), _mm_mul_ps(a.mR1, b.mL1)); +} + +PX_FORCE_INLINE FloatV V3Length(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + return _mm_sqrt_ps(V3Dot(a, a)); +} + +PX_FORCE_INLINE FloatV V3LengthSq(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + return V3Dot(a, a); +} + +PX_FORCE_INLINE Vec3V V3Normalize(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISFINITELENGTH(a); + return V3ScaleInv(a, _mm_sqrt_ps(V3Dot(a, a))); +} + +PX_FORCE_INLINE Vec3V V3NormalizeFast(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISFINITELENGTH(a); + return V3Scale(a, _mm_rsqrt_ps(V3Dot(a, a))); +} + +PX_FORCE_INLINE Vec3V V3NormalizeSafe(const Vec3V a, const Vec3V unsafeReturnValue) +{ + ASSERT_ISVALIDVEC3V(a); + const __m128 eps = V4Eps(); + const __m128 length = V3Length(a); + const __m128 isGreaterThanZero = FIsGrtr(length, eps); + return V3Sel(isGreaterThanZero, V3ScaleInv(a, length), unsafeReturnValue); +} + +PX_FORCE_INLINE Vec3V V3Sel(const BoolV c, const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(_mm_or_ps(_mm_andnot_ps(c, b), _mm_and_ps(c, a))); + return _mm_or_ps(_mm_andnot_ps(c, b), _mm_and_ps(c, a)); +} + +PX_FORCE_INLINE BoolV V3IsGrtr(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return _mm_cmpgt_ps(a, b); +} + +PX_FORCE_INLINE BoolV V3IsGrtrOrEq(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return _mm_cmpge_ps(a, b); +} + +PX_FORCE_INLINE BoolV V3IsEq(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return _mm_cmpeq_ps(a, b); +} + +PX_FORCE_INLINE Vec3V V3Max(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return _mm_max_ps(a, b); +} + +PX_FORCE_INLINE Vec3V V3Min(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return _mm_min_ps(a, b); +} + +PX_FORCE_INLINE FloatV V3ExtractMax(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + const __m128 shuf1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)); + const __m128 shuf2 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)); + const __m128 shuf3 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)); + + return _mm_max_ps(_mm_max_ps(shuf1, shuf2), shuf3); +} + +PX_FORCE_INLINE FloatV V3ExtractMin(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + + const __m128 shuf1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)); + const __m128 shuf2 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)); + const __m128 shuf3 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)); + + return _mm_min_ps(_mm_min_ps(shuf1, shuf2), shuf3); +} + +// return (a >= 0.0f) ? 1.0f : -1.0f; +PX_FORCE_INLINE Vec3V V3Sign(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + const __m128 zero = V3Zero(); + const __m128 one = V3One(); + const __m128 none = V3Neg(one); + return V3Sel(V3IsGrtrOrEq(a, zero), one, none); +} + +PX_FORCE_INLINE Vec3V V3Clamp(const Vec3V a, const Vec3V minV, const Vec3V maxV) +{ + ASSERT_ISVALIDVEC3V(maxV); + ASSERT_ISVALIDVEC3V(minV); + return V3Max(V3Min(a, maxV), minV); +} + +PX_FORCE_INLINE PxU32 V3AllGrtr(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return internalUnitSSE2Simd::BAllTrue3_R(V4IsGrtr(a, b)); +} + +PX_FORCE_INLINE PxU32 V3AllGrtrOrEq(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return internalUnitSSE2Simd::BAllTrue3_R(V4IsGrtrOrEq(a, b)); +} + +PX_FORCE_INLINE PxU32 V3AllEq(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return internalUnitSSE2Simd::BAllTrue3_R(V4IsEq(a, b)); +} + +PX_FORCE_INLINE Vec3V V3Round(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); +#ifdef __SSE4_2__ + return _mm_round_ps(a, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC); +#else + // return _mm_round_ps(a, 0x0); + const Vec3V half = V3Load(0.5f); + const __m128 signBit = _mm_cvtepi32_ps(_mm_srli_epi32(_mm_cvtps_epi32(a), 31)); + const Vec3V aRound = V3Sub(V3Add(a, half), signBit); + __m128i tmp = _mm_cvttps_epi32(aRound); + return _mm_cvtepi32_ps(tmp); +#endif +} + +PX_FORCE_INLINE Vec3V V3Sin(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + // Modulo the range of the given angles such that -XM_2PI <= Angles < XM_2PI + const Vec4V recipTwoPi = V4LoadA(g_PXReciprocalTwoPi.f); + const Vec4V twoPi = V4LoadA(g_PXTwoPi.f); + const Vec3V tmp = V3Scale(a, recipTwoPi); + const Vec3V b = V3Round(tmp); + const Vec3V V1 = V3NegScaleSub(b, twoPi, a); + + // sin(V) ~= V - V^3 / 3! + V^5 / 5! - V^7 / 7! + V^9 / 9! - V^11 / 11! + V^13 / 13! - + // V^15 / 15! + V^17 / 17! - V^19 / 19! + V^21 / 21! - V^23 / 23! (for -PI <= V < PI) + const Vec3V V2 = V3Mul(V1, V1); + const Vec3V V3 = V3Mul(V2, V1); + const Vec3V V5 = V3Mul(V3, V2); + const Vec3V V7 = V3Mul(V5, V2); + const Vec3V V9 = V3Mul(V7, V2); + const Vec3V V11 = V3Mul(V9, V2); + const Vec3V V13 = V3Mul(V11, V2); + const Vec3V V15 = V3Mul(V13, V2); + const Vec3V V17 = V3Mul(V15, V2); + const Vec3V V19 = V3Mul(V17, V2); + const Vec3V V21 = V3Mul(V19, V2); + const Vec3V V23 = V3Mul(V21, V2); + + const Vec4V sinCoefficients0 = V4LoadA(g_PXSinCoefficients0.f); + const Vec4V sinCoefficients1 = V4LoadA(g_PXSinCoefficients1.f); + const Vec4V sinCoefficients2 = V4LoadA(g_PXSinCoefficients2.f); + + const FloatV S1 = V4GetY(sinCoefficients0); + const FloatV S2 = V4GetZ(sinCoefficients0); + const FloatV S3 = V4GetW(sinCoefficients0); + const FloatV S4 = V4GetX(sinCoefficients1); + const FloatV S5 = V4GetY(sinCoefficients1); + const FloatV S6 = V4GetZ(sinCoefficients1); + const FloatV S7 = V4GetW(sinCoefficients1); + const FloatV S8 = V4GetX(sinCoefficients2); + const FloatV S9 = V4GetY(sinCoefficients2); + const FloatV S10 = V4GetZ(sinCoefficients2); + const FloatV S11 = V4GetW(sinCoefficients2); + + Vec3V Result; + Result = V3ScaleAdd(V3, S1, V1); + Result = V3ScaleAdd(V5, S2, Result); + Result = V3ScaleAdd(V7, S3, Result); + Result = V3ScaleAdd(V9, S4, Result); + Result = V3ScaleAdd(V11, S5, Result); + Result = V3ScaleAdd(V13, S6, Result); + Result = V3ScaleAdd(V15, S7, Result); + Result = V3ScaleAdd(V17, S8, Result); + Result = V3ScaleAdd(V19, S9, Result); + Result = V3ScaleAdd(V21, S10, Result); + Result = V3ScaleAdd(V23, S11, Result); + + ASSERT_ISVALIDVEC3V(Result); + return Result; +} + +PX_FORCE_INLINE Vec3V V3Cos(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + + // Modulo the range of the given angles such that -XM_2PI <= Angles < XM_2PI + const Vec4V recipTwoPi = V4LoadA(g_PXReciprocalTwoPi.f); + const Vec4V twoPi = V4LoadA(g_PXTwoPi.f); + const Vec3V tmp = V3Scale(a, recipTwoPi); + const Vec3V b = V3Round(tmp); + const Vec3V V1 = V3NegScaleSub(b, twoPi, a); + + // cos(V) ~= 1 - V^2 / 2! + V^4 / 4! - V^6 / 6! + V^8 / 8! - V^10 / 10! + V^12 / 12! - + // V^14 / 14! + V^16 / 16! - V^18 / 18! + V^20 / 20! - V^22 / 22! (for -PI <= V < PI) + const Vec3V V2 = V3Mul(V1, V1); + const Vec3V V4 = V3Mul(V2, V2); + const Vec3V V6 = V3Mul(V4, V2); + const Vec3V V8 = V3Mul(V4, V4); + const Vec3V V10 = V3Mul(V6, V4); + const Vec3V V12 = V3Mul(V6, V6); + const Vec3V V14 = V3Mul(V8, V6); + const Vec3V V16 = V3Mul(V8, V8); + const Vec3V V18 = V3Mul(V10, V8); + const Vec3V V20 = V3Mul(V10, V10); + const Vec3V V22 = V3Mul(V12, V10); + + const Vec4V cosCoefficients0 = V4LoadA(g_PXCosCoefficients0.f); + const Vec4V cosCoefficients1 = V4LoadA(g_PXCosCoefficients1.f); + const Vec4V cosCoefficients2 = V4LoadA(g_PXCosCoefficients2.f); + + const FloatV C1 = V4GetY(cosCoefficients0); + const FloatV C2 = V4GetZ(cosCoefficients0); + const FloatV C3 = V4GetW(cosCoefficients0); + const FloatV C4 = V4GetX(cosCoefficients1); + const FloatV C5 = V4GetY(cosCoefficients1); + const FloatV C6 = V4GetZ(cosCoefficients1); + const FloatV C7 = V4GetW(cosCoefficients1); + const FloatV C8 = V4GetX(cosCoefficients2); + const FloatV C9 = V4GetY(cosCoefficients2); + const FloatV C10 = V4GetZ(cosCoefficients2); + const FloatV C11 = V4GetW(cosCoefficients2); + + Vec3V Result; + Result = V3ScaleAdd(V2, C1, V3One()); + Result = V3ScaleAdd(V4, C2, Result); + Result = V3ScaleAdd(V6, C3, Result); + Result = V3ScaleAdd(V8, C4, Result); + Result = V3ScaleAdd(V10, C5, Result); + Result = V3ScaleAdd(V12, C6, Result); + Result = V3ScaleAdd(V14, C7, Result); + Result = V3ScaleAdd(V16, C8, Result); + Result = V3ScaleAdd(V18, C9, Result); + Result = V3ScaleAdd(V20, C10, Result); + Result = V3ScaleAdd(V22, C11, Result); + + ASSERT_ISVALIDVEC3V(Result); + return Result; +} + +PX_FORCE_INLINE Vec3V V3PermYZZ(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 2, 2, 1)); +} + +PX_FORCE_INLINE Vec3V V3PermXYX(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 1, 0)); +} + +PX_FORCE_INLINE Vec3V V3PermYZX(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 2, 1)); +} + +PX_FORCE_INLINE Vec3V V3PermZXY(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 1, 0, 2)); +} + +PX_FORCE_INLINE Vec3V V3PermZZY(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 1, 2, 2)); +} + +PX_FORCE_INLINE Vec3V V3PermYXX(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 0, 1)); +} + +PX_FORCE_INLINE Vec3V V3Perm_Zero_1Z_0Y(const Vec3V v0, const Vec3V v1) +{ + ASSERT_ISVALIDVEC3V(v0); + ASSERT_ISVALIDVEC3V(v1); + return _mm_shuffle_ps(v1, v0, _MM_SHUFFLE(3, 1, 2, 3)); +} + +PX_FORCE_INLINE Vec3V V3Perm_0Z_Zero_1X(const Vec3V v0, const Vec3V v1) +{ + ASSERT_ISVALIDVEC3V(v0); + ASSERT_ISVALIDVEC3V(v1); + return _mm_shuffle_ps(v0, v1, _MM_SHUFFLE(3, 0, 3, 2)); +} + +PX_FORCE_INLINE Vec3V V3Perm_1Y_0X_Zero(const Vec3V v0, const Vec3V v1) +{ + ASSERT_ISVALIDVEC3V(v0); + ASSERT_ISVALIDVEC3V(v1); + // There must be a better way to do this. + Vec3V v2 = V3Zero(); + FloatV y1 = V3GetY(v1); + FloatV x0 = V3GetX(v0); + v2 = V3SetX(v2, y1); + return V3SetY(v2, x0); +} + +PX_FORCE_INLINE FloatV V3SumElems(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); +#ifdef __SSE4_2__ + Vec3V r = _mm_hadd_ps(a, a); + r = _mm_hadd_ps(r, r); + return r; +#else + __m128 shuf1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)); // z,y,x,w + __m128 shuf2 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)); // y,x,w,z + __m128 shuf3 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)); // x,w,z,y + return _mm_add_ps(_mm_add_ps(shuf1, shuf2), shuf3); +#endif +} + +PX_FORCE_INLINE PxU32 V3OutOfBounds(const Vec3V a, const Vec3V min, const Vec3V max) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(min); + ASSERT_ISVALIDVEC3V(max); + const BoolV c = BOr(V3IsGrtr(a, max), V3IsGrtr(min, a)); + return !BAllEqFFFF(c); +} + +PX_FORCE_INLINE PxU32 V3InBounds(const Vec3V a, const Vec3V min, const Vec3V max) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(min); + ASSERT_ISVALIDVEC3V(max); + const BoolV c = BAnd(V3IsGrtrOrEq(a, min), V3IsGrtrOrEq(max, a)); + return BAllEqTTTT(c); +} + +PX_FORCE_INLINE PxU32 V3OutOfBounds(const Vec3V a, const Vec3V bounds) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(bounds); + return V3OutOfBounds(a, V3Neg(bounds), bounds); +} + +PX_FORCE_INLINE PxU32 V3InBounds(const Vec3V a, const Vec3V bounds) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(bounds) + return V3InBounds(a, V3Neg(bounds), bounds); +} + +PX_FORCE_INLINE void V3Transpose(Vec3V& col0, Vec3V& col1, Vec3V& col2) +{ + ASSERT_ISVALIDVEC3V(col0); + ASSERT_ISVALIDVEC3V(col1); + ASSERT_ISVALIDVEC3V(col2); + + const Vec3V col3 = _mm_setzero_ps(); + Vec3V tmp0 = _mm_unpacklo_ps(col0, col1); + Vec3V tmp2 = _mm_unpacklo_ps(col2, col3); + Vec3V tmp1 = _mm_unpackhi_ps(col0, col1); + Vec3V tmp3 = _mm_unpackhi_ps(col2, col3); + col0 = _mm_movelh_ps(tmp0, tmp2); + col1 = _mm_movehl_ps(tmp2, tmp0); + col2 = _mm_movelh_ps(tmp1, tmp3); +} + +////////////////////////////////// +// VEC4V +////////////////////////////////// + +PX_FORCE_INLINE Vec4V V4Splat(const FloatV f) +{ + ASSERT_ISVALIDFLOATV(f); + // return _mm_shuffle_ps(f, f, _MM_SHUFFLE(0,0,0,0)); + return f; +} + +PX_FORCE_INLINE Vec4V V4Merge(const FloatV* const floatVArray) +{ + ASSERT_ISVALIDFLOATV(floatVArray[0]); + ASSERT_ISVALIDFLOATV(floatVArray[1]); + ASSERT_ISVALIDFLOATV(floatVArray[2]); + ASSERT_ISVALIDFLOATV(floatVArray[3]); + const __m128 xw = _mm_move_ss(floatVArray[1], floatVArray[0]); // y, y, y, x + const __m128 yz = _mm_move_ss(floatVArray[2], floatVArray[3]); // z, z, z, w + return _mm_shuffle_ps(xw, yz, _MM_SHUFFLE(0, 2, 1, 0)); +} + +PX_FORCE_INLINE Vec4V V4Merge(const FloatVArg x, const FloatVArg y, const FloatVArg z, const FloatVArg w) +{ + ASSERT_ISVALIDFLOATV(x); + ASSERT_ISVALIDFLOATV(y); + ASSERT_ISVALIDFLOATV(z); + ASSERT_ISVALIDFLOATV(w); + const __m128 xw = _mm_move_ss(y, x); // y, y, y, x + const __m128 yz = _mm_move_ss(z, w); // z, z, z, w + return _mm_shuffle_ps(xw, yz, _MM_SHUFFLE(0, 2, 1, 0)); +} + +PX_FORCE_INLINE Vec4V V4MergeW(const Vec4VArg x, const Vec4VArg y, const Vec4VArg z, const Vec4VArg w) +{ + const Vec4V xz = _mm_unpackhi_ps(x, z); + const Vec4V yw = _mm_unpackhi_ps(y, w); + return _mm_unpackhi_ps(xz, yw); +} + +PX_FORCE_INLINE Vec4V V4MergeZ(const Vec4VArg x, const Vec4VArg y, const Vec4VArg z, const Vec4VArg w) +{ + const Vec4V xz = _mm_unpackhi_ps(x, z); + const Vec4V yw = _mm_unpackhi_ps(y, w); + return _mm_unpacklo_ps(xz, yw); +} + +PX_FORCE_INLINE Vec4V V4MergeY(const Vec4VArg x, const Vec4VArg y, const Vec4VArg z, const Vec4VArg w) +{ + const Vec4V xz = _mm_unpacklo_ps(x, z); + const Vec4V yw = _mm_unpacklo_ps(y, w); + return _mm_unpackhi_ps(xz, yw); +} + +PX_FORCE_INLINE Vec4V V4MergeX(const Vec4VArg x, const Vec4VArg y, const Vec4VArg z, const Vec4VArg w) +{ + const Vec4V xz = _mm_unpacklo_ps(x, z); + const Vec4V yw = _mm_unpacklo_ps(y, w); + return _mm_unpacklo_ps(xz, yw); +} + +PX_FORCE_INLINE Vec4V V4UnpackXY(const Vec4VArg a, const Vec4VArg b) +{ + return _mm_unpacklo_ps(a, b); +} + +PX_FORCE_INLINE Vec4V V4UnpackZW(const Vec4VArg a, const Vec4VArg b) +{ + return _mm_unpackhi_ps(a, b); +} + +PX_FORCE_INLINE Vec4V V4UnitW() +{ + const PX_ALIGN(16, PxF32) w[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; + const __m128 w128 = _mm_load_ps(w); + return w128; +} + +PX_FORCE_INLINE Vec4V V4UnitX() +{ + const PX_ALIGN(16, PxF32) x[4] = { 1.0f, 0.0f, 0.0f, 0.0f }; + const __m128 x128 = _mm_load_ps(x); + return x128; +} + +PX_FORCE_INLINE Vec4V V4UnitY() +{ + const PX_ALIGN(16, PxF32) y[4] = { 0.0f, 1.0f, 0.0f, 0.0f }; + const __m128 y128 = _mm_load_ps(y); + return y128; +} + +PX_FORCE_INLINE Vec4V V4UnitZ() +{ + const PX_ALIGN(16, PxF32) z[4] = { 0.0f, 0.0f, 1.0f, 0.0f }; + const __m128 z128 = _mm_load_ps(z); + return z128; +} + +PX_FORCE_INLINE FloatV V4GetW(const Vec4V f) +{ + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(3, 3, 3, 3)); +} + +PX_FORCE_INLINE FloatV V4GetX(const Vec4V f) +{ + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(0, 0, 0, 0)); +} + +PX_FORCE_INLINE FloatV V4GetY(const Vec4V f) +{ + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(1, 1, 1, 1)); +} + +PX_FORCE_INLINE FloatV V4GetZ(const Vec4V f) +{ + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(2, 2, 2, 2)); +} + +PX_FORCE_INLINE Vec4V V4SetW(const Vec4V v, const FloatV f) +{ + ASSERT_ISVALIDFLOATV(f); + return V4Sel(BTTTF(), v, f); +} + +PX_FORCE_INLINE Vec4V V4SetX(const Vec4V v, const FloatV f) +{ + ASSERT_ISVALIDFLOATV(f); + return V4Sel(BFTTT(), v, f); +} + +PX_FORCE_INLINE Vec4V V4SetY(const Vec4V v, const FloatV f) +{ + ASSERT_ISVALIDFLOATV(f); + return V4Sel(BTFTT(), v, f); +} + +PX_FORCE_INLINE Vec4V V4SetZ(const Vec4V v, const FloatV f) +{ + ASSERT_ISVALIDFLOATV(f); + return V4Sel(BTTFT(), v, f); +} + +PX_FORCE_INLINE Vec4V V4ClearW(const Vec4V v) +{ +#if !PX_EMSCRIPTEN + return _mm_and_ps(v, V4LoadA(internalUnitSSE2Simd::gMaskXYZ)); +#else + return _mm_and_ps(v, (VecI32V&)internalUnitSSE2Simd::gMaskXYZ); +#endif +} + +PX_FORCE_INLINE Vec4V V4PermYXWZ(const Vec4V a) +{ + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 3, 0, 1)); +} + +PX_FORCE_INLINE Vec4V V4PermXZXZ(const Vec4V a) +{ + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 0, 2, 0)); +} + +PX_FORCE_INLINE Vec4V V4PermYWYW(const Vec4V a) +{ + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 1, 3, 1)); +} + +PX_FORCE_INLINE Vec4V V4PermYZXW(const Vec4V a) +{ + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 2, 1)); +} + +PX_FORCE_INLINE Vec4V V4PermZWXY(const Vec4V a) +{ + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 0, 3, 2)); +} + +template +PX_FORCE_INLINE Vec4V V4Perm(const Vec4V a) +{ + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(w, z, y, x)); +} + +PX_FORCE_INLINE Vec4V V4Zero() +{ + return V4Load(0.0f); +} + +PX_FORCE_INLINE Vec4V V4One() +{ + return V4Load(1.0f); +} + +PX_FORCE_INLINE Vec4V V4Eps() +{ + return V4Load(PX_EPS_REAL); +} + +PX_FORCE_INLINE Vec4V V4Neg(const Vec4V f) +{ + return _mm_sub_ps(_mm_setzero_ps(), f); +} + +PX_FORCE_INLINE Vec4V V4Add(const Vec4V a, const Vec4V b) +{ + return _mm_add_ps(a, b); +} + +PX_FORCE_INLINE Vec4V V4Sub(const Vec4V a, const Vec4V b) +{ + return _mm_sub_ps(a, b); +} + +PX_FORCE_INLINE Vec4V V4Scale(const Vec4V a, const FloatV b) +{ + return _mm_mul_ps(a, b); +} + +PX_FORCE_INLINE Vec4V V4Mul(const Vec4V a, const Vec4V b) +{ + return _mm_mul_ps(a, b); +} + +PX_FORCE_INLINE Vec4V V4ScaleInv(const Vec4V a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(b); + return _mm_div_ps(a, b); +} + +PX_FORCE_INLINE Vec4V V4Div(const Vec4V a, const Vec4V b) +{ + return _mm_div_ps(a, b); +} + +PX_FORCE_INLINE Vec4V V4ScaleInvFast(const Vec4V a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(b); + return _mm_mul_ps(a, _mm_rcp_ps(b)); +} + +PX_FORCE_INLINE Vec4V V4DivFast(const Vec4V a, const Vec4V b) +{ + return _mm_mul_ps(a, _mm_rcp_ps(b)); +} + +PX_FORCE_INLINE Vec4V V4Recip(const Vec4V a) +{ + return _mm_div_ps(V4One(), a); +} + +PX_FORCE_INLINE Vec4V V4RecipFast(const Vec4V a) +{ + return _mm_rcp_ps(a); +} + +PX_FORCE_INLINE Vec4V V4Rsqrt(const Vec4V a) +{ + return _mm_div_ps(V4One(), _mm_sqrt_ps(a)); +} + +PX_FORCE_INLINE Vec4V V4RsqrtFast(const Vec4V a) +{ + return _mm_rsqrt_ps(a); +} + +PX_FORCE_INLINE Vec4V V4Sqrt(const Vec4V a) +{ + return _mm_sqrt_ps(a); +} + +PX_FORCE_INLINE Vec4V V4ScaleAdd(const Vec4V a, const FloatV b, const Vec4V c) +{ + ASSERT_ISVALIDFLOATV(b); + return V4Add(V4Scale(a, b), c); +} + +PX_FORCE_INLINE Vec4V V4NegScaleSub(const Vec4V a, const FloatV b, const Vec4V c) +{ + ASSERT_ISVALIDFLOATV(b); + return V4Sub(c, V4Scale(a, b)); +} + +PX_FORCE_INLINE Vec4V V4MulAdd(const Vec4V a, const Vec4V b, const Vec4V c) +{ + return V4Add(V4Mul(a, b), c); +} + +PX_FORCE_INLINE Vec4V V4NegMulSub(const Vec4V a, const Vec4V b, const Vec4V c) +{ + return V4Sub(c, V4Mul(a, b)); +} + +PX_FORCE_INLINE Vec4V V4Abs(const Vec4V a) +{ + return V4Max(a, V4Neg(a)); +} + +PX_FORCE_INLINE FloatV V4SumElements(const Vec4V a) +{ +#ifdef __SSE4_2__ + Vec4V r = _mm_hadd_ps(a, a); + r = _mm_hadd_ps(r, r); + return r; +#else + const Vec4V xy = V4UnpackXY(a, a); // x,x,y,y + const Vec4V zw = V4UnpackZW(a, a); // z,z,w,w + const Vec4V xz_yw = V4Add(xy, zw); // x+z,x+z,y+w,y+w + const FloatV xz = V4GetX(xz_yw); // x+z + const FloatV yw = V4GetZ(xz_yw); // y+w + return FAdd(xz, yw); // sum +#endif +} + +PX_FORCE_INLINE FloatV V4Dot(const Vec4V a, const Vec4V b) +{ +#ifdef __SSE4_2__ + return _mm_dp_ps(a, b, 0xff); +#else + //const __m128 dot1 = _mm_mul_ps(a, b); // x,y,z,w + //const __m128 shuf1 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(2, 1, 0, 3)); // w,x,y,z + //const __m128 shuf2 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(1, 0, 3, 2)); // z,w,x,y + //const __m128 shuf3 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(0, 3, 2, 1)); // y,z,w,x + //return _mm_add_ps(_mm_add_ps(shuf2, shuf3), _mm_add_ps(dot1, shuf1)); + + // aw*bw | az*bz | ay*by | ax*bx + const __m128 t0 = _mm_mul_ps(a, b); + // ay*by | ax*bx | aw*bw | az*bz + const __m128 t1 = _mm_shuffle_ps(t0, t0, _MM_SHUFFLE(1, 0, 3, 2)); + // ay*by + aw*bw | ax*bx + az*bz | aw*bw + ay*by | az*bz + ax*bx + const __m128 t2 = _mm_add_ps(t0, t1); + // ax*bx + az*bz | ay*by + aw*bw | az*bz + ax*bx | aw*bw + ay*by + const __m128 t3 = _mm_shuffle_ps(t2, t2, _MM_SHUFFLE(2, 3, 0, 1)); + // ax*bx + az*bz + ay*by + aw*bw + return _mm_add_ps(t3, t2); +#endif +} + +PX_FORCE_INLINE FloatV V4Dot3(const Vec4V a, const Vec4V b) +{ +#ifdef __SSE4_2__ + return _mm_dp_ps(a, b, 0x7f); +#else + const __m128 dot1 = _mm_mul_ps(a, b); // w,z,y,x + const __m128 shuf1 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(0, 0, 0, 0)); // z,y,x,w + const __m128 shuf2 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(1, 1, 1, 1)); // y,x,w,z + const __m128 shuf3 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(2, 2, 2, 2)); // x,w,z,y + return _mm_add_ps(_mm_add_ps(shuf1, shuf2), shuf3); +#endif +} + +PX_FORCE_INLINE Vec4V V4Cross(const Vec4V a, const Vec4V b) +{ + const __m128 r1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 1, 0, 2)); // z,x,y,w + const __m128 r2 = _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 0, 2, 1)); // y,z,x,w + const __m128 l1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 2, 1)); // y,z,x,w + const __m128 l2 = _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 1, 0, 2)); // z,x,y,w + return _mm_sub_ps(_mm_mul_ps(l1, l2), _mm_mul_ps(r1, r2)); +} + +PX_FORCE_INLINE FloatV V4Length(const Vec4V a) +{ + return _mm_sqrt_ps(V4Dot(a, a)); +} + +PX_FORCE_INLINE FloatV V4LengthSq(const Vec4V a) +{ + return V4Dot(a, a); +} + +PX_FORCE_INLINE Vec4V V4Normalize(const Vec4V a) +{ + ASSERT_ISFINITELENGTH(a); + return V4ScaleInv(a, _mm_sqrt_ps(V4Dot(a, a))); +} + +PX_FORCE_INLINE Vec4V V4NormalizeFast(const Vec4V a) +{ + ASSERT_ISFINITELENGTH(a); + return V4ScaleInvFast(a, _mm_sqrt_ps(V4Dot(a, a))); +} + +PX_FORCE_INLINE Vec4V V4NormalizeSafe(const Vec4V a, const Vec3V unsafeReturnValue) +{ + const __m128 eps = V3Eps(); + const __m128 length = V4Length(a); + const __m128 isGreaterThanZero = V4IsGrtr(length, eps); + return V4Sel(isGreaterThanZero, V4ScaleInv(a, length), unsafeReturnValue); +} + +PX_FORCE_INLINE BoolV V4IsEqU32(const VecU32V a, const VecU32V b) +{ + return m128_I2F(_mm_cmpeq_epi32(m128_F2I(a), m128_F2I(b))); +} + +PX_FORCE_INLINE Vec4V V4Sel(const BoolV c, const Vec4V a, const Vec4V b) +{ + return _mm_or_ps(_mm_andnot_ps(c, b), _mm_and_ps(c, a)); +} + +PX_FORCE_INLINE BoolV V4IsGrtr(const Vec4V a, const Vec4V b) +{ + return _mm_cmpgt_ps(a, b); +} + +PX_FORCE_INLINE BoolV V4IsGrtrOrEq(const Vec4V a, const Vec4V b) +{ + return _mm_cmpge_ps(a, b); +} + +PX_FORCE_INLINE BoolV V4IsEq(const Vec4V a, const Vec4V b) +{ + return _mm_cmpeq_ps(a, b); +} + +PX_FORCE_INLINE Vec4V V4Max(const Vec4V a, const Vec4V b) +{ + return _mm_max_ps(a, b); +} + +PX_FORCE_INLINE Vec4V V4Min(const Vec4V a, const Vec4V b) +{ + return _mm_min_ps(a, b); +} + +PX_FORCE_INLINE FloatV V4ExtractMax(const Vec4V a) +{ + const __m128 shuf1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 1, 0, 3)); + const __m128 shuf2 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 0, 3, 2)); + const __m128 shuf3 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 3, 2, 1)); + + return _mm_max_ps(_mm_max_ps(a, shuf1), _mm_max_ps(shuf2, shuf3)); +} + +PX_FORCE_INLINE FloatV V4ExtractMin(const Vec4V a) +{ + const __m128 shuf1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 1, 0, 3)); + const __m128 shuf2 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 0, 3, 2)); + const __m128 shuf3 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 3, 2, 1)); + + return _mm_min_ps(_mm_min_ps(a, shuf1), _mm_min_ps(shuf2, shuf3)); +} + +PX_FORCE_INLINE Vec4V V4Clamp(const Vec4V a, const Vec4V minV, const Vec4V maxV) +{ + return V4Max(V4Min(a, maxV), minV); +} + +PX_FORCE_INLINE PxU32 V4AllGrtr(const Vec4V a, const Vec4V b) +{ + return internalUnitSSE2Simd::BAllTrue4_R(V4IsGrtr(a, b)); +} + +PX_FORCE_INLINE PxU32 V4AllGrtrOrEq(const Vec4V a, const Vec4V b) +{ + return internalUnitSSE2Simd::BAllTrue4_R(V4IsGrtrOrEq(a, b)); +} + +PX_FORCE_INLINE PxU32 V4AllGrtrOrEq3(const Vec4V a, const Vec4V b) +{ + return internalUnitSSE2Simd::BAllTrue3_R(V4IsGrtrOrEq(a, b)); +} + +PX_FORCE_INLINE PxU32 V4AllEq(const Vec4V a, const Vec4V b) +{ + return internalUnitSSE2Simd::BAllTrue4_R(V4IsEq(a, b)); +} + +PX_FORCE_INLINE PxU32 V4AnyGrtr3(const Vec4V a, const Vec4V b) +{ + return internalUnitSSE2Simd::BAnyTrue3_R(V4IsGrtr(a, b)); +} + +PX_FORCE_INLINE Vec4V V4Round(const Vec4V a) +{ +#ifdef __SSE4_2__ + return _mm_round_ps(a, _MM_FROUND_TO_NEAREST_INT | _MM_FROUND_NO_EXC); +#else + // return _mm_round_ps(a, 0x0); + const Vec4V half = V4Load(0.5f); + const __m128 signBit = _mm_cvtepi32_ps(_mm_srli_epi32(_mm_cvtps_epi32(a), 31)); + const Vec4V aRound = V4Sub(V4Add(a, half), signBit); + __m128i tmp = _mm_cvttps_epi32(aRound); + return _mm_cvtepi32_ps(tmp); +#endif +} + +PX_FORCE_INLINE Vec4V V4Sin(const Vec4V a) +{ + const Vec4V recipTwoPi = V4LoadA(g_PXReciprocalTwoPi.f); + const Vec4V twoPi = V4LoadA(g_PXTwoPi.f); + const Vec4V tmp = V4Mul(a, recipTwoPi); + const Vec4V b = V4Round(tmp); + const Vec4V V1 = V4NegMulSub(twoPi, b, a); + + // sin(V) ~= V - V^3 / 3! + V^5 / 5! - V^7 / 7! + V^9 / 9! - V^11 / 11! + V^13 / 13! - + // V^15 / 15! + V^17 / 17! - V^19 / 19! + V^21 / 21! - V^23 / 23! (for -PI <= V < PI) + const Vec4V V2 = V4Mul(V1, V1); + const Vec4V V3 = V4Mul(V2, V1); + const Vec4V V5 = V4Mul(V3, V2); + const Vec4V V7 = V4Mul(V5, V2); + const Vec4V V9 = V4Mul(V7, V2); + const Vec4V V11 = V4Mul(V9, V2); + const Vec4V V13 = V4Mul(V11, V2); + const Vec4V V15 = V4Mul(V13, V2); + const Vec4V V17 = V4Mul(V15, V2); + const Vec4V V19 = V4Mul(V17, V2); + const Vec4V V21 = V4Mul(V19, V2); + const Vec4V V23 = V4Mul(V21, V2); + + const Vec4V sinCoefficients0 = V4LoadA(g_PXSinCoefficients0.f); + const Vec4V sinCoefficients1 = V4LoadA(g_PXSinCoefficients1.f); + const Vec4V sinCoefficients2 = V4LoadA(g_PXSinCoefficients2.f); + + const FloatV S1 = V4GetY(sinCoefficients0); + const FloatV S2 = V4GetZ(sinCoefficients0); + const FloatV S3 = V4GetW(sinCoefficients0); + const FloatV S4 = V4GetX(sinCoefficients1); + const FloatV S5 = V4GetY(sinCoefficients1); + const FloatV S6 = V4GetZ(sinCoefficients1); + const FloatV S7 = V4GetW(sinCoefficients1); + const FloatV S8 = V4GetX(sinCoefficients2); + const FloatV S9 = V4GetY(sinCoefficients2); + const FloatV S10 = V4GetZ(sinCoefficients2); + const FloatV S11 = V4GetW(sinCoefficients2); + + Vec4V Result; + Result = V4MulAdd(S1, V3, V1); + Result = V4MulAdd(S2, V5, Result); + Result = V4MulAdd(S3, V7, Result); + Result = V4MulAdd(S4, V9, Result); + Result = V4MulAdd(S5, V11, Result); + Result = V4MulAdd(S6, V13, Result); + Result = V4MulAdd(S7, V15, Result); + Result = V4MulAdd(S8, V17, Result); + Result = V4MulAdd(S9, V19, Result); + Result = V4MulAdd(S10, V21, Result); + Result = V4MulAdd(S11, V23, Result); + + return Result; +} + +PX_FORCE_INLINE Vec4V V4Cos(const Vec4V a) +{ + const Vec4V recipTwoPi = V4LoadA(g_PXReciprocalTwoPi.f); + const Vec4V twoPi = V4LoadA(g_PXTwoPi.f); + const Vec4V tmp = V4Mul(a, recipTwoPi); + const Vec4V b = V4Round(tmp); + const Vec4V V1 = V4NegMulSub(twoPi, b, a); + + // cos(V) ~= 1 - V^2 / 2! + V^4 / 4! - V^6 / 6! + V^8 / 8! - V^10 / 10! + V^12 / 12! - + // V^14 / 14! + V^16 / 16! - V^18 / 18! + V^20 / 20! - V^22 / 22! (for -PI <= V < PI) + const Vec4V V2 = V4Mul(V1, V1); + const Vec4V V4 = V4Mul(V2, V2); + const Vec4V V6 = V4Mul(V4, V2); + const Vec4V V8 = V4Mul(V4, V4); + const Vec4V V10 = V4Mul(V6, V4); + const Vec4V V12 = V4Mul(V6, V6); + const Vec4V V14 = V4Mul(V8, V6); + const Vec4V V16 = V4Mul(V8, V8); + const Vec4V V18 = V4Mul(V10, V8); + const Vec4V V20 = V4Mul(V10, V10); + const Vec4V V22 = V4Mul(V12, V10); + + const Vec4V cosCoefficients0 = V4LoadA(g_PXCosCoefficients0.f); + const Vec4V cosCoefficients1 = V4LoadA(g_PXCosCoefficients1.f); + const Vec4V cosCoefficients2 = V4LoadA(g_PXCosCoefficients2.f); + + const FloatV C1 = V4GetY(cosCoefficients0); + const FloatV C2 = V4GetZ(cosCoefficients0); + const FloatV C3 = V4GetW(cosCoefficients0); + const FloatV C4 = V4GetX(cosCoefficients1); + const FloatV C5 = V4GetY(cosCoefficients1); + const FloatV C6 = V4GetZ(cosCoefficients1); + const FloatV C7 = V4GetW(cosCoefficients1); + const FloatV C8 = V4GetX(cosCoefficients2); + const FloatV C9 = V4GetY(cosCoefficients2); + const FloatV C10 = V4GetZ(cosCoefficients2); + const FloatV C11 = V4GetW(cosCoefficients2); + + Vec4V Result; + Result = V4MulAdd(C1, V2, V4One()); + Result = V4MulAdd(C2, V4, Result); + Result = V4MulAdd(C3, V6, Result); + Result = V4MulAdd(C4, V8, Result); + Result = V4MulAdd(C5, V10, Result); + Result = V4MulAdd(C6, V12, Result); + Result = V4MulAdd(C7, V14, Result); + Result = V4MulAdd(C8, V16, Result); + Result = V4MulAdd(C9, V18, Result); + Result = V4MulAdd(C10, V20, Result); + Result = V4MulAdd(C11, V22, Result); + + return Result; +} + +PX_FORCE_INLINE void V4Transpose(Vec4V& col0, Vec4V& col1, Vec4V& col2, Vec4V& col3) +{ + Vec4V tmp0 = _mm_unpacklo_ps(col0, col1); + Vec4V tmp2 = _mm_unpacklo_ps(col2, col3); + Vec4V tmp1 = _mm_unpackhi_ps(col0, col1); + Vec4V tmp3 = _mm_unpackhi_ps(col2, col3); + col0 = _mm_movelh_ps(tmp0, tmp2); + col1 = _mm_movehl_ps(tmp2, tmp0); + col2 = _mm_movelh_ps(tmp1, tmp3); + col3 = _mm_movehl_ps(tmp3, tmp1); +} + +////////////////////////////////// +// BoolV +////////////////////////////////// + +PX_FORCE_INLINE BoolV BFFFF() +{ + return _mm_setzero_ps(); +} + +PX_FORCE_INLINE BoolV BFFFT() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0,0,0,0xFFFFFFFF}; + const __m128 ffft=_mm_load_ps((float*)&f); + return ffft;*/ + return m128_I2F(_mm_set_epi32(-1, 0, 0, 0)); +} + +PX_FORCE_INLINE BoolV BFFTF() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0,0,0xFFFFFFFF,0}; + const __m128 fftf=_mm_load_ps((float*)&f); + return fftf;*/ + return m128_I2F(_mm_set_epi32(0, -1, 0, 0)); +} + +PX_FORCE_INLINE BoolV BFFTT() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0,0,0xFFFFFFFF,0xFFFFFFFF}; + const __m128 fftt=_mm_load_ps((float*)&f); + return fftt;*/ + return m128_I2F(_mm_set_epi32(-1, -1, 0, 0)); +} + +PX_FORCE_INLINE BoolV BFTFF() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0,0xFFFFFFFF,0,0}; + const __m128 ftff=_mm_load_ps((float*)&f); + return ftff;*/ + return m128_I2F(_mm_set_epi32(0, 0, -1, 0)); +} + +PX_FORCE_INLINE BoolV BFTFT() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0,0xFFFFFFFF,0,0xFFFFFFFF}; + const __m128 ftft=_mm_load_ps((float*)&f); + return ftft;*/ + return m128_I2F(_mm_set_epi32(-1, 0, -1, 0)); +} + +PX_FORCE_INLINE BoolV BFTTF() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0,0xFFFFFFFF,0xFFFFFFFF,0}; + const __m128 fttf=_mm_load_ps((float*)&f); + return fttf;*/ + return m128_I2F(_mm_set_epi32(0, -1, -1, 0)); +} + +PX_FORCE_INLINE BoolV BFTTT() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}; + const __m128 fttt=_mm_load_ps((float*)&f); + return fttt;*/ + return m128_I2F(_mm_set_epi32(-1, -1, -1, 0)); +} + +PX_FORCE_INLINE BoolV BTFFF() +{ + // const PX_ALIGN(16, PxU32 f[4])={0xFFFFFFFF,0,0,0}; + // const __m128 tfff=_mm_load_ps((float*)&f); + // return tfff; + return m128_I2F(_mm_set_epi32(0, 0, 0, -1)); +} + +PX_FORCE_INLINE BoolV BTFFT() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0xFFFFFFFF,0,0,0xFFFFFFFF}; + const __m128 tfft=_mm_load_ps((float*)&f); + return tfft;*/ + return m128_I2F(_mm_set_epi32(-1, 0, 0, -1)); +} + +PX_FORCE_INLINE BoolV BTFTF() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0xFFFFFFFF,0,0xFFFFFFFF,0}; + const __m128 tftf=_mm_load_ps((float*)&f); + return tftf;*/ + return m128_I2F(_mm_set_epi32(0, -1, 0, -1)); +} + +PX_FORCE_INLINE BoolV BTFTT() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0xFFFFFFFF,0,0xFFFFFFFF,0xFFFFFFFF}; + const __m128 tftt=_mm_load_ps((float*)&f); + return tftt;*/ + return m128_I2F(_mm_set_epi32(-1, -1, 0, -1)); +} + +PX_FORCE_INLINE BoolV BTTFF() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0xFFFFFFFF,0xFFFFFFFF,0,0}; + const __m128 ttff=_mm_load_ps((float*)&f); + return ttff;*/ + return m128_I2F(_mm_set_epi32(0, 0, -1, -1)); +} + +PX_FORCE_INLINE BoolV BTTFT() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0xFFFFFFFF,0xFFFFFFFF,0,0xFFFFFFFF}; + const __m128 ttft=_mm_load_ps((float*)&f); + return ttft;*/ + return m128_I2F(_mm_set_epi32(-1, 0, -1, -1)); +} + +PX_FORCE_INLINE BoolV BTTTF() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0}; + const __m128 tttf=_mm_load_ps((float*)&f); + return tttf;*/ + return m128_I2F(_mm_set_epi32(0, -1, -1, -1)); +} + +PX_FORCE_INLINE BoolV BTTTT() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}; + const __m128 tttt=_mm_load_ps((float*)&f); + return tttt;*/ + return m128_I2F(_mm_set_epi32(-1, -1, -1, -1)); +} + +PX_FORCE_INLINE BoolV BXMask() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0xFFFFFFFF,0,0,0}; + const __m128 tfff=_mm_load_ps((float*)&f); + return tfff;*/ + return m128_I2F(_mm_set_epi32(0, 0, 0, -1)); +} + +PX_FORCE_INLINE BoolV BYMask() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0,0xFFFFFFFF,0,0}; + const __m128 ftff=_mm_load_ps((float*)&f); + return ftff;*/ + return m128_I2F(_mm_set_epi32(0, 0, -1, 0)); +} + +PX_FORCE_INLINE BoolV BZMask() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0,0,0xFFFFFFFF,0}; + const __m128 fftf=_mm_load_ps((float*)&f); + return fftf;*/ + return m128_I2F(_mm_set_epi32(0, -1, 0, 0)); +} + +PX_FORCE_INLINE BoolV BWMask() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0,0,0,0xFFFFFFFF}; + const __m128 ffft=_mm_load_ps((float*)&f); + return ffft;*/ + return m128_I2F(_mm_set_epi32(-1, 0, 0, 0)); +} + +PX_FORCE_INLINE BoolV BGetX(const BoolV f) +{ + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(0, 0, 0, 0)); +} + +PX_FORCE_INLINE BoolV BGetY(const BoolV f) +{ + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(1, 1, 1, 1)); +} + +PX_FORCE_INLINE BoolV BGetZ(const BoolV f) +{ + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(2, 2, 2, 2)); +} + +PX_FORCE_INLINE BoolV BGetW(const BoolV f) +{ + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(3, 3, 3, 3)); +} + +PX_FORCE_INLINE BoolV BSetX(const BoolV v, const BoolV f) +{ + return V4Sel(BFTTT(), v, f); +} + +PX_FORCE_INLINE BoolV BSetY(const BoolV v, const BoolV f) +{ + return V4Sel(BTFTT(), v, f); +} + +PX_FORCE_INLINE BoolV BSetZ(const BoolV v, const BoolV f) +{ + return V4Sel(BTTFT(), v, f); +} + +PX_FORCE_INLINE BoolV BSetW(const BoolV v, const BoolV f) +{ + return V4Sel(BTTTF(), v, f); +} + +PX_FORCE_INLINE BoolV BAnd(const BoolV a, const BoolV b) +{ + return _mm_and_ps(a, b); +} + +PX_FORCE_INLINE BoolV BNot(const BoolV a) +{ + const BoolV bAllTrue(BTTTT()); + return _mm_xor_ps(a, bAllTrue); +} + +PX_FORCE_INLINE BoolV BAndNot(const BoolV a, const BoolV b) +{ + return _mm_andnot_ps(b, a); +} + +PX_FORCE_INLINE BoolV BOr(const BoolV a, const BoolV b) +{ + return _mm_or_ps(a, b); +} + +PX_FORCE_INLINE BoolV BAllTrue4(const BoolV a) +{ + const BoolV bTmp = + _mm_and_ps(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 1, 0, 1)), _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 3, 2, 3))); + return _mm_and_ps(_mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(0, 0, 0, 0)), + _mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(1, 1, 1, 1))); +} + +PX_FORCE_INLINE BoolV BAnyTrue4(const BoolV a) +{ + const BoolV bTmp = + _mm_or_ps(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 1, 0, 1)), _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 3, 2, 3))); + return _mm_or_ps(_mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(0, 0, 0, 0)), + _mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(1, 1, 1, 1))); +} + +PX_FORCE_INLINE BoolV BAllTrue3(const BoolV a) +{ + const BoolV bTmp = + _mm_and_ps(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 1, 0, 1)), _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2))); + return _mm_and_ps(_mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(0, 0, 0, 0)), + _mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(1, 1, 1, 1))); +} + +PX_FORCE_INLINE BoolV BAnyTrue3(const BoolV a) +{ + const BoolV bTmp = + _mm_or_ps(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 1, 0, 1)), _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2))); + return _mm_or_ps(_mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(0, 0, 0, 0)), + _mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(1, 1, 1, 1))); +} + +PX_FORCE_INLINE PxU32 BAllEq(const BoolV a, const BoolV b) +{ + const BoolV bTest = m128_I2F(_mm_cmpeq_epi32(m128_F2I(a), m128_F2I(b))); + return internalUnitSSE2Simd::BAllTrue4_R(bTest); +} + +PX_FORCE_INLINE PxU32 BAllEqTTTT(const BoolV a) +{ + return PxU32(_mm_movemask_ps(a)==15); +} + +PX_FORCE_INLINE PxU32 BAllEqFFFF(const BoolV a) +{ + return PxU32(_mm_movemask_ps(a)==0); +} + +PX_FORCE_INLINE PxU32 BGetBitMask(const BoolV a) +{ + return PxU32(_mm_movemask_ps(a)); +} + +////////////////////////////////// +// MAT33V +////////////////////////////////// + +PX_FORCE_INLINE Vec3V M33MulV3(const Mat33V& a, const Vec3V b) +{ + const FloatV x = V3GetX(b); + const FloatV y = V3GetY(b); + const FloatV z = V3GetZ(b); + const Vec3V v0 = V3Scale(a.col0, x); + const Vec3V v1 = V3Scale(a.col1, y); + const Vec3V v2 = V3Scale(a.col2, z); + const Vec3V v0PlusV1 = V3Add(v0, v1); + return V3Add(v0PlusV1, v2); +} + +PX_FORCE_INLINE Vec3V M33TrnspsMulV3(const Mat33V& a, const Vec3V b) +{ + const FloatV x = V3Dot(a.col0, b); + const FloatV y = V3Dot(a.col1, b); + const FloatV z = V3Dot(a.col2, b); + return V3Merge(x, y, z); +} + +PX_FORCE_INLINE Vec3V M33MulV3AddV3(const Mat33V& A, const Vec3V b, const Vec3V c) +{ + const FloatV x = V3GetX(b); + const FloatV y = V3GetY(b); + const FloatV z = V3GetZ(b); + Vec3V result = V3ScaleAdd(A.col0, x, c); + result = V3ScaleAdd(A.col1, y, result); + return V3ScaleAdd(A.col2, z, result); +} + +PX_FORCE_INLINE Mat33V M33MulM33(const Mat33V& a, const Mat33V& b) +{ + return Mat33V(M33MulV3(a, b.col0), M33MulV3(a, b.col1), M33MulV3(a, b.col2)); +} + +PX_FORCE_INLINE Mat33V M33Add(const Mat33V& a, const Mat33V& b) +{ + return Mat33V(V3Add(a.col0, b.col0), V3Add(a.col1, b.col1), V3Add(a.col2, b.col2)); +} + +PX_FORCE_INLINE Mat33V M33Scale(const Mat33V& a, const FloatV& b) +{ + return Mat33V(V3Scale(a.col0, b), V3Scale(a.col1, b), V3Scale(a.col2, b)); +} + +PX_FORCE_INLINE Mat33V M33Inverse(const Mat33V& a) +{ + const BoolV tfft = BTFFT(); + const BoolV tttf = BTTTF(); + const FloatV zero = FZero(); + const Vec3V cross01 = V3Cross(a.col0, a.col1); + const Vec3V cross12 = V3Cross(a.col1, a.col2); + const Vec3V cross20 = V3Cross(a.col2, a.col0); + const FloatV dot = V3Dot(cross01, a.col2); + const FloatV invDet = _mm_rcp_ps(dot); + const Vec3V mergeh = _mm_unpacklo_ps(cross12, cross01); + const Vec3V mergel = _mm_unpackhi_ps(cross12, cross01); + Vec3V colInv0 = _mm_unpacklo_ps(mergeh, cross20); + colInv0 = _mm_or_ps(_mm_andnot_ps(tttf, zero), _mm_and_ps(tttf, colInv0)); + const Vec3V zppd = _mm_shuffle_ps(mergeh, cross20, _MM_SHUFFLE(3, 0, 0, 2)); + const Vec3V pbwp = _mm_shuffle_ps(cross20, mergeh, _MM_SHUFFLE(3, 3, 1, 0)); + const Vec3V colInv1 = _mm_or_ps(_mm_andnot_ps(BTFFT(), pbwp), _mm_and_ps(BTFFT(), zppd)); + const Vec3V xppd = _mm_shuffle_ps(mergel, cross20, _MM_SHUFFLE(3, 0, 0, 0)); + const Vec3V pcyp = _mm_shuffle_ps(cross20, mergel, _MM_SHUFFLE(3, 1, 2, 0)); + const Vec3V colInv2 = _mm_or_ps(_mm_andnot_ps(tfft, pcyp), _mm_and_ps(tfft, xppd)); + + return Mat33V(_mm_mul_ps(colInv0, invDet), _mm_mul_ps(colInv1, invDet), _mm_mul_ps(colInv2, invDet)); +} + +PX_FORCE_INLINE Mat33V M33Trnsps(const Mat33V& a) +{ + return Mat33V(V3Merge(V3GetX(a.col0), V3GetX(a.col1), V3GetX(a.col2)), + V3Merge(V3GetY(a.col0), V3GetY(a.col1), V3GetY(a.col2)), + V3Merge(V3GetZ(a.col0), V3GetZ(a.col1), V3GetZ(a.col2))); +} + +PX_FORCE_INLINE Mat33V M33Identity() +{ + return Mat33V(V3UnitX(), V3UnitY(), V3UnitZ()); +} + +PX_FORCE_INLINE Mat33V M33Sub(const Mat33V& a, const Mat33V& b) +{ + return Mat33V(V3Sub(a.col0, b.col0), V3Sub(a.col1, b.col1), V3Sub(a.col2, b.col2)); +} + +PX_FORCE_INLINE Mat33V M33Neg(const Mat33V& a) +{ + return Mat33V(V3Neg(a.col0), V3Neg(a.col1), V3Neg(a.col2)); +} + +PX_FORCE_INLINE Mat33V M33Abs(const Mat33V& a) +{ + return Mat33V(V3Abs(a.col0), V3Abs(a.col1), V3Abs(a.col2)); +} + +PX_FORCE_INLINE Mat33V PromoteVec3V(const Vec3V v) +{ + const BoolV bTFFF = BTFFF(); + const BoolV bFTFF = BFTFF(); + const BoolV bFFTF = BTFTF(); + + const Vec3V zero = V3Zero(); + + return Mat33V(V3Sel(bTFFF, v, zero), V3Sel(bFTFF, v, zero), V3Sel(bFFTF, v, zero)); +} + +PX_FORCE_INLINE Mat33V M33Diagonal(const Vec3VArg d) +{ + const FloatV x = V3Mul(V3UnitX(), d); + const FloatV y = V3Mul(V3UnitY(), d); + const FloatV z = V3Mul(V3UnitZ(), d); + return Mat33V(x, y, z); +} + +////////////////////////////////// +// MAT34V +////////////////////////////////// + +PX_FORCE_INLINE Vec3V M34MulV3(const Mat34V& a, const Vec3V b) +{ + const FloatV x = V3GetX(b); + const FloatV y = V3GetY(b); + const FloatV z = V3GetZ(b); + const Vec3V v0 = V3Scale(a.col0, x); + const Vec3V v1 = V3Scale(a.col1, y); + const Vec3V v2 = V3Scale(a.col2, z); + const Vec3V v0PlusV1 = V3Add(v0, v1); + const Vec3V v0PlusV1Plusv2 = V3Add(v0PlusV1, v2); + return V3Add(v0PlusV1Plusv2, a.col3); +} + +PX_FORCE_INLINE Vec3V M34Mul33V3(const Mat34V& a, const Vec3V b) +{ + const FloatV x = V3GetX(b); + const FloatV y = V3GetY(b); + const FloatV z = V3GetZ(b); + const Vec3V v0 = V3Scale(a.col0, x); + const Vec3V v1 = V3Scale(a.col1, y); + const Vec3V v2 = V3Scale(a.col2, z); + const Vec3V v0PlusV1 = V3Add(v0, v1); + return V3Add(v0PlusV1, v2); +} + +PX_FORCE_INLINE Vec3V M34TrnspsMul33V3(const Mat34V& a, const Vec3V b) +{ + const FloatV x = V3Dot(a.col0, b); + const FloatV y = V3Dot(a.col1, b); + const FloatV z = V3Dot(a.col2, b); + return V3Merge(x, y, z); +} + +PX_FORCE_INLINE Mat34V M34MulM34(const Mat34V& a, const Mat34V& b) +{ + return Mat34V(M34Mul33V3(a, b.col0), M34Mul33V3(a, b.col1), M34Mul33V3(a, b.col2), M34MulV3(a, b.col3)); +} + +PX_FORCE_INLINE Mat33V M34MulM33(const Mat34V& a, const Mat33V& b) +{ + return Mat33V(M34Mul33V3(a, b.col0), M34Mul33V3(a, b.col1), M34Mul33V3(a, b.col2)); +} + +PX_FORCE_INLINE Mat33V M34Mul33MM34(const Mat34V& a, const Mat34V& b) +{ + return Mat33V(M34Mul33V3(a, b.col0), M34Mul33V3(a, b.col1), M34Mul33V3(a, b.col2)); +} + +PX_FORCE_INLINE Mat34V M34Add(const Mat34V& a, const Mat34V& b) +{ + return Mat34V(V3Add(a.col0, b.col0), V3Add(a.col1, b.col1), V3Add(a.col2, b.col2), V3Add(a.col3, b.col3)); +} + +PX_FORCE_INLINE Mat33V M34Trnsps33(const Mat34V& a) +{ + return Mat33V(V3Merge(V3GetX(a.col0), V3GetX(a.col1), V3GetX(a.col2)), + V3Merge(V3GetY(a.col0), V3GetY(a.col1), V3GetY(a.col2)), + V3Merge(V3GetZ(a.col0), V3GetZ(a.col1), V3GetZ(a.col2))); +} + +////////////////////////////////// +// MAT44V +////////////////////////////////// + +PX_FORCE_INLINE Vec4V M44MulV4(const Mat44V& a, const Vec4V b) +{ + const FloatV x = V4GetX(b); + const FloatV y = V4GetY(b); + const FloatV z = V4GetZ(b); + const FloatV w = V4GetW(b); + + const Vec4V v0 = V4Scale(a.col0, x); + const Vec4V v1 = V4Scale(a.col1, y); + const Vec4V v2 = V4Scale(a.col2, z); + const Vec4V v3 = V4Scale(a.col3, w); + const Vec4V v0PlusV1 = V4Add(v0, v1); + const Vec4V v0PlusV1Plusv2 = V4Add(v0PlusV1, v2); + return V4Add(v0PlusV1Plusv2, v3); +} + +PX_FORCE_INLINE Vec4V M44TrnspsMulV4(const Mat44V& a, const Vec4V b) +{ + PX_ALIGN(16, FloatV) dotProdArray[4] = { V4Dot(a.col0, b), V4Dot(a.col1, b), V4Dot(a.col2, b), V4Dot(a.col3, b) }; + return V4Merge(dotProdArray); +} + +PX_FORCE_INLINE Mat44V M44MulM44(const Mat44V& a, const Mat44V& b) +{ + return Mat44V(M44MulV4(a, b.col0), M44MulV4(a, b.col1), M44MulV4(a, b.col2), M44MulV4(a, b.col3)); +} + +PX_FORCE_INLINE Mat44V M44Add(const Mat44V& a, const Mat44V& b) +{ + return Mat44V(V4Add(a.col0, b.col0), V4Add(a.col1, b.col1), V4Add(a.col2, b.col2), V4Add(a.col3, b.col3)); +} + +PX_FORCE_INLINE Mat44V M44Trnsps(const Mat44V& a) +{ + const Vec4V v0 = _mm_unpacklo_ps(a.col0, a.col2); + const Vec4V v1 = _mm_unpackhi_ps(a.col0, a.col2); + const Vec4V v2 = _mm_unpacklo_ps(a.col1, a.col3); + const Vec4V v3 = _mm_unpackhi_ps(a.col1, a.col3); + return Mat44V(_mm_unpacklo_ps(v0, v2), _mm_unpackhi_ps(v0, v2), _mm_unpacklo_ps(v1, v3), _mm_unpackhi_ps(v1, v3)); +} + +PX_FORCE_INLINE Mat44V M44Inverse(const Mat44V& a) +{ + __m128 minor0, minor1, minor2, minor3; + __m128 row0, row1, row2, row3; + __m128 det, tmp1; + + tmp1 = V4Zero(); + row1 = V4Zero(); + row3 = V4Zero(); + + row0 = a.col0; + row1 = _mm_shuffle_ps(a.col1, a.col1, _MM_SHUFFLE(1, 0, 3, 2)); + row2 = a.col2; + row3 = _mm_shuffle_ps(a.col3, a.col3, _MM_SHUFFLE(1, 0, 3, 2)); + + tmp1 = _mm_mul_ps(row2, row3); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); + minor0 = _mm_mul_ps(row1, tmp1); + minor1 = _mm_mul_ps(row0, tmp1); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); + minor0 = _mm_sub_ps(_mm_mul_ps(row1, tmp1), minor0); + minor1 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor1); + minor1 = _mm_shuffle_ps(minor1, minor1, 0x4E); + + tmp1 = _mm_mul_ps(row1, row2); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); + minor0 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor0); + minor3 = _mm_mul_ps(row0, tmp1); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); + minor0 = _mm_sub_ps(minor0, _mm_mul_ps(row3, tmp1)); + minor3 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor3); + minor3 = _mm_shuffle_ps(minor3, minor3, 0x4E); + + tmp1 = _mm_mul_ps(_mm_shuffle_ps(row1, row1, 0x4E), row3); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); + row2 = _mm_shuffle_ps(row2, row2, 0x4E); + minor0 = _mm_add_ps(_mm_mul_ps(row2, tmp1), minor0); + minor2 = _mm_mul_ps(row0, tmp1); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); + minor0 = _mm_sub_ps(minor0, _mm_mul_ps(row2, tmp1)); + minor2 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor2); + minor2 = _mm_shuffle_ps(minor2, minor2, 0x4E); + + tmp1 = _mm_mul_ps(row0, row1); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); + minor2 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor2); + minor3 = _mm_sub_ps(_mm_mul_ps(row2, tmp1), minor3); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); + minor2 = _mm_sub_ps(_mm_mul_ps(row3, tmp1), minor2); + minor3 = _mm_sub_ps(minor3, _mm_mul_ps(row2, tmp1)); + + tmp1 = _mm_mul_ps(row0, row3); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); + minor1 = _mm_sub_ps(minor1, _mm_mul_ps(row2, tmp1)); + minor2 = _mm_add_ps(_mm_mul_ps(row1, tmp1), minor2); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); + minor1 = _mm_add_ps(_mm_mul_ps(row2, tmp1), minor1); + minor2 = _mm_sub_ps(minor2, _mm_mul_ps(row1, tmp1)); + + tmp1 = _mm_mul_ps(row0, row2); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); + minor1 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor1); + minor3 = _mm_sub_ps(minor3, _mm_mul_ps(row1, tmp1)); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); + minor1 = _mm_sub_ps(minor1, _mm_mul_ps(row3, tmp1)); + minor3 = _mm_add_ps(_mm_mul_ps(row1, tmp1), minor3); + + det = _mm_mul_ps(row0, minor0); + det = _mm_add_ps(_mm_shuffle_ps(det, det, 0x4E), det); + det = _mm_add_ss(_mm_shuffle_ps(det, det, 0xB1), det); + tmp1 = _mm_rcp_ss(det); +#if 0 + det = _mm_sub_ss(_mm_add_ss(tmp1, tmp1), _mm_mul_ss(det, _mm_mul_ss(tmp1, tmp1))); + det = _mm_shuffle_ps(det, det, 0x00); +#else + det = _mm_shuffle_ps(tmp1, tmp1, _MM_SHUFFLE(0, 0, 0, 0)); +#endif + + minor0 = _mm_mul_ps(det, minor0); + minor1 = _mm_mul_ps(det, minor1); + minor2 = _mm_mul_ps(det, minor2); + minor3 = _mm_mul_ps(det, minor3); + Mat44V invTrans(minor0, minor1, minor2, minor3); + return M44Trnsps(invTrans); +} + +PX_FORCE_INLINE Vec4V V4LoadXYZW(const PxF32& x, const PxF32& y, const PxF32& z, const PxF32& w) +{ + return _mm_set_ps(w, z, y, x); +} + +/* +// AP: work in progress - use proper SSE intrinsics where possible +PX_FORCE_INLINE VecU16V V4U32PK(VecU32V a, VecU32V b) +{ + VecU16V result; + result.m128_u16[0] = PxU16(PxClamp((a).m128_u32[0], 0, 0xFFFF)); + result.m128_u16[1] = PxU16(PxClamp((a).m128_u32[1], 0, 0xFFFF)); + result.m128_u16[2] = PxU16(PxClamp((a).m128_u32[2], 0, 0xFFFF)); + result.m128_u16[3] = PxU16(PxClamp((a).m128_u32[3], 0, 0xFFFF)); + result.m128_u16[4] = PxU16(PxClamp((b).m128_u32[0], 0, 0xFFFF)); + result.m128_u16[5] = PxU16(PxClamp((b).m128_u32[1], 0, 0xFFFF)); + result.m128_u16[6] = PxU16(PxClamp((b).m128_u32[2], 0, 0xFFFF)); + result.m128_u16[7] = PxU16(PxClamp((b).m128_u32[3], 0, 0xFFFF)); + return result; +} +*/ + +PX_FORCE_INLINE VecU32V V4U32Sel(const BoolV c, const VecU32V a, const VecU32V b) +{ + return m128_I2F(_mm_or_si128(_mm_andnot_si128(m128_F2I(c), m128_F2I(b)), _mm_and_si128(m128_F2I(c), m128_F2I(a)))); +} + +PX_FORCE_INLINE VecU32V V4U32or(VecU32V a, VecU32V b) +{ + return m128_I2F(_mm_or_si128(m128_F2I(a), m128_F2I(b))); +} + +PX_FORCE_INLINE VecU32V V4U32xor(VecU32V a, VecU32V b) +{ + return m128_I2F(_mm_xor_si128(m128_F2I(a), m128_F2I(b))); +} + +PX_FORCE_INLINE VecU32V V4U32and(VecU32V a, VecU32V b) +{ + return m128_I2F(_mm_and_si128(m128_F2I(a), m128_F2I(b))); +} + +PX_FORCE_INLINE VecU32V V4U32Andc(VecU32V a, VecU32V b) +{ + return m128_I2F(_mm_andnot_si128(m128_F2I(b), m128_F2I(a))); +} + +/* +PX_FORCE_INLINE VecU16V V4U16Or(VecU16V a, VecU16V b) +{ + return m128_I2F(_mm_or_si128(m128_F2I(a), m128_F2I(b))); +} +*/ + +/* +PX_FORCE_INLINE VecU16V V4U16And(VecU16V a, VecU16V b) +{ + return m128_I2F(_mm_and_si128(m128_F2I(a), m128_F2I(b))); +} +*/ + +/* +PX_FORCE_INLINE VecU16V V4U16Andc(VecU16V a, VecU16V b) +{ + return m128_I2F(_mm_andnot_si128(m128_F2I(b), m128_F2I(a))); +} +*/ + +PX_FORCE_INLINE VecI32V I4Load(const PxI32 i) +{ + return m128_F2I(_mm_load1_ps(reinterpret_cast(&i))); +} + +PX_FORCE_INLINE VecI32V I4LoadU(const PxI32* i) +{ + return m128_F2I(_mm_loadu_ps(reinterpret_cast(i))); +} + +PX_FORCE_INLINE VecI32V I4LoadA(const PxI32* i) +{ + return m128_F2I(_mm_load_ps(reinterpret_cast(i))); +} + +PX_FORCE_INLINE VecI32V VecI32V_Add(const VecI32VArg a, const VecI32VArg b) +{ + return _mm_add_epi32(a, b); +} + +PX_FORCE_INLINE VecI32V VecI32V_Sub(const VecI32VArg a, const VecI32VArg b) +{ + return _mm_sub_epi32(a, b); +} + +PX_FORCE_INLINE BoolV VecI32V_IsGrtr(const VecI32VArg a, const VecI32VArg b) +{ + return m128_I2F(_mm_cmpgt_epi32(a, b)); +} + +PX_FORCE_INLINE BoolV VecI32V_IsEq(const VecI32VArg a, const VecI32VArg b) +{ + return m128_I2F(_mm_cmpeq_epi32(a, b)); +} + +PX_FORCE_INLINE VecI32V V4I32Sel(const BoolV c, const VecI32V a, const VecI32V b) +{ + return _mm_or_si128(_mm_andnot_si128(m128_F2I(c), b), _mm_and_si128(m128_F2I(c), a)); +} + +PX_FORCE_INLINE VecI32V VecI32V_Zero() +{ + return _mm_setzero_si128(); +} + +PX_FORCE_INLINE VecI32V VecI32V_One() +{ + return I4Load(1); +} + +PX_FORCE_INLINE VecI32V VecI32V_Two() +{ + return I4Load(2); +} + +PX_FORCE_INLINE VecI32V VecI32V_MinusOne() +{ + return I4Load(-1); +} + +PX_FORCE_INLINE VecU32V U4Zero() +{ + return U4Load(0); +} + +PX_FORCE_INLINE VecU32V U4One() +{ + return U4Load(1); +} + +PX_FORCE_INLINE VecU32V U4Two() +{ + return U4Load(2); +} + +PX_FORCE_INLINE VecI32V VecI32V_Sel(const BoolV c, const VecI32VArg a, const VecI32VArg b) +{ + return _mm_or_si128(_mm_andnot_si128(m128_F2I(c), b), _mm_and_si128(m128_F2I(c), a)); +} + +PX_FORCE_INLINE VecShiftV VecI32V_PrepareShift(const VecI32VArg shift) +{ + VecShiftV s; + s.shift = VecI32V_Sel(BTFFF(), shift, VecI32V_Zero()); + return s; +} + +PX_FORCE_INLINE VecI32V VecI32V_LeftShift(const VecI32VArg a, const VecShiftVArg count) +{ + return _mm_sll_epi32(a, count.shift); +} + +PX_FORCE_INLINE VecI32V VecI32V_RightShift(const VecI32VArg a, const VecShiftVArg count) +{ + return _mm_srl_epi32(a, count.shift); +} + +PX_FORCE_INLINE VecI32V VecI32V_LeftShift(const VecI32VArg a, const PxU32 count) +{ + return _mm_slli_epi32(a, PxI32(count)); +} + +PX_FORCE_INLINE VecI32V VecI32V_RightShift(const VecI32VArg a, const PxU32 count) +{ + return _mm_srai_epi32(a, PxI32(count)); +} + +PX_FORCE_INLINE VecI32V VecI32V_And(const VecI32VArg a, const VecI32VArg b) +{ + return _mm_and_si128(a, b); +} + +PX_FORCE_INLINE VecI32V VecI32V_Or(const VecI32VArg a, const VecI32VArg b) +{ + return _mm_or_si128(a, b); +} + +PX_FORCE_INLINE VecI32V VecI32V_GetX(const VecI32VArg a) +{ + return m128_F2I(_mm_shuffle_ps(m128_I2F(a), m128_I2F(a), _MM_SHUFFLE(0, 0, 0, 0))); +} + +PX_FORCE_INLINE VecI32V VecI32V_GetY(const VecI32VArg a) +{ + return m128_F2I(_mm_shuffle_ps(m128_I2F(a), m128_I2F(a), _MM_SHUFFLE(1, 1, 1, 1))); +} + +PX_FORCE_INLINE VecI32V VecI32V_GetZ(const VecI32VArg a) +{ + return m128_F2I(_mm_shuffle_ps(m128_I2F(a), m128_I2F(a), _MM_SHUFFLE(2, 2, 2, 2))); +} + +PX_FORCE_INLINE VecI32V VecI32V_GetW(const VecI32VArg a) +{ + return m128_F2I(_mm_shuffle_ps(m128_I2F(a), m128_I2F(a), _MM_SHUFFLE(3, 3, 3, 3))); +} + +PX_FORCE_INLINE void PxI32_From_VecI32V(const VecI32VArg a, PxI32* i) +{ + _mm_store_ss(reinterpret_cast(i), m128_I2F(a)); +} + +PX_FORCE_INLINE VecI32V VecI32V_Merge(const VecI32VArg x, const VecI32VArg y, const VecI32VArg z, const VecI32VArg w) +{ + const __m128 xw = _mm_move_ss(m128_I2F(y), m128_I2F(x)); // y, y, y, x + const __m128 yz = _mm_move_ss(m128_I2F(z), m128_I2F(w)); // z, z, z, w + return m128_F2I(_mm_shuffle_ps(xw, yz, _MM_SHUFFLE(0, 2, 1, 0))); +} + +PX_FORCE_INLINE VecI32V VecI32V_From_BoolV(const BoolVArg a) +{ + return m128_F2I(a); +} + +PX_FORCE_INLINE VecU32V VecU32V_From_BoolV(const BoolVArg a) +{ + return a; +} + +/* +template PX_FORCE_INLINE VecI32V V4ISplat() +{ + VecI32V result; + result.m128_i32[0] = a; + result.m128_i32[1] = a; + result.m128_i32[2] = a; + result.m128_i32[3] = a; + return result; +} + +template PX_FORCE_INLINE VecU32V V4USplat() +{ + VecU32V result; + result.m128_u32[0] = a; + result.m128_u32[1] = a; + result.m128_u32[2] = a; + result.m128_u32[3] = a; + return result; +} +*/ + +/* +PX_FORCE_INLINE void V4U16StoreAligned(VecU16V val, VecU16V* address) +{ + *address = val; +} +*/ + +PX_FORCE_INLINE void V4U32StoreAligned(VecU32V val, VecU32V* address) +{ + *address = val; +} + +PX_FORCE_INLINE Vec4V V4LoadAligned(Vec4V* addr) +{ + return *addr; +} + +PX_FORCE_INLINE Vec4V V4LoadUnaligned(Vec4V* addr) +{ + return V4LoadU(reinterpret_cast(addr)); +} + +PX_FORCE_INLINE Vec4V V4Andc(const Vec4V a, const VecU32V b) +{ + VecU32V result32(a); + result32 = V4U32Andc(result32, b); + return Vec4V(result32); +} + +PX_FORCE_INLINE VecU32V V4IsGrtrV32u(const Vec4V a, const Vec4V b) +{ + return V4IsGrtr(a, b); +} + +PX_FORCE_INLINE VecU16V V4U16LoadAligned(VecU16V* addr) +{ + return *addr; +} + +PX_FORCE_INLINE VecU16V V4U16LoadUnaligned(VecU16V* addr) +{ + return *addr; +} + +PX_FORCE_INLINE VecU16V V4U16CompareGt(VecU16V a, VecU16V b) +{ + // _mm_cmpgt_epi16 doesn't work for unsigned values unfortunately + // return m128_I2F(_mm_cmpgt_epi16(m128_F2I(a), m128_F2I(b))); + VecU16V result; + result.m128_u16[0] = (a).m128_u16[0] > (b).m128_u16[0]; + result.m128_u16[1] = (a).m128_u16[1] > (b).m128_u16[1]; + result.m128_u16[2] = (a).m128_u16[2] > (b).m128_u16[2]; + result.m128_u16[3] = (a).m128_u16[3] > (b).m128_u16[3]; + result.m128_u16[4] = (a).m128_u16[4] > (b).m128_u16[4]; + result.m128_u16[5] = (a).m128_u16[5] > (b).m128_u16[5]; + result.m128_u16[6] = (a).m128_u16[6] > (b).m128_u16[6]; + result.m128_u16[7] = (a).m128_u16[7] > (b).m128_u16[7]; + return result; +} + +PX_FORCE_INLINE VecU16V V4I16CompareGt(VecU16V a, VecU16V b) +{ + return m128_I2F(_mm_cmpgt_epi16(m128_F2I(a), m128_F2I(b))); +} + +PX_FORCE_INLINE Vec4V Vec4V_From_VecU32V(VecU32V a) +{ + Vec4V result = V4LoadXYZW(PxF32(a.m128_u32[0]), PxF32(a.m128_u32[1]), PxF32(a.m128_u32[2]), PxF32(a.m128_u32[3])); + return result; +} + +PX_FORCE_INLINE Vec4V Vec4V_From_VecI32V(VecI32V in) +{ + return _mm_cvtepi32_ps(in); +} + +PX_FORCE_INLINE VecI32V VecI32V_From_Vec4V(Vec4V a) +{ + return _mm_cvttps_epi32(a); +} + +PX_FORCE_INLINE Vec4V Vec4V_ReinterpretFrom_VecU32V(VecU32V a) +{ + return Vec4V(a); +} + +PX_FORCE_INLINE Vec4V Vec4V_ReinterpretFrom_VecI32V(VecI32V a) +{ + return m128_I2F(a); +} + +PX_FORCE_INLINE VecU32V VecU32V_ReinterpretFrom_Vec4V(Vec4V a) +{ + return VecU32V(a); +} + +PX_FORCE_INLINE VecI32V VecI32V_ReinterpretFrom_Vec4V(Vec4V a) +{ + return m128_F2I(a); +} + +/* +template PX_FORCE_INLINE BoolV BSplatElement(BoolV a) +{ + BoolV result; + result[0] = result[1] = result[2] = result[3] = a[index]; + return result; +} +*/ + +template +BoolV BSplatElement(BoolV a) +{ + float* data = reinterpret_cast(&a); + return V4Load(data[index]); +} + +template +PX_FORCE_INLINE VecU32V V4U32SplatElement(VecU32V a) +{ + VecU32V result; + result.m128_u32[0] = result.m128_u32[1] = result.m128_u32[2] = result.m128_u32[3] = a.m128_u32[index]; + return result; +} + +template +PX_FORCE_INLINE Vec4V V4SplatElement(Vec4V a) +{ + float* data = reinterpret_cast(&a); + return V4Load(data[index]); +} + +PX_FORCE_INLINE VecU32V U4LoadXYZW(PxU32 x, PxU32 y, PxU32 z, PxU32 w) +{ + VecU32V result; + result.m128_u32[0] = x; + result.m128_u32[1] = y; + result.m128_u32[2] = z; + result.m128_u32[3] = w; + return result; +} + +PX_FORCE_INLINE Vec4V V4Ceil(const Vec4V in) +{ + UnionM128 a(in); + return V4LoadXYZW(PxCeil(a.m128_f32[0]), PxCeil(a.m128_f32[1]), PxCeil(a.m128_f32[2]), PxCeil(a.m128_f32[3])); +} + +PX_FORCE_INLINE Vec4V V4Floor(const Vec4V in) +{ + UnionM128 a(in); + return V4LoadXYZW(PxFloor(a.m128_f32[0]), PxFloor(a.m128_f32[1]), PxFloor(a.m128_f32[2]), PxFloor(a.m128_f32[3])); +} + +PX_FORCE_INLINE VecU32V V4ConvertToU32VSaturate(const Vec4V in, PxU32 power) +{ + PX_ASSERT(power == 0 && "Non-zero power not supported in convertToU32VSaturate"); + PX_UNUSED(power); // prevent warning in release builds + PxF32 ffffFFFFasFloat = PxF32(0xFFFF0000); + UnionM128 a(in); + VecU32V result; + result.m128_u32[0] = PxU32(PxClamp((a).m128_f32[0], 0.0f, ffffFFFFasFloat)); + result.m128_u32[1] = PxU32(PxClamp((a).m128_f32[1], 0.0f, ffffFFFFasFloat)); + result.m128_u32[2] = PxU32(PxClamp((a).m128_f32[2], 0.0f, ffffFFFFasFloat)); + result.m128_u32[3] = PxU32(PxClamp((a).m128_f32[3], 0.0f, ffffFFFFasFloat)); + return result; +} + +} // namespace aos +} // namespace physx + +#endif // PXFOUNDATION_PXUNIXSSE2INLINEAOS_H diff --git a/Source/ThirdParty/PhysX/foundation/windows/PxWindowsAoS.h b/Source/ThirdParty/PhysX/foundation/windows/PxWindowsAoS.h new file mode 100644 index 000000000..13175e3ec --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/windows/PxWindowsAoS.h @@ -0,0 +1,143 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_WINDOWS_AOS_H +#define PX_WINDOWS_AOS_H + +// no includes here! this file should be included from PxAOS.h only!!! + +#if !COMPILE_VECTOR_INTRINSICS +#error Vector intrinsics should not be included when using scalar implementation. +#endif + +#if !PX_DOXYGEN +namespace physx +{ +#endif +namespace aos +{ + +typedef __m128 FloatV; +typedef __m128 Vec3V; +typedef __m128 Vec4V; +typedef __m128 BoolV; +typedef __m128 VecU32V; +typedef __m128 VecI32V; +typedef __m128 VecU16V; +typedef __m128 VecI16V; +typedef __m128 QuatV; + +#define FloatVArg FloatV & +#define Vec3VArg Vec3V & +#define Vec4VArg Vec4V & +#define BoolVArg BoolV & +#define VecU32VArg VecU32V & +#define VecI32VArg VecI32V & +#define VecU16VArg VecU16V & +#define VecI16VArg VecI16V & +#define QuatVArg QuatV & + +// Optimization for situations in which you cross product multiple vectors with the same vector. +// Avoids 2X shuffles per product +struct VecCrossV +{ + Vec3V mL1; + Vec3V mR1; +}; + +struct VecShiftV +{ + VecI32V shift; +}; +#define VecShiftVArg VecShiftV & + +PX_ALIGN_PREFIX(16) +struct Mat33V +{ + Mat33V() + { + } + Mat33V(const Vec3V& c0, const Vec3V& c1, const Vec3V& c2) : col0(c0), col1(c1), col2(c2) + { + } + Vec3V PX_ALIGN(16, col0); + Vec3V PX_ALIGN(16, col1); + Vec3V PX_ALIGN(16, col2); +} PX_ALIGN_SUFFIX(16); + +PX_ALIGN_PREFIX(16) +struct Mat34V +{ + Mat34V() + { + } + Mat34V(const Vec3V& c0, const Vec3V& c1, const Vec3V& c2, const Vec3V& c3) : col0(c0), col1(c1), col2(c2), col3(c3) + { + } + Vec3V PX_ALIGN(16, col0); + Vec3V PX_ALIGN(16, col1); + Vec3V PX_ALIGN(16, col2); + Vec3V PX_ALIGN(16, col3); +} PX_ALIGN_SUFFIX(16); + +PX_ALIGN_PREFIX(16) +struct Mat43V +{ + Mat43V() + { + } + Mat43V(const Vec4V& c0, const Vec4V& c1, const Vec4V& c2) : col0(c0), col1(c1), col2(c2) + { + } + Vec4V PX_ALIGN(16, col0); + Vec4V PX_ALIGN(16, col1); + Vec4V PX_ALIGN(16, col2); +} PX_ALIGN_SUFFIX(16); + +PX_ALIGN_PREFIX(16) +struct Mat44V +{ + Mat44V() + { + } + Mat44V(const Vec4V& c0, const Vec4V& c1, const Vec4V& c2, const Vec4V& c3) : col0(c0), col1(c1), col2(c2), col3(c3) + { + } + Vec4V PX_ALIGN(16, col0); + Vec4V PX_ALIGN(16, col1); + Vec4V PX_ALIGN(16, col2); + Vec4V PX_ALIGN(16, col3); +} PX_ALIGN_SUFFIX(16); + +} // namespace aos +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/windows/PxWindowsFPU.h b/Source/ThirdParty/PhysX/foundation/windows/PxWindowsFPU.h new file mode 100644 index 000000000..f70383eae --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/windows/PxWindowsFPU.h @@ -0,0 +1,63 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_WINDOWS_FPU_H +#define PX_WINDOWS_FPU_H + +PX_INLINE physx::PxSIMDGuard::PxSIMDGuard(bool enable) : mEnabled(enable) +{ +#if !PX_ARM && !PX_A64 + if (enable) + { + mControlWord = _mm_getcsr(); + // set default (disable exceptions: _MM_MASK_MASK) and FTZ (_MM_FLUSH_ZERO_ON), DAZ (_MM_DENORMALS_ZERO_ON: (1<<6)) + _mm_setcsr(_MM_MASK_MASK | _MM_FLUSH_ZERO_ON | (1 << 6)); + } + else + { + PX_ASSERT(_mm_getcsr() & _MM_FLUSH_ZERO_ON); + PX_ASSERT(_mm_getcsr() & (1 << 6)); + PX_ASSERT(_mm_getcsr() & _MM_MASK_MASK); + } +#endif +} + +PX_INLINE physx::PxSIMDGuard::~PxSIMDGuard() +{ +#if !PX_ARM && !PX_A64 + if (mEnabled) + { + // restore control word and clear any exception flags + // (setting exception state flags cause exceptions on the first following fp operation) + _mm_setcsr(mControlWord & ~_MM_EXCEPT_MASK); + } +#endif +} + +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/windows/PxWindowsInclude.h b/Source/ThirdParty/PhysX/foundation/windows/PxWindowsInclude.h new file mode 100644 index 000000000..992a5a6ef --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/windows/PxWindowsInclude.h @@ -0,0 +1,96 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_WINDOWS_INCLUDE_H +#define PX_WINDOWS_INCLUDE_H + +#ifndef _WIN32 +#error "This file should only be included by Windows builds!!" +#endif + +#ifdef _WINDOWS_ // windows already included +#error "Only include windows.h through this file!!" +#endif + +// We only support >= Windows XP, and we need this for critical section and +// Setting this hides some important APIs (e.g. LoadPackagedLibrary), so don't do it +#define _WIN32_WINNT 0x0501 + +// turn off as much as we can for windows. All we really need is the thread functions(critical sections/Interlocked* +// etc) +#define NOGDICAPMASKS +#define NOVIRTUALKEYCODES +#define NOWINMESSAGES +#define NOWINSTYLES +#define NOSYSMETRICS +#define NOMENUS +#define NOICONS +#define NOKEYSTATES +#define NOSYSCOMMANDS +#define NORASTEROPS +#define NOSHOWWINDOW +#define NOATOM +#define NOCLIPBOARD +#define NOCOLOR +#define NOCTLMGR +#define NODRAWTEXT +#define NOGDI +#define NOMB +#define NOMEMMGR +#define NOMETAFILE +#define NOMINMAX +#define NOOPENFILE +#define NOSCROLL +#define NOSERVICE +#define NOSOUND +#define NOTEXTMETRIC +#define NOWH +#define NOWINOFFSETS +#define NOCOMM +#define NOKANJI +#define NOHELP +#define NOPROFILER +#define NODEFERWINDOWPOS +#define NOMCX +#define WIN32_LEAN_AND_MEAN +// We need a slightly wider API surface for e.g. MultiByteToWideChar +#define NOUSER +#define NONLS +#define NOMSG + +#pragma warning(push) +#pragma warning(disable : 4668) //'symbol' is not defined as a preprocessor macro, replacing with '0' for 'directives' +#include +#pragma warning(pop) + +#if PX_SSE2 +#include +#endif + +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/windows/PxWindowsInlineAoS.h b/Source/ThirdParty/PhysX/foundation/windows/PxWindowsInlineAoS.h new file mode 100644 index 000000000..ac6ebabd5 --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/windows/PxWindowsInlineAoS.h @@ -0,0 +1,3174 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_WINDOWS_INLINE_AOS_H +#define PX_WINDOWS_INLINE_AOS_H + +#if !COMPILE_VECTOR_INTRINSICS +#error Vector intrinsics should not be included when using scalar implementation. +#endif + +#include "../PxVecMathSSE.h" + +namespace physx +{ +namespace aos +{ + +////////////////////////////////////////////////////////////////////// +//Test that Vec3V and FloatV are legal +////////////////////////////////////////////////////////////////////// + +#define FLOAT_COMPONENTS_EQUAL_THRESHOLD 0.01f +PX_FORCE_INLINE bool isValidFloatV(const FloatV a) +{ + const PxF32 x = V4ReadX(a); + const PxF32 y = V4ReadY(a); + const PxF32 z = V4ReadZ(a); + const PxF32 w = V4ReadW(a); + + return (!(x != y || x != z || x != w)); + + /*if ( + (PxAbs(x - y) < FLOAT_COMPONENTS_EQUAL_THRESHOLD) && + (PxAbs(x - z) < FLOAT_COMPONENTS_EQUAL_THRESHOLD) && + (PxAbs(x - w) < FLOAT_COMPONENTS_EQUAL_THRESHOLD) + ) + { + return true; + } + + if ( + (PxAbs((x - y) / x) < FLOAT_COMPONENTS_EQUAL_THRESHOLD) && + (PxAbs((x - z) / x) < FLOAT_COMPONENTS_EQUAL_THRESHOLD) && + (PxAbs((x - w) / x) < FLOAT_COMPONENTS_EQUAL_THRESHOLD) + ) + { + return true; + } + return false;*/ +} + +PX_FORCE_INLINE bool isValidVec3V(const Vec3V a) +{ + //using _mm_comieq_ss to do the comparison doesn't work for NaN. + PX_ALIGN(16, PxF32 f[4]); + V4StoreA((const Vec4V&)a, f); + return f[3] == 0.0f; +} + +PX_FORCE_INLINE bool isFiniteLength(const Vec3V a) +{ + return !FAllEq(V4LengthSq(a), FZero()); +} + +PX_FORCE_INLINE bool isAligned16(void* a) +{ + return(0 == ((size_t)a & 0x0f)); +} + +//ASSERT_FINITELENGTH is deactivated because there is a lot of code that calls a simd normalisation function with zero length but then ignores the result. + +#if PX_DEBUG +#define ASSERT_ISVALIDVEC3V(a) PX_ASSERT(isValidVec3V(a)) +#define ASSERT_ISVALIDFLOATV(a) PX_ASSERT(isValidFloatV(a)) +#define ASSERT_ISALIGNED16(a) PX_ASSERT(isAligned16((void*)a)) +#define ASSERT_ISFINITELENGTH(a) //PX_ASSERT(isFiniteLength(a)) +#else +#define ASSERT_ISVALIDVEC3V(a) +#define ASSERT_ISVALIDFLOATV(a) +#define ASSERT_ISALIGNED16(a) +#define ASSERT_ISFINITELENGTH(a) +#endif +///////////////////////////////////////////////////////////////////// +////FUNCTIONS USED ONLY FOR ASSERTS IN VECTORISED IMPLEMENTATIONS +///////////////////////////////////////////////////////////////////// + +////////////////////////////////////////////////////////////////////// +// USED ONLY INTERNALLY +////////////////////////////////////////////////////////////////////// + +namespace internalWindowsSimd +{ +PX_FORCE_INLINE __m128 m128_I2F(__m128i n) +{ + return _mm_castsi128_ps(n); +} + +PX_FORCE_INLINE __m128i m128_F2I(__m128 n) +{ + return _mm_castps_si128(n); +} + +PX_FORCE_INLINE PxU32 BAllTrue4_R(const BoolV a) +{ + const PxI32 moveMask = _mm_movemask_ps(a); + return PxU32(moveMask == 0xf); +} + +PX_FORCE_INLINE PxU32 BAllTrue3_R(const BoolV a) +{ + const PxI32 moveMask = _mm_movemask_ps(a); + return PxU32((moveMask & 0x7) == 0x7); +} + +PX_FORCE_INLINE PxU32 BAnyTrue4_R(const BoolV a) +{ + const PxI32 moveMask = _mm_movemask_ps(a); + return PxU32(moveMask != 0x0); +} + +PX_FORCE_INLINE PxU32 BAnyTrue3_R(const BoolV a) +{ + const PxI32 moveMask = _mm_movemask_ps(a); + return PxU32(((moveMask & 0x7) != 0x0)); +} + +PX_FORCE_INLINE PxU32 FiniteTestEq(const Vec4V a, const Vec4V b) +{ + // This is a bit of a bodge. + //_mm_comieq_ss returns 1 if either value is nan so we need to re-cast a and b with true encoded as a non-nan + // number. + // There must be a better way of doing this in sse. + const BoolV one = FOne(); + const BoolV zero = FZero(); + const BoolV a1 = V4Sel(a, one, zero); + const BoolV b1 = V4Sel(b, one, zero); + return (PxU32( + _mm_comieq_ss(a1, b1) && + _mm_comieq_ss(_mm_shuffle_ps(a1, a1, _MM_SHUFFLE(1, 1, 1, 1)), _mm_shuffle_ps(b1, b1, _MM_SHUFFLE(1, 1, 1, 1))) && + _mm_comieq_ss(_mm_shuffle_ps(a1, a1, _MM_SHUFFLE(2, 2, 2, 2)), _mm_shuffle_ps(b1, b1, _MM_SHUFFLE(2, 2, 2, 2))) && + _mm_comieq_ss(_mm_shuffle_ps(a1, a1, _MM_SHUFFLE(3, 3, 3, 3)), _mm_shuffle_ps(b1, b1, _MM_SHUFFLE(3, 3, 3, 3))))); +} + +PX_FORCE_INLINE bool hasZeroElementinFloatV(const FloatV a) +{ + ASSERT_ISVALIDFLOATV(a); + return _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)), FZero()) ? true : false; +} + +PX_FORCE_INLINE bool hasZeroElementInVec3V(const Vec3V a) +{ + return (_mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)), FZero()) || + _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)), FZero()) || + _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)), FZero())); +} + +PX_FORCE_INLINE bool hasZeroElementInVec4V(const Vec4V a) +{ + return (_mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)), FZero()) || + _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)), FZero()) || + _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)), FZero()) || + _mm_comieq_ss(_mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 3, 3, 3)), FZero())); +} + +const PX_ALIGN(16, PxU32 gMaskXYZ[4]) = { 0xffffffff, 0xffffffff, 0xffffffff, 0 }; +} //internalWindowsSimd + +namespace vecMathTests +{ +// PT: this function returns an invalid Vec3V (W!=0.0f) just for unit-testing 'isValidVec3V' +PX_FORCE_INLINE Vec3V getInvalidVec3V() +{ + const float f = 1.0f; + return _mm_load1_ps(&f); +} + +PX_FORCE_INLINE bool allElementsEqualFloatV(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return _mm_comieq_ss(a, b) != 0; +} + +PX_FORCE_INLINE bool allElementsEqualVec3V(const Vec3V a, const Vec3V b) +{ + return V3AllEq(a, b) != 0; +} + +PX_FORCE_INLINE bool allElementsEqualVec4V(const Vec4V a, const Vec4V b) +{ + return V4AllEq(a, b) != 0; +} + +PX_FORCE_INLINE bool allElementsEqualBoolV(const BoolV a, const BoolV b) +{ + return internalWindowsSimd::BAllTrue4_R(VecI32V_IsEq(a, b)) != 0; +} + +PX_FORCE_INLINE bool allElementsEqualVecU32V(const VecU32V a, const VecU32V b) +{ + return internalWindowsSimd::BAllTrue4_R(V4IsEqU32(a, b)) != 0; +} + +PX_FORCE_INLINE bool allElementsEqualVecI32V(const VecI32V a, const VecI32V b) +{ + BoolV c = internalWindowsSimd::m128_I2F( + _mm_cmpeq_epi32(internalWindowsSimd::m128_F2I(a), internalWindowsSimd::m128_F2I(b))); + return internalWindowsSimd::BAllTrue4_R(c) != 0; +} + +#define VECMATH_AOS_EPSILON (1e-3f) +static const FloatV minFError = FLoad(-VECMATH_AOS_EPSILON); +static const FloatV maxFError = FLoad(VECMATH_AOS_EPSILON); +static const Vec3V minV3Error = V3Load(-VECMATH_AOS_EPSILON); +static const Vec3V maxV3Error = V3Load(VECMATH_AOS_EPSILON); +static const Vec4V minV4Error = V4Load(-VECMATH_AOS_EPSILON); +static const Vec4V maxV4Error = V4Load(VECMATH_AOS_EPSILON); + +PX_FORCE_INLINE bool allElementsNearEqualFloatV(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + const FloatV c = FSub(a, b); + return _mm_comigt_ss(c, minFError) && _mm_comilt_ss(c, maxFError); +} + +PX_FORCE_INLINE bool allElementsNearEqualVec3V(const Vec3V a, const Vec3V b) +{ + const Vec3V c = V3Sub(a, b); + return (_mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(0, 0, 0, 0)), minV3Error) && + _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(0, 0, 0, 0)), maxV3Error) && + _mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(1, 1, 1, 1)), minV3Error) && + _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(1, 1, 1, 1)), maxV3Error) && + _mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(2, 2, 2, 2)), minV3Error) && + _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(2, 2, 2, 2)), maxV3Error)); +} + +PX_FORCE_INLINE bool allElementsNearEqualVec4V(const Vec4V a, const Vec4V b) +{ + const Vec4V c = V4Sub(a, b); + return (_mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(0, 0, 0, 0)), minV4Error) && + _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(0, 0, 0, 0)), maxV4Error) && + _mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(1, 1, 1, 1)), minV4Error) && + _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(1, 1, 1, 1)), maxV4Error) && + _mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(2, 2, 2, 2)), minV4Error) && + _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(2, 2, 2, 2)), maxV4Error) && + _mm_comigt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(3, 3, 3, 3)), minV4Error) && + _mm_comilt_ss(_mm_shuffle_ps(c, c, _MM_SHUFFLE(3, 3, 3, 3)), maxV4Error)); +} +} //vecMathTests + +PX_FORCE_INLINE bool isFiniteFloatV(const FloatV a) +{ + PxF32 f; + FStore(a, &f); + return PxIsFinite(f); + /* + const PxU32 badNumber = (_FPCLASS_SNAN | _FPCLASS_QNAN | _FPCLASS_NINF | _FPCLASS_PINF); + const FloatV vBadNum = FloatV_From_F32((PxF32&)badNumber); + const BoolV vMask = BAnd(vBadNum, a); + return FiniteTestEq(vMask, BFFFF()) == 1; + */ +} + +PX_FORCE_INLINE bool isFiniteVec3V(const Vec3V a) +{ + PX_ALIGN(16, PxF32 f[4]); + V4StoreA((Vec4V&)a, f); + return PxIsFinite(f[0]) && PxIsFinite(f[1]) && PxIsFinite(f[2]); + + /* + const PxU32 badNumber = (_FPCLASS_SNAN | _FPCLASS_QNAN | _FPCLASS_NINF | _FPCLASS_PINF); + const Vec3V vBadNum = Vec3V_From_F32((PxF32&)badNumber); + const BoolV vMask = BAnd(BAnd(vBadNum, a), BTTTF()); + return FiniteTestEq(vMask, BFFFF()) == 1; + */ +} + +PX_FORCE_INLINE bool isFiniteVec4V(const Vec4V a) +{ + PX_ALIGN(16, PxF32 f[4]); + V4StoreA(a, f); + return PxIsFinite(f[0]) && PxIsFinite(f[1]) && PxIsFinite(f[2]) && PxIsFinite(f[3]); + + /* + const PxU32 badNumber = (_FPCLASS_SNAN | _FPCLASS_QNAN | _FPCLASS_NINF | _FPCLASS_PINF); + const Vec4V vBadNum = Vec4V_From_U32((PxF32&)badNumber); + const BoolV vMask = BAnd(vBadNum, a); + + return FiniteTestEq(vMask, BFFFF()) == 1; + */ +} + +///////////////////////////////////////////////////////////////////// +////VECTORISED FUNCTION IMPLEMENTATIONS +///////////////////////////////////////////////////////////////////// + +PX_FORCE_INLINE FloatV FLoad(const PxF32 f) +{ + return _mm_load1_ps(&f); +} + +PX_FORCE_INLINE Vec3V V3Load(const PxF32 f) +{ + return _mm_set_ps(0.0f, f, f, f); +} + +PX_FORCE_INLINE Vec4V V4Load(const PxF32 f) +{ + return _mm_load1_ps(&f); +} + +PX_FORCE_INLINE BoolV BLoad(const bool f) +{ + const PxU32 i = PxU32(-(PxI32)f); + return _mm_load1_ps((float*)&i); +} + +PX_FORCE_INLINE Vec3V V3LoadA(const PxVec3& f) +{ + ASSERT_ISALIGNED16(&f); + return _mm_and_ps(_mm_load_ps(&f.x), reinterpret_cast(internalWindowsSimd::gMaskXYZ)); +} + +PX_FORCE_INLINE Vec3V V3LoadU(const PxVec3& f) +{ + return _mm_set_ps(0.0f, f.z, f.y, f.x); +} + +// w component of result is undefined +PX_FORCE_INLINE Vec3V V3LoadUnsafeA(const PxVec3& f) +{ + ASSERT_ISALIGNED16(&f); + return _mm_load_ps(&f.x); +} + +PX_FORCE_INLINE Vec3V V3LoadA(const PxF32* const f) +{ + ASSERT_ISALIGNED16(f); + return V4ClearW(_mm_load_ps(f)); +} + +PX_FORCE_INLINE Vec3V V3LoadU(const PxF32* const i) +{ + return _mm_set_ps(0.0f, i[2], i[1], i[0]); +} + +PX_FORCE_INLINE Vec3V Vec3V_From_Vec4V(Vec4V v) +{ + return V4ClearW(v); +} + +PX_FORCE_INLINE Vec3V Vec3V_From_Vec4V_WUndefined(const Vec4V v) +{ + return v; +} + +PX_FORCE_INLINE Vec4V Vec4V_From_Vec3V(Vec3V f) +{ + return f; // ok if it is implemented as the same type. +} + +PX_FORCE_INLINE Vec4V Vec4V_From_FloatV(FloatV f) +{ + return f; +} + +PX_FORCE_INLINE Vec3V Vec3V_From_FloatV(FloatV f) +{ + return Vec3V_From_Vec4V(Vec4V_From_FloatV(f)); +} + +PX_FORCE_INLINE Vec3V Vec3V_From_FloatV_WUndefined(FloatV f) +{ + return Vec3V_From_Vec4V_WUndefined(Vec4V_From_FloatV(f)); +} + +PX_FORCE_INLINE Vec4V Vec4V_From_PxVec3_WUndefined(const PxVec3& f) +{ + return _mm_set_ps(0.0f, f.z, f.y, f.x); +} + +PX_FORCE_INLINE Vec4V V4LoadA(const PxF32* const f) +{ + ASSERT_ISALIGNED16(f); + return _mm_load_ps(f); +} + +PX_FORCE_INLINE void V4StoreA(const Vec4V a, PxF32* f) +{ + ASSERT_ISALIGNED16(f); + _mm_store_ps(f, a); +} + +PX_FORCE_INLINE void V4StoreU(const Vec4V a, PxF32* f) +{ + _mm_storeu_ps(f, a); +} + +PX_FORCE_INLINE void BStoreA(const BoolV a, PxU32* f) +{ + ASSERT_ISALIGNED16(f); + _mm_store_ps((PxF32*)f, a); +} + +PX_FORCE_INLINE void U4StoreA(const VecU32V uv, PxU32* u) +{ + ASSERT_ISALIGNED16(u); + _mm_store_ps((PxF32*)u, uv); +} + +PX_FORCE_INLINE void I4StoreA(const VecI32V iv, PxI32* i) +{ + ASSERT_ISALIGNED16(i); + _mm_store_ps((PxF32*)i, iv); +} + +PX_FORCE_INLINE Vec4V V4LoadU(const PxF32* const f) +{ + return _mm_loadu_ps(f); +} + +PX_FORCE_INLINE BoolV BLoad(const bool* const f) +{ + const PX_ALIGN(16, PxU32 b[4]) = { PxU32(-(PxI32)f[0]), PxU32(-(PxI32)f[1]), + PxU32(-(PxI32)f[2]), PxU32(-(PxI32)f[3]) }; + return _mm_load_ps((float*)&b); +} + +PX_FORCE_INLINE void FStore(const FloatV a, PxF32* PX_RESTRICT f) +{ + ASSERT_ISVALIDFLOATV(a); + _mm_store_ss(f, a); +} + +PX_FORCE_INLINE void V3StoreA(const Vec3V a, PxVec3& f) +{ + ASSERT_ISALIGNED16(&f); + PX_ALIGN(16, PxF32 f2[4]); + _mm_store_ps(f2, a); + f = PxVec3(f2[0], f2[1], f2[2]); +} + +PX_FORCE_INLINE void Store_From_BoolV(const BoolV b, PxU32* b2) +{ + _mm_store_ss((PxF32*)b2, b); +} + +PX_FORCE_INLINE void V3StoreU(const Vec3V a, PxVec3& f) +{ + PX_ALIGN(16, PxF32 f2[4]); + _mm_store_ps(f2, a); + f = PxVec3(f2[0], f2[1], f2[2]); +} + +PX_FORCE_INLINE Mat33V Mat33V_From_PxMat33(const PxMat33& m) +{ + return Mat33V(V3LoadU(m.column0), V3LoadU(m.column1), V3LoadU(m.column2)); +} + +PX_FORCE_INLINE void PxMat33_From_Mat33V(const Mat33V& m, PxMat33& out) +{ + ASSERT_ISALIGNED16(&out); + V3StoreU(m.col0, out.column0); + V3StoreU(m.col1, out.column1); + V3StoreU(m.col2, out.column2); +} + +////////////////////////////////// +// FLOATV +////////////////////////////////// + +PX_FORCE_INLINE FloatV FZero() +{ + return _mm_setzero_ps(); +} + +PX_FORCE_INLINE FloatV FOne() +{ + return FLoad(1.0f); +} + +PX_FORCE_INLINE FloatV FHalf() +{ + return FLoad(0.5f); +} + +PX_FORCE_INLINE FloatV FEps() +{ + return FLoad(PX_EPS_REAL); +} + +PX_FORCE_INLINE FloatV FEps6() +{ + return FLoad(1e-6f); +} + +PX_FORCE_INLINE FloatV FMax() +{ + return FLoad(PX_MAX_REAL); +} + +PX_FORCE_INLINE FloatV FNegMax() +{ + return FLoad(-PX_MAX_REAL); +} + +PX_FORCE_INLINE FloatV IZero() +{ + const PxU32 zero = 0; + return _mm_load1_ps((PxF32*)&zero); +} + +PX_FORCE_INLINE FloatV IOne() +{ + const PxU32 one = 1; + return _mm_load1_ps((PxF32*)&one); +} + +PX_FORCE_INLINE FloatV ITwo() +{ + const PxU32 two = 2; + return _mm_load1_ps((PxF32*)&two); +} + +PX_FORCE_INLINE FloatV IThree() +{ + const PxU32 three = 3; + return _mm_load1_ps((PxF32*)&three); +} + +PX_FORCE_INLINE FloatV IFour() +{ + const PxU32 four = 4; + return _mm_load1_ps((PxF32*)&four); +} + +PX_FORCE_INLINE FloatV FNeg(const FloatV f) +{ + ASSERT_ISVALIDFLOATV(f); + return _mm_sub_ps(_mm_setzero_ps(), f); +} + +PX_FORCE_INLINE FloatV FAdd(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return _mm_add_ps(a, b); +} + +PX_FORCE_INLINE FloatV FSub(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return _mm_sub_ps(a, b); +} + +PX_FORCE_INLINE FloatV FMul(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return _mm_mul_ps(a, b); +} + +PX_FORCE_INLINE FloatV FDiv(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return _mm_div_ps(a, b); +} + +PX_FORCE_INLINE FloatV FDivFast(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return _mm_mul_ps(a, _mm_rcp_ps(b)); +} + +PX_FORCE_INLINE FloatV FRecip(const FloatV a) +{ + ASSERT_ISVALIDFLOATV(a); + return _mm_div_ps(FOne(), a); +} + +PX_FORCE_INLINE FloatV FRecipFast(const FloatV a) +{ + return _mm_rcp_ps(a); +} + +PX_FORCE_INLINE FloatV FRsqrt(const FloatV a) +{ + ASSERT_ISVALIDFLOATV(a); + return _mm_div_ps(FOne(), _mm_sqrt_ps(a)); +} + +PX_FORCE_INLINE FloatV FSqrt(const FloatV a) +{ + ASSERT_ISVALIDFLOATV(a); + return _mm_sqrt_ps(a); +} + +PX_FORCE_INLINE FloatV FRsqrtFast(const FloatV a) +{ + ASSERT_ISVALIDFLOATV(a); + return _mm_rsqrt_ps(a); +} + +PX_FORCE_INLINE FloatV FScaleAdd(const FloatV a, const FloatV b, const FloatV c) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + ASSERT_ISVALIDFLOATV(c); + return FAdd(FMul(a, b), c); +} + +PX_FORCE_INLINE FloatV FNegScaleSub(const FloatV a, const FloatV b, const FloatV c) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + ASSERT_ISVALIDFLOATV(c); + return FSub(c, FMul(a, b)); +} + +PX_FORCE_INLINE FloatV FAbs(const FloatV a) +{ + ASSERT_ISVALIDFLOATV(a); + PX_ALIGN(16, const static PxU32 absMask[4]) = { 0x7fFFffFF, 0x7fFFffFF, 0x7fFFffFF, 0x7fFFffFF }; + return _mm_and_ps(a, _mm_load_ps((PxF32*)absMask)); +} + +PX_FORCE_INLINE FloatV FSel(const BoolV c, const FloatV a, const FloatV b) +{ + PX_ASSERT(vecMathTests::allElementsEqualBoolV(c, BTTTT()) || + vecMathTests::allElementsEqualBoolV(c, BFFFF())); + ASSERT_ISVALIDFLOATV(_mm_or_ps(_mm_andnot_ps(c, b), _mm_and_ps(c, a))); + return _mm_or_ps(_mm_andnot_ps(c, b), _mm_and_ps(c, a)); +} + +PX_FORCE_INLINE BoolV FIsGrtr(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return _mm_cmpgt_ps(a, b); +} + +PX_FORCE_INLINE BoolV FIsGrtrOrEq(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return _mm_cmpge_ps(a, b); +} + +PX_FORCE_INLINE BoolV FIsEq(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return _mm_cmpeq_ps(a, b); +} + +PX_FORCE_INLINE FloatV FMax(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return _mm_max_ps(a, b); +} + +PX_FORCE_INLINE FloatV FMin(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return _mm_min_ps(a, b); +} + +PX_FORCE_INLINE FloatV FClamp(const FloatV a, const FloatV minV, const FloatV maxV) +{ + ASSERT_ISVALIDFLOATV(minV); + ASSERT_ISVALIDFLOATV(maxV); + return _mm_max_ps(_mm_min_ps(a, maxV), minV); +} + +PX_FORCE_INLINE PxU32 FAllGrtr(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return PxU32(_mm_comigt_ss(a, b)); +} + +PX_FORCE_INLINE PxU32 FAllGrtrOrEq(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return PxU32(_mm_comige_ss(a, b)); +} + +PX_FORCE_INLINE PxU32 FAllEq(const FloatV a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(b); + return PxU32(_mm_comieq_ss(a, b)); +} + +PX_FORCE_INLINE FloatV FRound(const FloatV a) +{ + ASSERT_ISVALIDFLOATV(a); + // return _mm_round_ps(a, 0x0); + const FloatV half = FLoad(0.5f); + const __m128 signBit = _mm_cvtepi32_ps(_mm_srli_epi32(_mm_cvtps_epi32(a), 31)); + const FloatV aRound = FSub(FAdd(a, half), signBit); + __m128i tmp = _mm_cvttps_epi32(aRound); + return _mm_cvtepi32_ps(tmp); +} + +PX_FORCE_INLINE FloatV FSin(const FloatV a) +{ + ASSERT_ISVALIDFLOATV(a); + // Modulo the range of the given angles such that -XM_2PI <= Angles < XM_2PI + const FloatV recipTwoPi = V4LoadA(g_PXReciprocalTwoPi.f); + const FloatV twoPi = V4LoadA(g_PXTwoPi.f); + const FloatV tmp = FMul(a, recipTwoPi); + const FloatV b = FRound(tmp); + const FloatV V1 = FNegScaleSub(twoPi, b, a); + + // sin(V) ~= V - V^3 / 3! + V^5 / 5! - V^7 / 7! + V^9 / 9! - V^11 / 11! + V^13 / 13! - + // V^15 / 15! + V^17 / 17! - V^19 / 19! + V^21 / 21! - V^23 / 23! (for -PI <= V < PI) + const FloatV V2 = FMul(V1, V1); + const FloatV V3 = FMul(V2, V1); + const FloatV V5 = FMul(V3, V2); + const FloatV V7 = FMul(V5, V2); + const FloatV V9 = FMul(V7, V2); + const FloatV V11 = FMul(V9, V2); + const FloatV V13 = FMul(V11, V2); + const FloatV V15 = FMul(V13, V2); + const FloatV V17 = FMul(V15, V2); + const FloatV V19 = FMul(V17, V2); + const FloatV V21 = FMul(V19, V2); + const FloatV V23 = FMul(V21, V2); + + const Vec4V sinCoefficients0 = V4LoadA(g_PXSinCoefficients0.f); + const Vec4V sinCoefficients1 = V4LoadA(g_PXSinCoefficients1.f); + const Vec4V sinCoefficients2 = V4LoadA(g_PXSinCoefficients2.f); + + const FloatV S1 = V4GetY(sinCoefficients0); + const FloatV S2 = V4GetZ(sinCoefficients0); + const FloatV S3 = V4GetW(sinCoefficients0); + const FloatV S4 = V4GetX(sinCoefficients1); + const FloatV S5 = V4GetY(sinCoefficients1); + const FloatV S6 = V4GetZ(sinCoefficients1); + const FloatV S7 = V4GetW(sinCoefficients1); + const FloatV S8 = V4GetX(sinCoefficients2); + const FloatV S9 = V4GetY(sinCoefficients2); + const FloatV S10 = V4GetZ(sinCoefficients2); + const FloatV S11 = V4GetW(sinCoefficients2); + + FloatV Result; + Result = FScaleAdd(S1, V3, V1); + Result = FScaleAdd(S2, V5, Result); + Result = FScaleAdd(S3, V7, Result); + Result = FScaleAdd(S4, V9, Result); + Result = FScaleAdd(S5, V11, Result); + Result = FScaleAdd(S6, V13, Result); + Result = FScaleAdd(S7, V15, Result); + Result = FScaleAdd(S8, V17, Result); + Result = FScaleAdd(S9, V19, Result); + Result = FScaleAdd(S10, V21, Result); + Result = FScaleAdd(S11, V23, Result); + + return Result; +} + +PX_FORCE_INLINE FloatV FCos(const FloatV a) +{ + ASSERT_ISVALIDFLOATV(a); + + // Modulo the range of the given angles such that -XM_2PI <= Angles < XM_2PI + const FloatV recipTwoPi = V4LoadA(g_PXReciprocalTwoPi.f); + const FloatV twoPi = V4LoadA(g_PXTwoPi.f); + const FloatV tmp = FMul(a, recipTwoPi); + const FloatV b = FRound(tmp); + const FloatV V1 = FNegScaleSub(twoPi, b, a); + + // cos(V) ~= 1 - V^2 / 2! + V^4 / 4! - V^6 / 6! + V^8 / 8! - V^10 / 10! + V^12 / 12! - + // V^14 / 14! + V^16 / 16! - V^18 / 18! + V^20 / 20! - V^22 / 22! (for -PI <= V < PI) + const FloatV V2 = FMul(V1, V1); + const FloatV V4 = FMul(V2, V2); + const FloatV V6 = FMul(V4, V2); + const FloatV V8 = FMul(V4, V4); + const FloatV V10 = FMul(V6, V4); + const FloatV V12 = FMul(V6, V6); + const FloatV V14 = FMul(V8, V6); + const FloatV V16 = FMul(V8, V8); + const FloatV V18 = FMul(V10, V8); + const FloatV V20 = FMul(V10, V10); + const FloatV V22 = FMul(V12, V10); + + const Vec4V cosCoefficients0 = V4LoadA(g_PXCosCoefficients0.f); + const Vec4V cosCoefficients1 = V4LoadA(g_PXCosCoefficients1.f); + const Vec4V cosCoefficients2 = V4LoadA(g_PXCosCoefficients2.f); + + const FloatV C1 = V4GetY(cosCoefficients0); + const FloatV C2 = V4GetZ(cosCoefficients0); + const FloatV C3 = V4GetW(cosCoefficients0); + const FloatV C4 = V4GetX(cosCoefficients1); + const FloatV C5 = V4GetY(cosCoefficients1); + const FloatV C6 = V4GetZ(cosCoefficients1); + const FloatV C7 = V4GetW(cosCoefficients1); + const FloatV C8 = V4GetX(cosCoefficients2); + const FloatV C9 = V4GetY(cosCoefficients2); + const FloatV C10 = V4GetZ(cosCoefficients2); + const FloatV C11 = V4GetW(cosCoefficients2); + + FloatV Result; + Result = FScaleAdd(C1, V2, V4One()); + Result = FScaleAdd(C2, V4, Result); + Result = FScaleAdd(C3, V6, Result); + Result = FScaleAdd(C4, V8, Result); + Result = FScaleAdd(C5, V10, Result); + Result = FScaleAdd(C6, V12, Result); + Result = FScaleAdd(C7, V14, Result); + Result = FScaleAdd(C8, V16, Result); + Result = FScaleAdd(C9, V18, Result); + Result = FScaleAdd(C10, V20, Result); + Result = FScaleAdd(C11, V22, Result); + + return Result; +} + +PX_FORCE_INLINE PxU32 FOutOfBounds(const FloatV a, const FloatV min, const FloatV max) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(min); + ASSERT_ISVALIDFLOATV(max); + const BoolV c = BOr(FIsGrtr(a, max), FIsGrtr(min, a)); + return PxU32(!BAllEqFFFF(c)); +} + +PX_FORCE_INLINE PxU32 FInBounds(const FloatV a, const FloatV min, const FloatV max) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(min); + ASSERT_ISVALIDFLOATV(max); + const BoolV c = BAnd(FIsGrtrOrEq(a, min), FIsGrtrOrEq(max, a)); + return BAllEqTTTT(c); +} + +PX_FORCE_INLINE PxU32 FOutOfBounds(const FloatV a, const FloatV bounds) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(bounds); + return FOutOfBounds(a, FNeg(bounds), bounds); +} + +PX_FORCE_INLINE PxU32 FInBounds(const FloatV a, const FloatV bounds) +{ + ASSERT_ISVALIDFLOATV(a); + ASSERT_ISVALIDFLOATV(bounds); + return FInBounds(a, FNeg(bounds), bounds); +} + +////////////////////////////////// +// VEC3V +////////////////////////////////// + +PX_FORCE_INLINE Vec3V V3Splat(const FloatV f) +{ + ASSERT_ISVALIDFLOATV(f); + const __m128 zero = V3Zero(); + const __m128 fff0 = _mm_move_ss(f, zero); + return _mm_shuffle_ps(fff0, fff0, _MM_SHUFFLE(0, 1, 2, 3)); +} + +PX_FORCE_INLINE Vec3V V3Merge(const FloatVArg x, const FloatVArg y, const FloatVArg z) +{ + ASSERT_ISVALIDFLOATV(x); + ASSERT_ISVALIDFLOATV(y); + ASSERT_ISVALIDFLOATV(z); + // static on zero causes compiler crash on x64 debug_opt + const __m128 zero = V3Zero(); + const __m128 xy = _mm_move_ss(x, y); + const __m128 z0 = _mm_move_ss(zero, z); + + return _mm_shuffle_ps(xy, z0, _MM_SHUFFLE(1, 0, 0, 1)); +} + +PX_FORCE_INLINE Vec3V V3UnitX() +{ + const PX_ALIGN(16, PxF32 x[4]) = { 1.0f, 0.0f, 0.0f, 0.0f }; + const __m128 x128 = _mm_load_ps(x); + return x128; +} + +PX_FORCE_INLINE Vec3V V3UnitY() +{ + const PX_ALIGN(16, PxF32 y[4]) = { 0.0f, 1.0f, 0.0f, 0.0f }; + const __m128 y128 = _mm_load_ps(y); + return y128; +} + +PX_FORCE_INLINE Vec3V V3UnitZ() +{ + const PX_ALIGN(16, PxF32 z[4]) = { 0.0f, 0.0f, 1.0f, 0.0f }; + const __m128 z128 = _mm_load_ps(z); + return z128; +} + +PX_FORCE_INLINE FloatV V3GetX(const Vec3V f) +{ + ASSERT_ISVALIDVEC3V(f); + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(0, 0, 0, 0)); +} + +PX_FORCE_INLINE FloatV V3GetY(const Vec3V f) +{ + ASSERT_ISVALIDVEC3V(f); + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(1, 1, 1, 1)); +} + +PX_FORCE_INLINE FloatV V3GetZ(const Vec3V f) +{ + ASSERT_ISVALIDVEC3V(f); + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(2, 2, 2, 2)); +} + +PX_FORCE_INLINE Vec3V V3SetX(const Vec3V v, const FloatV f) +{ + ASSERT_ISVALIDVEC3V(v); + ASSERT_ISVALIDFLOATV(f); + return V4Sel(BFTTT(), v, f); +} + +PX_FORCE_INLINE Vec3V V3SetY(const Vec3V v, const FloatV f) +{ + ASSERT_ISVALIDVEC3V(v); + ASSERT_ISVALIDFLOATV(f); + return V4Sel(BTFTT(), v, f); +} + +PX_FORCE_INLINE Vec3V V3SetZ(const Vec3V v, const FloatV f) +{ + ASSERT_ISVALIDVEC3V(v); + ASSERT_ISVALIDFLOATV(f); + return V4Sel(BTTFT(), v, f); +} + +PX_FORCE_INLINE Vec3V V3ColX(const Vec3V a, const Vec3V b, const Vec3V c) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + ASSERT_ISVALIDVEC3V(c); + Vec3V r = _mm_shuffle_ps(a, c, _MM_SHUFFLE(3, 0, 3, 0)); + return V3SetY(r, V3GetX(b)); +} + +PX_FORCE_INLINE Vec3V V3ColY(const Vec3V a, const Vec3V b, const Vec3V c) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + ASSERT_ISVALIDVEC3V(c); + Vec3V r = _mm_shuffle_ps(a, c, _MM_SHUFFLE(3, 1, 3, 1)); + return V3SetY(r, V3GetY(b)); +} + +PX_FORCE_INLINE Vec3V V3ColZ(const Vec3V a, const Vec3V b, const Vec3V c) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + ASSERT_ISVALIDVEC3V(c); + Vec3V r = _mm_shuffle_ps(a, c, _MM_SHUFFLE(3, 2, 3, 2)); + return V3SetY(r, V3GetZ(b)); +} + +PX_FORCE_INLINE Vec3V V3Zero() +{ + return _mm_setzero_ps(); +} + +PX_FORCE_INLINE Vec3V V3One() +{ + return V3Load(1.0f); +} + +PX_FORCE_INLINE Vec3V V3Eps() +{ + return V3Load(PX_EPS_REAL); +} + +PX_FORCE_INLINE Vec3V V3Neg(const Vec3V f) +{ + ASSERT_ISVALIDVEC3V(f); + return _mm_sub_ps(_mm_setzero_ps(), f); +} + +PX_FORCE_INLINE Vec3V V3Add(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return _mm_add_ps(a, b); +} + +PX_FORCE_INLINE Vec3V V3Sub(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return _mm_sub_ps(a, b); +} + +PX_FORCE_INLINE Vec3V V3Scale(const Vec3V a, const FloatV b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDFLOATV(b); + return _mm_mul_ps(a, b); +} + +PX_FORCE_INLINE Vec3V V3Mul(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return _mm_mul_ps(a, b); +} + +PX_FORCE_INLINE Vec3V V3ScaleInv(const Vec3V a, const FloatV b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDFLOATV(b); + return _mm_div_ps(a, b); +} + +PX_FORCE_INLINE Vec3V V3Div(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return V4ClearW(_mm_div_ps(a, b)); +} + +PX_FORCE_INLINE Vec3V V3ScaleInvFast(const Vec3V a, const FloatV b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDFLOATV(b); + return _mm_mul_ps(a, _mm_rcp_ps(b)); +} + +PX_FORCE_INLINE Vec3V V3DivFast(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return V4ClearW(_mm_mul_ps(a, _mm_rcp_ps(b))); +} + +PX_FORCE_INLINE Vec3V V3Recip(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + const __m128 zero = V3Zero(); + const __m128 tttf = BTTTF(); + const __m128 recipA = _mm_div_ps(V3One(), a); + return V4Sel(tttf, recipA, zero); +} + +PX_FORCE_INLINE Vec3V V3RecipFast(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + const __m128 zero = V3Zero(); + const __m128 tttf = BTTTF(); + const __m128 recipA = _mm_rcp_ps(a); + return V4Sel(tttf, recipA, zero); +} + +PX_FORCE_INLINE Vec3V V3Rsqrt(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + const __m128 zero = V3Zero(); + const __m128 tttf = BTTTF(); + const __m128 recipA = _mm_div_ps(V3One(), _mm_sqrt_ps(a)); + return V4Sel(tttf, recipA, zero); +} + +PX_FORCE_INLINE Vec3V V3RsqrtFast(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + const __m128 zero = V3Zero(); + const __m128 tttf = BTTTF(); + const __m128 recipA = _mm_rsqrt_ps(a); + return V4Sel(tttf, recipA, zero); +} + +PX_FORCE_INLINE Vec3V V3ScaleAdd(const Vec3V a, const FloatV b, const Vec3V c) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDFLOATV(b); + ASSERT_ISVALIDVEC3V(c); + return V3Add(V3Scale(a, b), c); +} + +PX_FORCE_INLINE Vec3V V3NegScaleSub(const Vec3V a, const FloatV b, const Vec3V c) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDFLOATV(b); + ASSERT_ISVALIDVEC3V(c); + return V3Sub(c, V3Scale(a, b)); +} + +PX_FORCE_INLINE Vec3V V3MulAdd(const Vec3V a, const Vec3V b, const Vec3V c) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + ASSERT_ISVALIDVEC3V(c); + return V3Add(V3Mul(a, b), c); +} + +PX_FORCE_INLINE Vec3V V3NegMulSub(const Vec3V a, const Vec3V b, const Vec3V c) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + ASSERT_ISVALIDVEC3V(c); + return V3Sub(c, V3Mul(a, b)); +} + +PX_FORCE_INLINE Vec3V V3Abs(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + return V3Max(a, V3Neg(a)); +} + +PX_FORCE_INLINE FloatV V3Dot(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + + const __m128 t0 = _mm_mul_ps(a, b); // aw*bw | az*bz | ay*by | ax*bx + const __m128 t1 = _mm_shuffle_ps(t0, t0, _MM_SHUFFLE(1,0,3,2)); // ay*by | ax*bx | aw*bw | az*bz + const __m128 t2 = _mm_add_ps(t0, t1); // ay*by + aw*bw | ax*bx + az*bz | aw*bw + ay*by | az*bz + ax*bx + const __m128 t3 = _mm_shuffle_ps(t2, t2, _MM_SHUFFLE(2,3,0,1)); // ax*bx + az*bz | ay*by + aw*bw | az*bz + ax*bx | aw*bw + ay*by + return _mm_add_ps(t3, t2); // ax*bx + az*bz + ay*by + aw*bw + // ay*by + aw*bw + ax*bx + az*bz + // az*bz + ax*bx + aw*bw + ay*by + // aw*bw + ay*by + az*bz + ax*bx +} + +PX_FORCE_INLINE Vec3V V3Cross(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); +/* if(0) + { + const __m128 r1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 1, 0, 2)); // z,x,y,w + const __m128 r2 = _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 0, 2, 1)); // y,z,x,w + const __m128 l1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 2, 1)); // y,z,x,w + const __m128 l2 = _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 1, 0, 2)); // z,x,y,w + return _mm_sub_ps(_mm_mul_ps(l1, l2), _mm_mul_ps(r1, r2)); + } + else*/ + { + const __m128 b0 = _mm_shuffle_ps(b, b, _MM_SHUFFLE(3,0,2,1)); + const __m128 a1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(3,0,2,1)); + __m128 v = _mm_mul_ps(a1, b); + v = _mm_sub_ps(_mm_mul_ps(a, b0), v); + __m128 res = _mm_shuffle_ps(v, v, _MM_SHUFFLE(3,0,2,1)); + ASSERT_ISVALIDVEC3V(res); + return res; + } +} + +PX_FORCE_INLINE VecCrossV V3PrepareCross(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + VecCrossV v; + v.mR1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 1, 0, 2)); // z,x,y,w + v.mL1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 2, 1)); // y,z,x,w + return v; +} + +PX_FORCE_INLINE Vec3V V3Cross(const VecCrossV& a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(b); + const __m128 r2 = _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 0, 2, 1)); // y,z,x,w + const __m128 l2 = _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 1, 0, 2)); // z,x,y,w + return _mm_sub_ps(_mm_mul_ps(a.mL1, l2), _mm_mul_ps(a.mR1, r2)); +} + +PX_FORCE_INLINE Vec3V V3Cross(const Vec3V a, const VecCrossV& b) +{ + ASSERT_ISVALIDVEC3V(a); + const __m128 r2 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 2, 1)); // y,z,x,w + const __m128 l2 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 1, 0, 2)); // z,x,y,w + return _mm_sub_ps(_mm_mul_ps(b.mR1, r2), _mm_mul_ps(b.mL1, l2)); +} + +PX_FORCE_INLINE Vec3V V3Cross(const VecCrossV& a, const VecCrossV& b) +{ + return _mm_sub_ps(_mm_mul_ps(a.mL1, b.mR1), _mm_mul_ps(a.mR1, b.mL1)); +} + +PX_FORCE_INLINE FloatV V3Length(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + return _mm_sqrt_ps(V3Dot(a, a)); +} + +PX_FORCE_INLINE FloatV V3LengthSq(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + return V3Dot(a, a); +} + +PX_FORCE_INLINE Vec3V V3Normalize(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISFINITELENGTH(a); + return V3ScaleInv(a, _mm_sqrt_ps(V3Dot(a, a))); +} + +PX_FORCE_INLINE Vec3V V3NormalizeFast(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISFINITELENGTH(a); + return V3Scale(a, _mm_rsqrt_ps(V3Dot(a, a))); +} + +PX_FORCE_INLINE Vec3V V3NormalizeSafe(const Vec3V a, const Vec3V unsafeReturnValue) +{ + ASSERT_ISVALIDVEC3V(a); + const __m128 eps = FEps(); + const __m128 length = V3Length(a); + const __m128 isGreaterThanZero = FIsGrtr(length, eps); + return V3Sel(isGreaterThanZero, V3ScaleInv(a, length), unsafeReturnValue); +} + +PX_FORCE_INLINE Vec3V V3Sel(const BoolV c, const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(_mm_or_ps(_mm_andnot_ps(c, b), _mm_and_ps(c, a))); + return _mm_or_ps(_mm_andnot_ps(c, b), _mm_and_ps(c, a)); +} + +PX_FORCE_INLINE BoolV V3IsGrtr(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return _mm_cmpgt_ps(a, b); +} + +PX_FORCE_INLINE BoolV V3IsGrtrOrEq(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return _mm_cmpge_ps(a, b); +} + +PX_FORCE_INLINE BoolV V3IsEq(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return _mm_cmpeq_ps(a, b); +} + +PX_FORCE_INLINE Vec3V V3Max(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return _mm_max_ps(a, b); +} + +PX_FORCE_INLINE Vec3V V3Min(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return _mm_min_ps(a, b); +} + +PX_FORCE_INLINE FloatV V3ExtractMax(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + const __m128 shuf1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)); + const __m128 shuf2 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)); + const __m128 shuf3 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)); + return _mm_max_ps(_mm_max_ps(shuf1, shuf2), shuf3); +} + +PX_FORCE_INLINE FloatV V3ExtractMin(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + const __m128 shuf1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)); + const __m128 shuf2 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)); + const __m128 shuf3 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)); + return _mm_min_ps(_mm_min_ps(shuf1, shuf2), shuf3); +} + +//// if(a > 0.0f) return 1.0f; else if a == 0.f return 0.f, else return -1.f; +// PX_FORCE_INLINE Vec3V V3MathSign(const Vec3V a) +//{ +// VECMATHAOS_ASSERT(isValidVec3V(a)); +// +// const __m128i ai = _mm_cvtps_epi32(a); +// const __m128i bi = _mm_cvtps_epi32(V3Neg(a)); +// const __m128 aa = _mm_cvtepi32_ps(_mm_srai_epi32(ai, 31)); +// const __m128 bb = _mm_cvtepi32_ps(_mm_srai_epi32(bi, 31)); +// return _mm_or_ps(aa, bb); +//} + +// return (a >= 0.0f) ? 1.0f : -1.0f; +PX_FORCE_INLINE Vec3V V3Sign(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + const __m128 zero = V3Zero(); + const __m128 one = V3One(); + const __m128 none = V3Neg(one); + return V3Sel(V3IsGrtrOrEq(a, zero), one, none); +} + +PX_FORCE_INLINE Vec3V V3Clamp(const Vec3V a, const Vec3V minV, const Vec3V maxV) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(minV); + ASSERT_ISVALIDVEC3V(maxV); + return V3Max(V3Min(a, maxV), minV); +} + +PX_FORCE_INLINE PxU32 V3AllGrtr(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return internalWindowsSimd::BAllTrue3_R(V4IsGrtr(a, b)); +} + +PX_FORCE_INLINE PxU32 V3AllGrtrOrEq(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return internalWindowsSimd::BAllTrue3_R(V4IsGrtrOrEq(a, b)); +} + +PX_FORCE_INLINE PxU32 V3AllEq(const Vec3V a, const Vec3V b) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(b); + return internalWindowsSimd::BAllTrue3_R(V4IsEq(a, b)); +} + +PX_FORCE_INLINE Vec3V V3Round(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + + // return _mm_round_ps(a, 0x0); + const Vec3V half = V3Load(0.5f); + const __m128 signBit = _mm_cvtepi32_ps(_mm_srli_epi32(_mm_cvtps_epi32(a), 31)); + const Vec3V aRound = V3Sub(V3Add(a, half), signBit); + __m128i tmp = _mm_cvttps_epi32(aRound); + return _mm_cvtepi32_ps(tmp); +} + +PX_FORCE_INLINE Vec3V V3Sin(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + + // Modulo the range of the given angles such that -XM_2PI <= Angles < XM_2PI + const Vec4V recipTwoPi = V4LoadA(g_PXReciprocalTwoPi.f); + const Vec4V twoPi = V4LoadA(g_PXTwoPi.f); + const Vec3V tmp = V3Scale(a, recipTwoPi); + const Vec3V b = V3Round(tmp); + const Vec3V V1 = V3NegScaleSub(b, twoPi, a); + + // sin(V) ~= V - V^3 / 3! + V^5 / 5! - V^7 / 7! + V^9 / 9! - V^11 / 11! + V^13 / 13! - + // V^15 / 15! + V^17 / 17! - V^19 / 19! + V^21 / 21! - V^23 / 23! (for -PI <= V < PI) + const Vec3V V2 = V3Mul(V1, V1); + const Vec3V V3 = V3Mul(V2, V1); + const Vec3V V5 = V3Mul(V3, V2); + const Vec3V V7 = V3Mul(V5, V2); + const Vec3V V9 = V3Mul(V7, V2); + const Vec3V V11 = V3Mul(V9, V2); + const Vec3V V13 = V3Mul(V11, V2); + const Vec3V V15 = V3Mul(V13, V2); + const Vec3V V17 = V3Mul(V15, V2); + const Vec3V V19 = V3Mul(V17, V2); + const Vec3V V21 = V3Mul(V19, V2); + const Vec3V V23 = V3Mul(V21, V2); + + const Vec4V sinCoefficients0 = V4LoadA(g_PXSinCoefficients0.f); + const Vec4V sinCoefficients1 = V4LoadA(g_PXSinCoefficients1.f); + const Vec4V sinCoefficients2 = V4LoadA(g_PXSinCoefficients2.f); + + const FloatV S1 = V4GetY(sinCoefficients0); + const FloatV S2 = V4GetZ(sinCoefficients0); + const FloatV S3 = V4GetW(sinCoefficients0); + const FloatV S4 = V4GetX(sinCoefficients1); + const FloatV S5 = V4GetY(sinCoefficients1); + const FloatV S6 = V4GetZ(sinCoefficients1); + const FloatV S7 = V4GetW(sinCoefficients1); + const FloatV S8 = V4GetX(sinCoefficients2); + const FloatV S9 = V4GetY(sinCoefficients2); + const FloatV S10 = V4GetZ(sinCoefficients2); + const FloatV S11 = V4GetW(sinCoefficients2); + + Vec3V Result; + Result = V3ScaleAdd(V3, S1, V1); + Result = V3ScaleAdd(V5, S2, Result); + Result = V3ScaleAdd(V7, S3, Result); + Result = V3ScaleAdd(V9, S4, Result); + Result = V3ScaleAdd(V11, S5, Result); + Result = V3ScaleAdd(V13, S6, Result); + Result = V3ScaleAdd(V15, S7, Result); + Result = V3ScaleAdd(V17, S8, Result); + Result = V3ScaleAdd(V19, S9, Result); + Result = V3ScaleAdd(V21, S10, Result); + Result = V3ScaleAdd(V23, S11, Result); + + ASSERT_ISVALIDVEC3V(Result); + return Result; +} + +PX_FORCE_INLINE Vec3V V3Cos(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + + // Modulo the range of the given angles such that -XM_2PI <= Angles < XM_2PI + const Vec4V recipTwoPi = V4LoadA(g_PXReciprocalTwoPi.f); + const Vec4V twoPi = V4LoadA(g_PXTwoPi.f); + const Vec3V tmp = V3Scale(a, recipTwoPi); + const Vec3V b = V3Round(tmp); + const Vec3V V1 = V3NegScaleSub(b, twoPi, a); + + // cos(V) ~= 1 - V^2 / 2! + V^4 / 4! - V^6 / 6! + V^8 / 8! - V^10 / 10! + V^12 / 12! - + // V^14 / 14! + V^16 / 16! - V^18 / 18! + V^20 / 20! - V^22 / 22! (for -PI <= V < PI) + const Vec3V V2 = V3Mul(V1, V1); + const Vec3V V4 = V3Mul(V2, V2); + const Vec3V V6 = V3Mul(V4, V2); + const Vec3V V8 = V3Mul(V4, V4); + const Vec3V V10 = V3Mul(V6, V4); + const Vec3V V12 = V3Mul(V6, V6); + const Vec3V V14 = V3Mul(V8, V6); + const Vec3V V16 = V3Mul(V8, V8); + const Vec3V V18 = V3Mul(V10, V8); + const Vec3V V20 = V3Mul(V10, V10); + const Vec3V V22 = V3Mul(V12, V10); + + const Vec4V cosCoefficients0 = V4LoadA(g_PXCosCoefficients0.f); + const Vec4V cosCoefficients1 = V4LoadA(g_PXCosCoefficients1.f); + const Vec4V cosCoefficients2 = V4LoadA(g_PXCosCoefficients2.f); + + const FloatV C1 = V4GetY(cosCoefficients0); + const FloatV C2 = V4GetZ(cosCoefficients0); + const FloatV C3 = V4GetW(cosCoefficients0); + const FloatV C4 = V4GetX(cosCoefficients1); + const FloatV C5 = V4GetY(cosCoefficients1); + const FloatV C6 = V4GetZ(cosCoefficients1); + const FloatV C7 = V4GetW(cosCoefficients1); + const FloatV C8 = V4GetX(cosCoefficients2); + const FloatV C9 = V4GetY(cosCoefficients2); + const FloatV C10 = V4GetZ(cosCoefficients2); + const FloatV C11 = V4GetW(cosCoefficients2); + + Vec3V Result; + Result = V3ScaleAdd(V2, C1, V3One()); + Result = V3ScaleAdd(V4, C2, Result); + Result = V3ScaleAdd(V6, C3, Result); + Result = V3ScaleAdd(V8, C4, Result); + Result = V3ScaleAdd(V10, C5, Result); + Result = V3ScaleAdd(V12, C6, Result); + Result = V3ScaleAdd(V14, C7, Result); + Result = V3ScaleAdd(V16, C8, Result); + Result = V3ScaleAdd(V18, C9, Result); + Result = V3ScaleAdd(V20, C10, Result); + Result = V3ScaleAdd(V22, C11, Result); + + ASSERT_ISVALIDVEC3V(Result); + return Result; +} + +PX_FORCE_INLINE Vec3V V3PermYZZ(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 2, 2, 1)); +} + +PX_FORCE_INLINE Vec3V V3PermXYX(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 1, 0)); +} + +PX_FORCE_INLINE Vec3V V3PermYZX(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 2, 1)); +} + +PX_FORCE_INLINE Vec3V V3PermZXY(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 1, 0, 2)); +} + +PX_FORCE_INLINE Vec3V V3PermZZY(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 1, 2, 2)); +} + +PX_FORCE_INLINE Vec3V V3PermYXX(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 0, 1)); +} + +PX_FORCE_INLINE Vec3V V3Perm_Zero_1Z_0Y(const Vec3V v0, const Vec3V v1) +{ + ASSERT_ISVALIDVEC3V(v0); + ASSERT_ISVALIDVEC3V(v1); + return _mm_shuffle_ps(v1, v0, _MM_SHUFFLE(3, 1, 2, 3)); +} + +PX_FORCE_INLINE Vec3V V3Perm_0Z_Zero_1X(const Vec3V v0, const Vec3V v1) +{ + ASSERT_ISVALIDVEC3V(v0); + ASSERT_ISVALIDVEC3V(v1); + return _mm_shuffle_ps(v0, v1, _MM_SHUFFLE(3, 0, 3, 2)); +} + +PX_FORCE_INLINE Vec3V V3Perm_1Y_0X_Zero(const Vec3V v0, const Vec3V v1) +{ + ASSERT_ISVALIDVEC3V(v0); + ASSERT_ISVALIDVEC3V(v1); + // There must be a better way to do this. + Vec3V v2 = V3Zero(); + FloatV y1 = V3GetY(v1); + FloatV x0 = V3GetX(v0); + v2 = V3SetX(v2, y1); + return V3SetY(v2, x0); +} + +PX_FORCE_INLINE FloatV V3SumElems(const Vec3V a) +{ + ASSERT_ISVALIDVEC3V(a); + const __m128 shuf1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)); // z,y,x,w + const __m128 shuf2 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)); // y,x,w,z + const __m128 shuf3 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)); // x,w,z,y + return _mm_add_ps(_mm_add_ps(shuf1, shuf2), shuf3); +} + +PX_FORCE_INLINE PxU32 V3OutOfBounds(const Vec3V a, const Vec3V min, const Vec3V max) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(min); + ASSERT_ISVALIDVEC3V(max); + const BoolV c = BOr(V3IsGrtr(a, max), V3IsGrtr(min, a)); + return PxU32(!BAllEqFFFF(c)); +} + +PX_FORCE_INLINE PxU32 V3InBounds(const Vec3V a, const Vec3V min, const Vec3V max) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(min); + ASSERT_ISVALIDVEC3V(max); + const BoolV c = BAnd(V3IsGrtrOrEq(a, min), V3IsGrtrOrEq(max, a)); + return BAllEqTTTT(c); +} + +PX_FORCE_INLINE PxU32 V3OutOfBounds(const Vec3V a, const Vec3V bounds) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(bounds); + return V3OutOfBounds(a, V3Neg(bounds), bounds); +} + +PX_FORCE_INLINE PxU32 V3InBounds(const Vec3V a, const Vec3V bounds) +{ + ASSERT_ISVALIDVEC3V(a); + ASSERT_ISVALIDVEC3V(bounds); + return V3InBounds(a, V3Neg(bounds), bounds); +} + +PX_FORCE_INLINE void V3Transpose(Vec3V& col0, Vec3V& col1, Vec3V& col2) +{ + ASSERT_ISVALIDVEC3V(col0); + ASSERT_ISVALIDVEC3V(col1); + ASSERT_ISVALIDVEC3V(col2); + const Vec3V col3 = _mm_setzero_ps(); + Vec3V tmp0 = _mm_unpacklo_ps(col0, col1); + Vec3V tmp2 = _mm_unpacklo_ps(col2, col3); + Vec3V tmp1 = _mm_unpackhi_ps(col0, col1); + Vec3V tmp3 = _mm_unpackhi_ps(col2, col3); + col0 = _mm_movelh_ps(tmp0, tmp2); + col1 = _mm_movehl_ps(tmp2, tmp0); + col2 = _mm_movelh_ps(tmp1, tmp3); +} + +////////////////////////////////// +// VEC4V +////////////////////////////////// + +PX_FORCE_INLINE Vec4V V4Splat(const FloatV f) +{ + ASSERT_ISVALIDFLOATV(f); + // return _mm_shuffle_ps(f, f, _MM_SHUFFLE(0,0,0,0)); + return f; +} + +PX_FORCE_INLINE Vec4V V4Merge(const FloatV* const floatVArray) +{ + ASSERT_ISVALIDFLOATV(floatVArray[0]); + ASSERT_ISVALIDFLOATV(floatVArray[1]); + ASSERT_ISVALIDFLOATV(floatVArray[2]); + ASSERT_ISVALIDFLOATV(floatVArray[3]); + const __m128 xw = _mm_move_ss(floatVArray[1], floatVArray[0]); // y, y, y, x + const __m128 yz = _mm_move_ss(floatVArray[2], floatVArray[3]); // z, z, z, w + return _mm_shuffle_ps(xw, yz, _MM_SHUFFLE(0, 2, 1, 0)); +} + +PX_FORCE_INLINE Vec4V V4Merge(const FloatVArg x, const FloatVArg y, const FloatVArg z, const FloatVArg w) +{ + ASSERT_ISVALIDFLOATV(x); + ASSERT_ISVALIDFLOATV(y); + ASSERT_ISVALIDFLOATV(z); + ASSERT_ISVALIDFLOATV(w); + const __m128 xw = _mm_move_ss(y, x); // y, y, y, x + const __m128 yz = _mm_move_ss(z, w); // z, z, z, w + return _mm_shuffle_ps(xw, yz, _MM_SHUFFLE(0, 2, 1, 0)); +} + +PX_FORCE_INLINE Vec4V V4MergeW(const Vec4VArg x, const Vec4VArg y, const Vec4VArg z, const Vec4VArg w) +{ + const Vec4V xz = _mm_unpackhi_ps(x, z); + const Vec4V yw = _mm_unpackhi_ps(y, w); + return _mm_unpackhi_ps(xz, yw); +} + +PX_FORCE_INLINE Vec4V V4MergeZ(const Vec4VArg x, const Vec4VArg y, const Vec4VArg z, const Vec4VArg w) +{ + const Vec4V xz = _mm_unpackhi_ps(x, z); + const Vec4V yw = _mm_unpackhi_ps(y, w); + return _mm_unpacklo_ps(xz, yw); +} + +PX_FORCE_INLINE Vec4V V4MergeY(const Vec4VArg x, const Vec4VArg y, const Vec4VArg z, const Vec4VArg w) +{ + const Vec4V xz = _mm_unpacklo_ps(x, z); + const Vec4V yw = _mm_unpacklo_ps(y, w); + return _mm_unpackhi_ps(xz, yw); +} + +PX_FORCE_INLINE Vec4V V4MergeX(const Vec4VArg x, const Vec4VArg y, const Vec4VArg z, const Vec4VArg w) +{ + const Vec4V xz = _mm_unpacklo_ps(x, z); + const Vec4V yw = _mm_unpacklo_ps(y, w); + return _mm_unpacklo_ps(xz, yw); +} + +PX_FORCE_INLINE Vec4V V4UnpackXY(const Vec4VArg a, const Vec4VArg b) +{ + return _mm_unpacklo_ps(a, b); +} + +PX_FORCE_INLINE Vec4V V4UnpackZW(const Vec4VArg a, const Vec4VArg b) +{ + return _mm_unpackhi_ps(a, b); +} + +PX_FORCE_INLINE Vec4V V4PermYXWZ(const Vec4V a) +{ + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 3, 0, 1)); +} + +PX_FORCE_INLINE Vec4V V4PermXZXZ(const Vec4V a) +{ + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 0, 2, 0)); +} + +PX_FORCE_INLINE Vec4V V4PermYWYW(const Vec4V a) +{ + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 1, 3, 1)); +} + +PX_FORCE_INLINE Vec4V V4PermYZXW(const Vec4V a) +{ + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 2, 1)); +} + +PX_FORCE_INLINE Vec4V V4PermZWXY(const Vec4V a) +{ + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 0, 3, 2)); +} + +template +PX_FORCE_INLINE Vec4V V4Perm(const Vec4V a) +{ + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(w, z, y, x)); +} + +PX_FORCE_INLINE Vec4V V4UnitW() +{ + const PX_ALIGN(16, PxF32 w[4]) = { 0.0f, 0.0f, 0.0f, 1.0f }; + const __m128 w128 = _mm_load_ps(w); + return w128; +} + +PX_FORCE_INLINE Vec4V V4UnitX() +{ + const PX_ALIGN(16, PxF32 x[4]) = { 1.0f, 0.0f, 0.0f, 0.0f }; + const __m128 x128 = _mm_load_ps(x); + return x128; +} + +PX_FORCE_INLINE Vec4V V4UnitY() +{ + const PX_ALIGN(16, PxF32 y[4]) = { 0.0f, 1.0f, 0.0f, 0.0f }; + const __m128 y128 = _mm_load_ps(y); + return y128; +} + +PX_FORCE_INLINE Vec4V V4UnitZ() +{ + const PX_ALIGN(16, PxF32 z[4]) = { 0.0f, 0.0f, 1.0f, 0.0f }; + const __m128 z128 = _mm_load_ps(z); + return z128; +} + +PX_FORCE_INLINE FloatV V4GetW(const Vec4V f) +{ + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(3, 3, 3, 3)); +} + +PX_FORCE_INLINE FloatV V4GetX(const Vec4V f) +{ + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(0, 0, 0, 0)); +} + +PX_FORCE_INLINE FloatV V4GetY(const Vec4V f) +{ + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(1, 1, 1, 1)); +} + +PX_FORCE_INLINE FloatV V4GetZ(const Vec4V f) +{ + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(2, 2, 2, 2)); +} + +PX_FORCE_INLINE Vec4V V4SetW(const Vec4V v, const FloatV f) +{ + ASSERT_ISVALIDFLOATV(f); + return V4Sel(BTTTF(), v, f); +} + +PX_FORCE_INLINE Vec4V V4ClearW(const Vec4V v) +{ + return _mm_and_ps(v, (VecI32V&)internalWindowsSimd::gMaskXYZ); +} + +PX_FORCE_INLINE Vec4V V4SetX(const Vec4V v, const FloatV f) +{ + ASSERT_ISVALIDFLOATV(f); + return V4Sel(BFTTT(), v, f); +} + +PX_FORCE_INLINE Vec4V V4SetY(const Vec4V v, const FloatV f) +{ + ASSERT_ISVALIDFLOATV(f); + return V4Sel(BTFTT(), v, f); +} + +PX_FORCE_INLINE Vec4V V4SetZ(const Vec4V v, const FloatV f) +{ + ASSERT_ISVALIDFLOATV(f); + return V4Sel(BTTFT(), v, f); +} + +PX_FORCE_INLINE Vec4V V4Zero() +{ + return _mm_setzero_ps(); +} + +PX_FORCE_INLINE Vec4V V4One() +{ + return V4Load(1.0f); +} + +PX_FORCE_INLINE Vec4V V4Eps() +{ + return V4Load(PX_EPS_REAL); +} + +PX_FORCE_INLINE Vec4V V4Neg(const Vec4V f) +{ + return _mm_sub_ps(_mm_setzero_ps(), f); +} + +PX_FORCE_INLINE Vec4V V4Add(const Vec4V a, const Vec4V b) +{ + return _mm_add_ps(a, b); +} + +PX_FORCE_INLINE Vec4V V4Sub(const Vec4V a, const Vec4V b) +{ + return _mm_sub_ps(a, b); +} + +PX_FORCE_INLINE Vec4V V4Scale(const Vec4V a, const FloatV b) +{ + return _mm_mul_ps(a, b); +} + +PX_FORCE_INLINE Vec4V V4Mul(const Vec4V a, const Vec4V b) +{ + return _mm_mul_ps(a, b); +} + +PX_FORCE_INLINE Vec4V V4ScaleInv(const Vec4V a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(b); + return _mm_div_ps(a, b); +} + +PX_FORCE_INLINE Vec4V V4Div(const Vec4V a, const Vec4V b) +{ + return _mm_div_ps(a, b); +} + +PX_FORCE_INLINE Vec4V V4ScaleInvFast(const Vec4V a, const FloatV b) +{ + ASSERT_ISVALIDFLOATV(b); + return _mm_mul_ps(a, _mm_rcp_ps(b)); +} + +PX_FORCE_INLINE Vec4V V4DivFast(const Vec4V a, const Vec4V b) +{ + return _mm_mul_ps(a, _mm_rcp_ps(b)); +} + +PX_FORCE_INLINE Vec4V V4Recip(const Vec4V a) +{ + return _mm_div_ps(V4One(), a); +} + +PX_FORCE_INLINE Vec4V V4RecipFast(const Vec4V a) +{ + return _mm_rcp_ps(a); +} + +PX_FORCE_INLINE Vec4V V4Rsqrt(const Vec4V a) +{ + return _mm_div_ps(V4One(), _mm_sqrt_ps(a)); +} + +PX_FORCE_INLINE Vec4V V4RsqrtFast(const Vec4V a) +{ + return _mm_rsqrt_ps(a); +} + +PX_FORCE_INLINE Vec4V V4Sqrt(const Vec4V a) +{ + return _mm_sqrt_ps(a); +} + +PX_FORCE_INLINE Vec4V V4ScaleAdd(const Vec4V a, const FloatV b, const Vec4V c) +{ + ASSERT_ISVALIDFLOATV(b); + return V4Add(V4Scale(a, b), c); +} + +PX_FORCE_INLINE Vec4V V4NegScaleSub(const Vec4V a, const FloatV b, const Vec4V c) +{ + ASSERT_ISVALIDFLOATV(b); + return V4Sub(c, V4Scale(a, b)); +} + +PX_FORCE_INLINE Vec4V V4MulAdd(const Vec4V a, const Vec4V b, const Vec4V c) +{ + return V4Add(V4Mul(a, b), c); +} + +PX_FORCE_INLINE Vec4V V4NegMulSub(const Vec4V a, const Vec4V b, const Vec4V c) +{ + return V4Sub(c, V4Mul(a, b)); +} + +PX_FORCE_INLINE Vec4V V4Abs(const Vec4V a) +{ + return V4Max(a, V4Neg(a)); +} + +PX_FORCE_INLINE FloatV V4SumElements(const Vec4V a) +{ + const Vec4V xy = V4UnpackXY(a, a); // x,x,y,y + const Vec4V zw = V4UnpackZW(a, a); // z,z,w,w + const Vec4V xz_yw = V4Add(xy, zw); // x+z,x+z,y+w,y+w + const FloatV xz = V4GetX(xz_yw); // x+z + const FloatV yw = V4GetZ(xz_yw); // y+w + return FAdd(xz, yw); // sum +} + +PX_FORCE_INLINE FloatV V4Dot(const Vec4V a, const Vec4V b) +{ + //const __m128 dot1 = _mm_mul_ps(a, b); // x,y,z,w + //const __m128 shuf1 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(2, 1, 0, 3)); // w,x,y,z + //const __m128 shuf2 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(1, 0, 3, 2)); // z,w,x,y + //const __m128 shuf3 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(0, 3, 2, 1)); // y,z,w,x + //return _mm_add_ps(_mm_add_ps(shuf2, shuf3), _mm_add_ps(dot1, shuf1)); + + // PT: this version has two less instructions but we should check its accuracy + // aw*bw | az*bz | ay*by | ax*bx + const __m128 t0 = _mm_mul_ps(a, b); + // ay*by | ax*bx | aw*bw | az*bz + const __m128 t1 = _mm_shuffle_ps(t0, t0, _MM_SHUFFLE(1,0,3,2)); + // ay*by + aw*bw | ax*bx + az*bz | aw*bw + ay*by | az*bz + ax*bx + const __m128 t2 = _mm_add_ps(t0, t1); + // ax*bx + az*bz | ay*by + aw*bw | az*bz + ax*bx | aw*bw + ay*by + const __m128 t3 = _mm_shuffle_ps(t2, t2, _MM_SHUFFLE(2,3,0,1)); + // ax*bx + az*bz + ay*by + aw*bw + return _mm_add_ps(t3, t2); + // ay*by + aw*bw + ax*bx + az*bz + // az*bz + ax*bx + aw*bw + ay*by + // aw*bw + ay*by + az*bz + ax*bx +} + +PX_FORCE_INLINE FloatV V4Dot3(const Vec4V a, const Vec4V b) +{ + const __m128 dot1 = _mm_mul_ps(a, b); // aw*bw | az*bz | ay*by | ax*bx + const __m128 shuf1 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(0, 0, 0, 0)); // ax*bx | ax*bx | ax*bx | ax*bx + const __m128 shuf2 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(1, 1, 1, 1)); // ay*by | ay*by | ay*by | ay*by + const __m128 shuf3 = _mm_shuffle_ps(dot1, dot1, _MM_SHUFFLE(2, 2, 2, 2)); // az*bz | az*bz | az*bz | az*bz + return _mm_add_ps(_mm_add_ps(shuf1, shuf2), shuf3); // ax*bx + ay*by + az*bz in each component +} + +PX_FORCE_INLINE Vec4V V4Cross(const Vec4V a, const Vec4V b) +{ +/* if(0) + { + const __m128 r1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 1, 0, 2)); // z,x,y,w + const __m128 r2 = _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 0, 2, 1)); // y,z,x,w + const __m128 l1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 0, 2, 1)); // y,z,x,w + const __m128 l2 = _mm_shuffle_ps(b, b, _MM_SHUFFLE(3, 1, 0, 2)); // z,x,y,w + return _mm_sub_ps(_mm_mul_ps(l1, l2), _mm_mul_ps(r1, r2)); + } + else*/ + { + const __m128 b0 = _mm_shuffle_ps(b, b, _MM_SHUFFLE(3,0,2,1)); + const __m128 a1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(3,0,2,1)); + __m128 v = _mm_mul_ps(a1, b); + v = _mm_sub_ps(_mm_mul_ps(a, b0), v); + return _mm_shuffle_ps(v, v, _MM_SHUFFLE(3,0,2,1)); + } +} + +PX_FORCE_INLINE FloatV V4Length(const Vec4V a) +{ + return _mm_sqrt_ps(V4Dot(a, a)); +} + +PX_FORCE_INLINE FloatV V4LengthSq(const Vec4V a) +{ + return V4Dot(a, a); +} + +PX_FORCE_INLINE Vec4V V4Normalize(const Vec4V a) +{ + ASSERT_ISFINITELENGTH(a); + return V4ScaleInv(a, _mm_sqrt_ps(V4Dot(a, a))); +} + +PX_FORCE_INLINE Vec4V V4NormalizeFast(const Vec4V a) +{ + ASSERT_ISFINITELENGTH(a); + return V4ScaleInvFast(a, _mm_sqrt_ps(V4Dot(a, a))); +} + +PX_FORCE_INLINE Vec4V V4NormalizeSafe(const Vec4V a, const Vec4V unsafeReturnValue) +{ + const __m128 eps = V3Eps(); + const __m128 length = V4Length(a); + const __m128 isGreaterThanZero = V4IsGrtr(length, eps); + return V4Sel(isGreaterThanZero, V4ScaleInv(a, length), unsafeReturnValue); +} + +PX_FORCE_INLINE Vec4V V4Sel(const BoolV c, const Vec4V a, const Vec4V b) +{ + return _mm_or_ps(_mm_andnot_ps(c, b), _mm_and_ps(c, a)); +} + +PX_FORCE_INLINE BoolV V4IsGrtr(const Vec4V a, const Vec4V b) +{ + return _mm_cmpgt_ps(a, b); +} + +PX_FORCE_INLINE BoolV V4IsGrtrOrEq(const Vec4V a, const Vec4V b) +{ + return _mm_cmpge_ps(a, b); +} + +PX_FORCE_INLINE BoolV V4IsEq(const Vec4V a, const Vec4V b) +{ + return _mm_cmpeq_ps(a, b); +} + +PX_FORCE_INLINE BoolV V4IsEqU32(const VecU32V a, const VecU32V b) +{ + return internalWindowsSimd::m128_I2F( + _mm_cmpeq_epi32(internalWindowsSimd::m128_F2I(a), internalWindowsSimd::m128_F2I(b))); +} + +PX_FORCE_INLINE Vec4V V4Max(const Vec4V a, const Vec4V b) +{ + return _mm_max_ps(a, b); +} + +PX_FORCE_INLINE Vec4V V4Min(const Vec4V a, const Vec4V b) +{ + return _mm_min_ps(a, b); +} + +PX_FORCE_INLINE FloatV V4ExtractMax(const Vec4V a) +{ + const __m128 shuf1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 1, 0, 3)); + const __m128 shuf2 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 0, 3, 2)); + const __m128 shuf3 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 3, 2, 1)); + + return _mm_max_ps(_mm_max_ps(a, shuf1), _mm_max_ps(shuf2, shuf3)); +} + +PX_FORCE_INLINE FloatV V4ExtractMin(const Vec4V a) +{ + const __m128 shuf1 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 1, 0, 3)); + const __m128 shuf2 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 0, 3, 2)); + const __m128 shuf3 = _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 3, 2, 1)); + + return _mm_min_ps(_mm_min_ps(a, shuf1), _mm_min_ps(shuf2, shuf3)); +} + +PX_FORCE_INLINE Vec4V V4Clamp(const Vec4V a, const Vec4V minV, const Vec4V maxV) +{ + return V4Max(V4Min(a, maxV), minV); +} + +PX_FORCE_INLINE PxU32 V4AllGrtr(const Vec4V a, const Vec4V b) +{ + return internalWindowsSimd::BAllTrue4_R(V4IsGrtr(a, b)); +} + +PX_FORCE_INLINE PxU32 V4AllGrtrOrEq(const Vec4V a, const Vec4V b) +{ + return internalWindowsSimd::BAllTrue4_R(V4IsGrtrOrEq(a, b)); +} + +PX_FORCE_INLINE PxU32 V4AllGrtrOrEq3(const Vec4V a, const Vec4V b) +{ + return internalWindowsSimd::BAllTrue3_R(V4IsGrtrOrEq(a, b)); +} + +PX_FORCE_INLINE PxU32 V4AllEq(const Vec4V a, const Vec4V b) +{ + return internalWindowsSimd::BAllTrue4_R(V4IsEq(a, b)); +} + +PX_FORCE_INLINE PxU32 V4AnyGrtr3(const Vec4V a, const Vec4V b) +{ + return internalWindowsSimd::BAnyTrue3_R(V4IsGrtr(a, b)); +} + +PX_FORCE_INLINE Vec4V V4Round(const Vec4V a) +{ + // return _mm_round_ps(a, 0x0); + const Vec4V half = V4Load(0.5f); + const __m128 signBit = _mm_cvtepi32_ps(_mm_srli_epi32(_mm_cvtps_epi32(a), 31)); + const Vec4V aRound = V4Sub(V4Add(a, half), signBit); + const __m128i tmp = _mm_cvttps_epi32(aRound); + return _mm_cvtepi32_ps(tmp); +} + +PX_FORCE_INLINE Vec4V V4Sin(const Vec4V a) +{ + const Vec4V recipTwoPi = V4LoadA(g_PXReciprocalTwoPi.f); + const Vec4V twoPi = V4LoadA(g_PXTwoPi.f); + const Vec4V tmp = V4Mul(a, recipTwoPi); + const Vec4V b = V4Round(tmp); + const Vec4V V1 = V4NegMulSub(twoPi, b, a); + + // sin(V) ~= V - V^3 / 3! + V^5 / 5! - V^7 / 7! + V^9 / 9! - V^11 / 11! + V^13 / 13! - + // V^15 / 15! + V^17 / 17! - V^19 / 19! + V^21 / 21! - V^23 / 23! (for -PI <= V < PI) + const Vec4V V2 = V4Mul(V1, V1); + const Vec4V V3 = V4Mul(V2, V1); + const Vec4V V5 = V4Mul(V3, V2); + const Vec4V V7 = V4Mul(V5, V2); + const Vec4V V9 = V4Mul(V7, V2); + const Vec4V V11 = V4Mul(V9, V2); + const Vec4V V13 = V4Mul(V11, V2); + const Vec4V V15 = V4Mul(V13, V2); + const Vec4V V17 = V4Mul(V15, V2); + const Vec4V V19 = V4Mul(V17, V2); + const Vec4V V21 = V4Mul(V19, V2); + const Vec4V V23 = V4Mul(V21, V2); + + const Vec4V sinCoefficients0 = V4LoadA(g_PXSinCoefficients0.f); + const Vec4V sinCoefficients1 = V4LoadA(g_PXSinCoefficients1.f); + const Vec4V sinCoefficients2 = V4LoadA(g_PXSinCoefficients2.f); + + const FloatV S1 = V4GetY(sinCoefficients0); + const FloatV S2 = V4GetZ(sinCoefficients0); + const FloatV S3 = V4GetW(sinCoefficients0); + const FloatV S4 = V4GetX(sinCoefficients1); + const FloatV S5 = V4GetY(sinCoefficients1); + const FloatV S6 = V4GetZ(sinCoefficients1); + const FloatV S7 = V4GetW(sinCoefficients1); + const FloatV S8 = V4GetX(sinCoefficients2); + const FloatV S9 = V4GetY(sinCoefficients2); + const FloatV S10 = V4GetZ(sinCoefficients2); + const FloatV S11 = V4GetW(sinCoefficients2); + + Vec4V Result; + Result = V4MulAdd(S1, V3, V1); + Result = V4MulAdd(S2, V5, Result); + Result = V4MulAdd(S3, V7, Result); + Result = V4MulAdd(S4, V9, Result); + Result = V4MulAdd(S5, V11, Result); + Result = V4MulAdd(S6, V13, Result); + Result = V4MulAdd(S7, V15, Result); + Result = V4MulAdd(S8, V17, Result); + Result = V4MulAdd(S9, V19, Result); + Result = V4MulAdd(S10, V21, Result); + Result = V4MulAdd(S11, V23, Result); + + return Result; +} + +PX_FORCE_INLINE Vec4V V4Cos(const Vec4V a) +{ + const Vec4V recipTwoPi = V4LoadA(g_PXReciprocalTwoPi.f); + const FloatV twoPi = V4LoadA(g_PXTwoPi.f); + const Vec4V tmp = V4Mul(a, recipTwoPi); + const Vec4V b = V4Round(tmp); + const Vec4V V1 = V4NegMulSub(twoPi, b, a); + + // cos(V) ~= 1 - V^2 / 2! + V^4 / 4! - V^6 / 6! + V^8 / 8! - V^10 / 10! + V^12 / 12! - + // V^14 / 14! + V^16 / 16! - V^18 / 18! + V^20 / 20! - V^22 / 22! (for -PI <= V < PI) + const Vec4V V2 = V4Mul(V1, V1); + const Vec4V V4 = V4Mul(V2, V2); + const Vec4V V6 = V4Mul(V4, V2); + const Vec4V V8 = V4Mul(V4, V4); + const Vec4V V10 = V4Mul(V6, V4); + const Vec4V V12 = V4Mul(V6, V6); + const Vec4V V14 = V4Mul(V8, V6); + const Vec4V V16 = V4Mul(V8, V8); + const Vec4V V18 = V4Mul(V10, V8); + const Vec4V V20 = V4Mul(V10, V10); + const Vec4V V22 = V4Mul(V12, V10); + + const Vec4V cosCoefficients0 = V4LoadA(g_PXCosCoefficients0.f); + const Vec4V cosCoefficients1 = V4LoadA(g_PXCosCoefficients1.f); + const Vec4V cosCoefficients2 = V4LoadA(g_PXCosCoefficients2.f); + + const FloatV C1 = V4GetY(cosCoefficients0); + const FloatV C2 = V4GetZ(cosCoefficients0); + const FloatV C3 = V4GetW(cosCoefficients0); + const FloatV C4 = V4GetX(cosCoefficients1); + const FloatV C5 = V4GetY(cosCoefficients1); + const FloatV C6 = V4GetZ(cosCoefficients1); + const FloatV C7 = V4GetW(cosCoefficients1); + const FloatV C8 = V4GetX(cosCoefficients2); + const FloatV C9 = V4GetY(cosCoefficients2); + const FloatV C10 = V4GetZ(cosCoefficients2); + const FloatV C11 = V4GetW(cosCoefficients2); + + Vec4V Result; + Result = V4MulAdd(C1, V2, V4One()); + Result = V4MulAdd(C2, V4, Result); + Result = V4MulAdd(C3, V6, Result); + Result = V4MulAdd(C4, V8, Result); + Result = V4MulAdd(C5, V10, Result); + Result = V4MulAdd(C6, V12, Result); + Result = V4MulAdd(C7, V14, Result); + Result = V4MulAdd(C8, V16, Result); + Result = V4MulAdd(C9, V18, Result); + Result = V4MulAdd(C10, V20, Result); + Result = V4MulAdd(C11, V22, Result); + + return Result; +} + +PX_FORCE_INLINE void V4Transpose(Vec4V& col0, Vec4V& col1, Vec4V& col2, Vec4V& col3) +{ + Vec4V tmp0 = _mm_unpacklo_ps(col0, col1); + Vec4V tmp2 = _mm_unpacklo_ps(col2, col3); + Vec4V tmp1 = _mm_unpackhi_ps(col0, col1); + Vec4V tmp3 = _mm_unpackhi_ps(col2, col3); + col0 = _mm_movelh_ps(tmp0, tmp2); + col1 = _mm_movehl_ps(tmp2, tmp0); + col2 = _mm_movelh_ps(tmp1, tmp3); + col3 = _mm_movehl_ps(tmp3, tmp1); +} + +////////////////////////////////// +// BoolV +////////////////////////////////// + +PX_FORCE_INLINE BoolV BFFFF() +{ + return _mm_setzero_ps(); +} + +PX_FORCE_INLINE BoolV BFFFT() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0,0,0,0xFFFFFFFF}; + const __m128 ffft=_mm_load_ps((float*)&f); + return ffft;*/ + return internalWindowsSimd::m128_I2F(_mm_set_epi32(-1, 0, 0, 0)); +} + +PX_FORCE_INLINE BoolV BFFTF() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0,0,0xFFFFFFFF,0}; + const __m128 fftf=_mm_load_ps((float*)&f); + return fftf;*/ + return internalWindowsSimd::m128_I2F(_mm_set_epi32(0, -1, 0, 0)); +} + +PX_FORCE_INLINE BoolV BFFTT() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0,0,0xFFFFFFFF,0xFFFFFFFF}; + const __m128 fftt=_mm_load_ps((float*)&f); + return fftt;*/ + return internalWindowsSimd::m128_I2F(_mm_set_epi32(-1, -1, 0, 0)); +} + +PX_FORCE_INLINE BoolV BFTFF() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0,0xFFFFFFFF,0,0}; + const __m128 ftff=_mm_load_ps((float*)&f); + return ftff;*/ + return internalWindowsSimd::m128_I2F(_mm_set_epi32(0, 0, -1, 0)); +} + +PX_FORCE_INLINE BoolV BFTFT() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0,0xFFFFFFFF,0,0xFFFFFFFF}; + const __m128 ftft=_mm_load_ps((float*)&f); + return ftft;*/ + return internalWindowsSimd::m128_I2F(_mm_set_epi32(-1, 0, -1, 0)); +} + +PX_FORCE_INLINE BoolV BFTTF() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0,0xFFFFFFFF,0xFFFFFFFF,0}; + const __m128 fttf=_mm_load_ps((float*)&f); + return fttf;*/ + return internalWindowsSimd::m128_I2F(_mm_set_epi32(0, -1, -1, 0)); +} + +PX_FORCE_INLINE BoolV BFTTT() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}; + const __m128 fttt=_mm_load_ps((float*)&f); + return fttt;*/ + return internalWindowsSimd::m128_I2F(_mm_set_epi32(-1, -1, -1, 0)); +} + +PX_FORCE_INLINE BoolV BTFFF() +{ + // const PX_ALIGN(16, PxU32 f[4])={0xFFFFFFFF,0,0,0}; + // const __m128 tfff=_mm_load_ps((float*)&f); + // return tfff; + return internalWindowsSimd::m128_I2F(_mm_set_epi32(0, 0, 0, -1)); +} + +PX_FORCE_INLINE BoolV BTFFT() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0xFFFFFFFF,0,0,0xFFFFFFFF}; + const __m128 tfft=_mm_load_ps((float*)&f); + return tfft;*/ + return internalWindowsSimd::m128_I2F(_mm_set_epi32(-1, 0, 0, -1)); +} + +PX_FORCE_INLINE BoolV BTFTF() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0xFFFFFFFF,0,0xFFFFFFFF,0}; + const __m128 tftf=_mm_load_ps((float*)&f); + return tftf;*/ + return internalWindowsSimd::m128_I2F(_mm_set_epi32(0, -1, 0, -1)); +} + +PX_FORCE_INLINE BoolV BTFTT() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0xFFFFFFFF,0,0xFFFFFFFF,0xFFFFFFFF}; + const __m128 tftt=_mm_load_ps((float*)&f); + return tftt;*/ + return internalWindowsSimd::m128_I2F(_mm_set_epi32(-1, -1, 0, -1)); +} + +PX_FORCE_INLINE BoolV BTTFF() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0xFFFFFFFF,0xFFFFFFFF,0,0}; + const __m128 ttff=_mm_load_ps((float*)&f); + return ttff;*/ + return internalWindowsSimd::m128_I2F(_mm_set_epi32(0, 0, -1, -1)); +} + +PX_FORCE_INLINE BoolV BTTFT() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0xFFFFFFFF,0xFFFFFFFF,0,0xFFFFFFFF}; + const __m128 ttft=_mm_load_ps((float*)&f); + return ttft;*/ + return internalWindowsSimd::m128_I2F(_mm_set_epi32(-1, 0, -1, -1)); +} + +PX_FORCE_INLINE BoolV BTTTF() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0}; + const __m128 tttf=_mm_load_ps((float*)&f); + return tttf;*/ + return internalWindowsSimd::m128_I2F(_mm_set_epi32(0, -1, -1, -1)); +} + +PX_FORCE_INLINE BoolV BTTTT() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF,0xFFFFFFFF}; + const __m128 tttt=_mm_load_ps((float*)&f); + return tttt;*/ + return internalWindowsSimd::m128_I2F(_mm_set_epi32(-1, -1, -1, -1)); +} + +PX_FORCE_INLINE BoolV BXMask() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0xFFFFFFFF,0,0,0}; + const __m128 tfff=_mm_load_ps((float*)&f); + return tfff;*/ + return internalWindowsSimd::m128_I2F(_mm_set_epi32(0, 0, 0, -1)); +} + +PX_FORCE_INLINE BoolV BYMask() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0,0xFFFFFFFF,0,0}; + const __m128 ftff=_mm_load_ps((float*)&f); + return ftff;*/ + return internalWindowsSimd::m128_I2F(_mm_set_epi32(0, 0, -1, 0)); +} + +PX_FORCE_INLINE BoolV BZMask() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0,0,0xFFFFFFFF,0}; + const __m128 fftf=_mm_load_ps((float*)&f); + return fftf;*/ + return internalWindowsSimd::m128_I2F(_mm_set_epi32(0, -1, 0, 0)); +} + +PX_FORCE_INLINE BoolV BWMask() +{ + /*const PX_ALIGN(16, PxU32 f[4])={0,0,0,0xFFFFFFFF}; + const __m128 ffft=_mm_load_ps((float*)&f); + return ffft;*/ + return internalWindowsSimd::m128_I2F(_mm_set_epi32(-1, 0, 0, 0)); +} + +PX_FORCE_INLINE BoolV BGetX(const BoolV f) +{ + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(0, 0, 0, 0)); +} + +PX_FORCE_INLINE BoolV BGetY(const BoolV f) +{ + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(1, 1, 1, 1)); +} + +PX_FORCE_INLINE BoolV BGetZ(const BoolV f) +{ + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(2, 2, 2, 2)); +} + +PX_FORCE_INLINE BoolV BGetW(const BoolV f) +{ + return _mm_shuffle_ps(f, f, _MM_SHUFFLE(3, 3, 3, 3)); +} + +PX_FORCE_INLINE BoolV BSetX(const BoolV v, const BoolV f) +{ + return V4Sel(BFTTT(), v, f); +} + +PX_FORCE_INLINE BoolV BSetY(const BoolV v, const BoolV f) +{ + return V4Sel(BTFTT(), v, f); +} + +PX_FORCE_INLINE BoolV BSetZ(const BoolV v, const BoolV f) +{ + return V4Sel(BTTFT(), v, f); +} + +PX_FORCE_INLINE BoolV BSetW(const BoolV v, const BoolV f) +{ + return V4Sel(BTTTF(), v, f); +} + +template +BoolV BSplatElement(BoolV a) +{ + return internalWindowsSimd::m128_I2F( + _mm_shuffle_epi32(internalWindowsSimd::m128_F2I(a), _MM_SHUFFLE(index, index, index, index))); +} + +PX_FORCE_INLINE BoolV BAnd(const BoolV a, const BoolV b) +{ + return _mm_and_ps(a, b); +} + +PX_FORCE_INLINE BoolV BNot(const BoolV a) +{ + const BoolV bAllTrue(BTTTT()); + return _mm_xor_ps(a, bAllTrue); +} + +PX_FORCE_INLINE BoolV BAndNot(const BoolV a, const BoolV b) +{ + return _mm_andnot_ps(b, a); +} + +PX_FORCE_INLINE BoolV BOr(const BoolV a, const BoolV b) +{ + return _mm_or_ps(a, b); +} + +PX_FORCE_INLINE BoolV BAllTrue4(const BoolV a) +{ + const BoolV bTmp = + _mm_and_ps(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 1, 0, 1)), _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 3, 2, 3))); + return _mm_and_ps(_mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(0, 0, 0, 0)), + _mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(1, 1, 1, 1))); +} + +PX_FORCE_INLINE BoolV BAnyTrue4(const BoolV a) +{ + const BoolV bTmp = + _mm_or_ps(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 1, 0, 1)), _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 3, 2, 3))); + return _mm_or_ps(_mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(0, 0, 0, 0)), + _mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(1, 1, 1, 1))); +} + +PX_FORCE_INLINE BoolV BAllTrue3(const BoolV a) +{ + const BoolV bTmp = + _mm_and_ps(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 1, 0, 1)), _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2))); + return _mm_and_ps(_mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(0, 0, 0, 0)), + _mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(1, 1, 1, 1))); +} + +PX_FORCE_INLINE BoolV BAnyTrue3(const BoolV a) +{ + const BoolV bTmp = + _mm_or_ps(_mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 1, 0, 1)), _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2))); + return _mm_or_ps(_mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(0, 0, 0, 0)), + _mm_shuffle_ps(bTmp, bTmp, _MM_SHUFFLE(1, 1, 1, 1))); +} + +PX_FORCE_INLINE PxU32 BAllEq(const BoolV a, const BoolV b) +{ + const BoolV bTest = internalWindowsSimd::m128_I2F( + _mm_cmpeq_epi32(internalWindowsSimd::m128_F2I(a), internalWindowsSimd::m128_F2I(b))); + return internalWindowsSimd::BAllTrue4_R(bTest); +} + +PX_FORCE_INLINE PxU32 BAllEqTTTT(const BoolV a) +{ + return PxU32(_mm_movemask_ps(a)==15); +} + +PX_FORCE_INLINE PxU32 BAllEqFFFF(const BoolV a) +{ + return PxU32(_mm_movemask_ps(a)==0); +} + +PX_FORCE_INLINE PxU32 BGetBitMask(const BoolV a) +{ + return PxU32(_mm_movemask_ps(a)); +} + +////////////////////////////////// +// MAT33V +////////////////////////////////// + +PX_FORCE_INLINE Vec3V M33MulV3(const Mat33V& a, const Vec3V b) +{ + const FloatV x = V3GetX(b); + const FloatV y = V3GetY(b); + const FloatV z = V3GetZ(b); + const Vec3V v0 = V3Scale(a.col0, x); + const Vec3V v1 = V3Scale(a.col1, y); + const Vec3V v2 = V3Scale(a.col2, z); + const Vec3V v0PlusV1 = V3Add(v0, v1); + return V3Add(v0PlusV1, v2); +} + +PX_FORCE_INLINE Vec3V M33TrnspsMulV3(const Mat33V& a, const Vec3V b) +{ + Vec3V v0 = V3Mul(a.col0, b); + Vec3V v1 = V3Mul(a.col1, b); + Vec3V v2 = V3Mul(a.col2, b); + V3Transpose(v0, v1, v2); + return V3Add(V3Add(v0, v1), v2); +} + +PX_FORCE_INLINE Vec3V M33MulV3AddV3(const Mat33V& A, const Vec3V b, const Vec3V c) +{ + const FloatV x = V3GetX(b); + const FloatV y = V3GetY(b); + const FloatV z = V3GetZ(b); + Vec3V result = V3ScaleAdd(A.col0, x, c); + result = V3ScaleAdd(A.col1, y, result); + return V3ScaleAdd(A.col2, z, result); +} + +PX_FORCE_INLINE Mat33V M33MulM33(const Mat33V& a, const Mat33V& b) +{ + return Mat33V(M33MulV3(a, b.col0), M33MulV3(a, b.col1), M33MulV3(a, b.col2)); +} + +PX_FORCE_INLINE Mat33V M33Add(const Mat33V& a, const Mat33V& b) +{ + return Mat33V(V3Add(a.col0, b.col0), V3Add(a.col1, b.col1), V3Add(a.col2, b.col2)); +} + +PX_FORCE_INLINE Mat33V M33Scale(const Mat33V& a, const FloatV& b) +{ + return Mat33V(V3Scale(a.col0, b), V3Scale(a.col1, b), V3Scale(a.col2, b)); +} + +PX_FORCE_INLINE Mat33V M33Sub(const Mat33V& a, const Mat33V& b) +{ + return Mat33V(V3Sub(a.col0, b.col0), V3Sub(a.col1, b.col1), V3Sub(a.col2, b.col2)); +} + +PX_FORCE_INLINE Mat33V M33Neg(const Mat33V& a) +{ + return Mat33V(V3Neg(a.col0), V3Neg(a.col1), V3Neg(a.col2)); +} + +PX_FORCE_INLINE Mat33V M33Abs(const Mat33V& a) +{ + return Mat33V(V3Abs(a.col0), V3Abs(a.col1), V3Abs(a.col2)); +} + +PX_FORCE_INLINE Mat33V M33Inverse(const Mat33V& a) +{ + const BoolV tfft = BTFFT(); + const BoolV tttf = BTTTF(); + const FloatV zero = V3Zero(); + const Vec3V cross01 = V3Cross(a.col0, a.col1); + const Vec3V cross12 = V3Cross(a.col1, a.col2); + const Vec3V cross20 = V3Cross(a.col2, a.col0); + const FloatV dot = V3Dot(cross01, a.col2); + const FloatV invDet = _mm_rcp_ps(dot); + const Vec3V mergeh = _mm_unpacklo_ps(cross12, cross01); + const Vec3V mergel = _mm_unpackhi_ps(cross12, cross01); + Vec3V colInv0 = _mm_unpacklo_ps(mergeh, cross20); + colInv0 = _mm_or_ps(_mm_andnot_ps(tttf, zero), _mm_and_ps(tttf, colInv0)); + const Vec3V zppd = _mm_shuffle_ps(mergeh, cross20, _MM_SHUFFLE(3, 0, 0, 2)); + const Vec3V pbwp = _mm_shuffle_ps(cross20, mergeh, _MM_SHUFFLE(3, 3, 1, 0)); + const Vec3V colInv1 = _mm_or_ps(_mm_andnot_ps(BTFFT(), pbwp), _mm_and_ps(BTFFT(), zppd)); + const Vec3V xppd = _mm_shuffle_ps(mergel, cross20, _MM_SHUFFLE(3, 0, 0, 0)); + const Vec3V pcyp = _mm_shuffle_ps(cross20, mergel, _MM_SHUFFLE(3, 1, 2, 0)); + const Vec3V colInv2 = _mm_or_ps(_mm_andnot_ps(tfft, pcyp), _mm_and_ps(tfft, xppd)); + + return Mat33V(_mm_mul_ps(colInv0, invDet), _mm_mul_ps(colInv1, invDet), _mm_mul_ps(colInv2, invDet)); +} + +PX_FORCE_INLINE Mat33V M33Trnsps(const Mat33V& a) +{ + Vec3V col0 = a.col0, col1 = a.col1, col2 = a.col2; + V3Transpose(col0, col1, col2); + return Mat33V(col0, col1, col2); +} + +PX_FORCE_INLINE Mat33V M33Identity() +{ + return Mat33V(V3UnitX(), V3UnitY(), V3UnitZ()); +} + +PX_FORCE_INLINE Mat33V M33Diagonal(const Vec3VArg d) +{ + const FloatV x = V3Mul(V3UnitX(), d); + const FloatV y = V3Mul(V3UnitY(), d); + const FloatV z = V3Mul(V3UnitZ(), d); + return Mat33V(x, y, z); +} + +////////////////////////////////// +// MAT34V +////////////////////////////////// + +PX_FORCE_INLINE Vec3V M34MulV3(const Mat34V& a, const Vec3V b) +{ + const FloatV x = V3GetX(b); + const FloatV y = V3GetY(b); + const FloatV z = V3GetZ(b); + const Vec3V v0 = V3Scale(a.col0, x); + const Vec3V v1 = V3Scale(a.col1, y); + const Vec3V v2 = V3Scale(a.col2, z); + const Vec3V v0PlusV1 = V3Add(v0, v1); + const Vec3V v0PlusV1Plusv2 = V3Add(v0PlusV1, v2); + return V3Add(v0PlusV1Plusv2, a.col3); +} + +PX_FORCE_INLINE Vec3V M34Mul33V3(const Mat34V& a, const Vec3V b) +{ + const FloatV x = V3GetX(b); + const FloatV y = V3GetY(b); + const FloatV z = V3GetZ(b); + const Vec3V v0 = V3Scale(a.col0, x); + const Vec3V v1 = V3Scale(a.col1, y); + const Vec3V v2 = V3Scale(a.col2, z); + const Vec3V v0PlusV1 = V3Add(v0, v1); + return V3Add(v0PlusV1, v2); +} + +PX_FORCE_INLINE Vec3V M34TrnspsMul33V3(const Mat34V& a, const Vec3V b) +{ + Vec3V v0 = V3Mul(a.col0, b); + Vec3V v1 = V3Mul(a.col1, b); + Vec3V v2 = V3Mul(a.col2, b); + V3Transpose(v0, v1, v2); + return V3Add(V3Add(v0, v1), v2); +} + +PX_FORCE_INLINE Mat34V M34MulM34(const Mat34V& a, const Mat34V& b) +{ + return Mat34V(M34Mul33V3(a, b.col0), M34Mul33V3(a, b.col1), M34Mul33V3(a, b.col2), M34MulV3(a, b.col3)); +} + +PX_FORCE_INLINE Mat33V M34MulM33(const Mat34V& a, const Mat33V& b) +{ + return Mat33V(M34Mul33V3(a, b.col0), M34Mul33V3(a, b.col1), M34Mul33V3(a, b.col2)); +} + +PX_FORCE_INLINE Mat33V M34Mul33MM34(const Mat34V& a, const Mat34V& b) +{ + return Mat33V(M34Mul33V3(a, b.col0), M34Mul33V3(a, b.col1), M34Mul33V3(a, b.col2)); +} + +PX_FORCE_INLINE Mat34V M34Add(const Mat34V& a, const Mat34V& b) +{ + return Mat34V(V3Add(a.col0, b.col0), V3Add(a.col1, b.col1), V3Add(a.col2, b.col2), V3Add(a.col3, b.col3)); +} + +PX_FORCE_INLINE Mat34V M34Inverse(const Mat34V& a) +{ + Mat34V aInv; + const BoolV tfft = BTFFT(); + const BoolV tttf = BTTTF(); + const FloatV zero = V3Zero(); + const Vec3V cross01 = V3Cross(a.col0, a.col1); + const Vec3V cross12 = V3Cross(a.col1, a.col2); + const Vec3V cross20 = V3Cross(a.col2, a.col0); + const FloatV dot = V3Dot(cross01, a.col2); + const FloatV invDet = _mm_rcp_ps(dot); + const Vec3V mergeh = _mm_unpacklo_ps(cross12, cross01); + const Vec3V mergel = _mm_unpackhi_ps(cross12, cross01); + Vec3V colInv0 = _mm_unpacklo_ps(mergeh, cross20); + colInv0 = _mm_or_ps(_mm_andnot_ps(tttf, zero), _mm_and_ps(tttf, colInv0)); + const Vec3V zppd = _mm_shuffle_ps(mergeh, cross20, _MM_SHUFFLE(3, 0, 0, 2)); + const Vec3V pbwp = _mm_shuffle_ps(cross20, mergeh, _MM_SHUFFLE(3, 3, 1, 0)); + const Vec3V colInv1 = _mm_or_ps(_mm_andnot_ps(BTFFT(), pbwp), _mm_and_ps(BTFFT(), zppd)); + const Vec3V xppd = _mm_shuffle_ps(mergel, cross20, _MM_SHUFFLE(3, 0, 0, 0)); + const Vec3V pcyp = _mm_shuffle_ps(cross20, mergel, _MM_SHUFFLE(3, 1, 2, 0)); + const Vec3V colInv2 = _mm_or_ps(_mm_andnot_ps(tfft, pcyp), _mm_and_ps(tfft, xppd)); + aInv.col0 = _mm_mul_ps(colInv0, invDet); + aInv.col1 = _mm_mul_ps(colInv1, invDet); + aInv.col2 = _mm_mul_ps(colInv2, invDet); + aInv.col3 = M34Mul33V3(aInv, V3Neg(a.col3)); + return aInv; +} + +PX_FORCE_INLINE Mat33V M34Trnsps33(const Mat34V& a) +{ + Vec3V col0 = a.col0, col1 = a.col1, col2 = a.col2; + V3Transpose(col0, col1, col2); + return Mat33V(col0, col1, col2); +} + +////////////////////////////////// +// MAT44V +////////////////////////////////// + +PX_FORCE_INLINE Vec4V M44MulV4(const Mat44V& a, const Vec4V b) +{ + const FloatV x = V4GetX(b); + const FloatV y = V4GetY(b); + const FloatV z = V4GetZ(b); + const FloatV w = V4GetW(b); + + const Vec4V v0 = V4Scale(a.col0, x); + const Vec4V v1 = V4Scale(a.col1, y); + const Vec4V v2 = V4Scale(a.col2, z); + const Vec4V v3 = V4Scale(a.col3, w); + const Vec4V v0PlusV1 = V4Add(v0, v1); + const Vec4V v0PlusV1Plusv2 = V4Add(v0PlusV1, v2); + return V4Add(v0PlusV1Plusv2, v3); +} + +PX_FORCE_INLINE Vec4V M44TrnspsMulV4(const Mat44V& a, const Vec4V b) +{ + Vec4V v0 = V4Mul(a.col0, b); + Vec4V v1 = V4Mul(a.col1, b); + Vec4V v2 = V4Mul(a.col2, b); + Vec4V v3 = V4Mul(a.col3, b); + V4Transpose(v0, v1, v2, v3); + return V4Add(V4Add(v0, v1), V4Add(v2, v3)); +} + +PX_FORCE_INLINE Mat44V M44MulM44(const Mat44V& a, const Mat44V& b) +{ + return Mat44V(M44MulV4(a, b.col0), M44MulV4(a, b.col1), M44MulV4(a, b.col2), M44MulV4(a, b.col3)); +} + +PX_FORCE_INLINE Mat44V M44Add(const Mat44V& a, const Mat44V& b) +{ + return Mat44V(V4Add(a.col0, b.col0), V4Add(a.col1, b.col1), V4Add(a.col2, b.col2), V4Add(a.col3, b.col3)); +} + +PX_FORCE_INLINE Mat44V M44Trnsps(const Mat44V& a) +{ + Vec4V col0 = a.col0, col1 = a.col1, col2 = a.col2, col3 = a.col3; + V4Transpose(col0, col1, col2, col3); + return Mat44V(col0, col1, col2, col3); +} + +PX_FORCE_INLINE Mat44V M44Inverse(const Mat44V& a) +{ + __m128 minor0, minor1, minor2, minor3; + __m128 row0, row1, row2, row3; + __m128 det, tmp1; + + tmp1 = V4Zero(); + row1 = V4Zero(); + row3 = V4Zero(); + + row0 = a.col0; + row1 = _mm_shuffle_ps(a.col1, a.col1, _MM_SHUFFLE(1, 0, 3, 2)); + row2 = a.col2; + row3 = _mm_shuffle_ps(a.col3, a.col3, _MM_SHUFFLE(1, 0, 3, 2)); + + tmp1 = _mm_mul_ps(row2, row3); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); + minor0 = _mm_mul_ps(row1, tmp1); + minor1 = _mm_mul_ps(row0, tmp1); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); + minor0 = _mm_sub_ps(_mm_mul_ps(row1, tmp1), minor0); + minor1 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor1); + minor1 = _mm_shuffle_ps(minor1, minor1, 0x4E); + + tmp1 = _mm_mul_ps(row1, row2); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); + minor0 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor0); + minor3 = _mm_mul_ps(row0, tmp1); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); + minor0 = _mm_sub_ps(minor0, _mm_mul_ps(row3, tmp1)); + minor3 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor3); + minor3 = _mm_shuffle_ps(minor3, minor3, 0x4E); + + tmp1 = _mm_mul_ps(_mm_shuffle_ps(row1, row1, 0x4E), row3); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); + row2 = _mm_shuffle_ps(row2, row2, 0x4E); + minor0 = _mm_add_ps(_mm_mul_ps(row2, tmp1), minor0); + minor2 = _mm_mul_ps(row0, tmp1); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); + minor0 = _mm_sub_ps(minor0, _mm_mul_ps(row2, tmp1)); + minor2 = _mm_sub_ps(_mm_mul_ps(row0, tmp1), minor2); + minor2 = _mm_shuffle_ps(minor2, minor2, 0x4E); + + tmp1 = _mm_mul_ps(row0, row1); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); + minor2 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor2); + minor3 = _mm_sub_ps(_mm_mul_ps(row2, tmp1), minor3); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); + minor2 = _mm_sub_ps(_mm_mul_ps(row3, tmp1), minor2); + minor3 = _mm_sub_ps(minor3, _mm_mul_ps(row2, tmp1)); + + tmp1 = _mm_mul_ps(row0, row3); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); + minor1 = _mm_sub_ps(minor1, _mm_mul_ps(row2, tmp1)); + minor2 = _mm_add_ps(_mm_mul_ps(row1, tmp1), minor2); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); + minor1 = _mm_add_ps(_mm_mul_ps(row2, tmp1), minor1); + minor2 = _mm_sub_ps(minor2, _mm_mul_ps(row1, tmp1)); + + tmp1 = _mm_mul_ps(row0, row2); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0xB1); + minor1 = _mm_add_ps(_mm_mul_ps(row3, tmp1), minor1); + minor3 = _mm_sub_ps(minor3, _mm_mul_ps(row1, tmp1)); + tmp1 = _mm_shuffle_ps(tmp1, tmp1, 0x4E); + minor1 = _mm_sub_ps(minor1, _mm_mul_ps(row3, tmp1)); + minor3 = _mm_add_ps(_mm_mul_ps(row1, tmp1), minor3); + + det = _mm_mul_ps(row0, minor0); + det = _mm_add_ps(_mm_shuffle_ps(det, det, 0x4E), det); + det = _mm_add_ss(_mm_shuffle_ps(det, det, 0xB1), det); + tmp1 = _mm_rcp_ss(det); +#if 0 + det = _mm_sub_ss(_mm_add_ss(tmp1, tmp1), _mm_mul_ss(det, _mm_mul_ss(tmp1, tmp1))); + det = _mm_shuffle_ps(det, det, 0x00); +#else + det = _mm_shuffle_ps(tmp1, tmp1, _MM_SHUFFLE(0, 0, 0, 0)); +#endif + + minor0 = _mm_mul_ps(det, minor0); + minor1 = _mm_mul_ps(det, minor1); + minor2 = _mm_mul_ps(det, minor2); + minor3 = _mm_mul_ps(det, minor3); + Mat44V invTrans(minor0, minor1, minor2, minor3); + return M44Trnsps(invTrans); +} + +PX_FORCE_INLINE Vec4V V4LoadXYZW(const PxF32& x, const PxF32& y, const PxF32& z, const PxF32& w) +{ + return _mm_set_ps(w, z, y, x); +} + +PX_FORCE_INLINE VecU32V V4U32Sel(const BoolV c, const VecU32V a, const VecU32V b) +{ + return internalWindowsSimd::m128_I2F( + _mm_or_si128(_mm_andnot_si128(internalWindowsSimd::m128_F2I(c), internalWindowsSimd::m128_F2I(b)), + _mm_and_si128(internalWindowsSimd::m128_F2I(c), internalWindowsSimd::m128_F2I(a)))); +} + +PX_FORCE_INLINE VecU32V V4U32or(VecU32V a, VecU32V b) +{ + return internalWindowsSimd::m128_I2F(_mm_or_si128(internalWindowsSimd::m128_F2I(a), internalWindowsSimd::m128_F2I(b))); +} + +PX_FORCE_INLINE VecU32V V4U32xor(VecU32V a, VecU32V b) +{ + return internalWindowsSimd::m128_I2F( + _mm_xor_si128(internalWindowsSimd::m128_F2I(a), internalWindowsSimd::m128_F2I(b))); +} + +PX_FORCE_INLINE VecU32V V4U32and(VecU32V a, VecU32V b) +{ + return internalWindowsSimd::m128_I2F( + _mm_and_si128(internalWindowsSimd::m128_F2I(a), internalWindowsSimd::m128_F2I(b))); +} + +PX_FORCE_INLINE VecU32V V4U32Andc(VecU32V a, VecU32V b) +{ + return internalWindowsSimd::m128_I2F( + _mm_andnot_si128(internalWindowsSimd::m128_F2I(b), internalWindowsSimd::m128_F2I(a))); +} + +PX_FORCE_INLINE VecI32V U4Load(const PxU32 i) +{ + return _mm_load1_ps((PxF32*)&i); +} + +PX_FORCE_INLINE VecU32V U4LoadU(const PxU32* i) +{ + return _mm_loadu_ps((PxF32*)i); +} + +PX_FORCE_INLINE VecU32V U4LoadA(const PxU32* i) +{ + ASSERT_ISALIGNED16(i); + return _mm_load_ps((PxF32*)i); +} + +PX_FORCE_INLINE VecI32V I4LoadXYZW(const PxI32& x, const PxI32& y, const PxI32& z, const PxI32& w) +{ + return internalWindowsSimd::m128_I2F(_mm_set_epi32(w, z, y, x)); +} + +PX_FORCE_INLINE VecI32V I4Load(const PxI32 i) +{ + return _mm_load1_ps((PxF32*)&i); +} + +PX_FORCE_INLINE VecI32V I4LoadU(const PxI32* i) +{ + return _mm_loadu_ps((PxF32*)i); +} + +PX_FORCE_INLINE VecI32V I4LoadA(const PxI32* i) +{ + ASSERT_ISALIGNED16(i); + return _mm_load_ps((PxF32*)i); +} + +PX_FORCE_INLINE VecI32V VecI32V_Add(const VecI32VArg a, const VecI32VArg b) +{ + return internalWindowsSimd::m128_I2F( + _mm_add_epi32(internalWindowsSimd::m128_F2I(a), internalWindowsSimd::m128_F2I(b))); +} + +PX_FORCE_INLINE VecI32V VecI32V_Sub(const VecI32VArg a, const VecI32VArg b) +{ + return internalWindowsSimd::m128_I2F( + _mm_sub_epi32(internalWindowsSimd::m128_F2I(a), internalWindowsSimd::m128_F2I(b))); +} + +PX_FORCE_INLINE BoolV VecI32V_IsGrtr(const VecI32VArg a, const VecI32VArg b) +{ + return internalWindowsSimd::m128_I2F( + _mm_cmpgt_epi32(internalWindowsSimd::m128_F2I(a), internalWindowsSimd::m128_F2I(b))); +} + +PX_FORCE_INLINE BoolV VecI32V_IsEq(const VecI32VArg a, const VecI32VArg b) +{ + return internalWindowsSimd::m128_I2F( + _mm_cmpeq_epi32(internalWindowsSimd::m128_F2I(a), internalWindowsSimd::m128_F2I(b))); +} + +PX_FORCE_INLINE VecI32V V4I32Sel(const BoolV c, const VecI32V a, const VecI32V b) +{ + return V4U32Sel(c, a, b); +} + +PX_FORCE_INLINE VecI32V VecI32V_Zero() +{ + return V4Zero(); +} + +PX_FORCE_INLINE VecI32V VecI32V_One() +{ + return I4Load(1); +} + +PX_FORCE_INLINE VecI32V VecI32V_Two() +{ + return I4Load(2); +} + +PX_FORCE_INLINE VecI32V VecI32V_MinusOne() +{ + return I4Load(-1); +} + +PX_FORCE_INLINE VecU32V U4Zero() +{ + return U4Load(0); +} + +PX_FORCE_INLINE VecU32V U4One() +{ + return U4Load(1); +} + +PX_FORCE_INLINE VecU32V U4Two() +{ + return U4Load(2); +} + +PX_FORCE_INLINE VecI32V VecI32V_Sel(const BoolV c, const VecI32VArg a, const VecI32VArg b) +{ + PX_ASSERT(vecMathTests::allElementsEqualBoolV(c, BTTTT()) || + vecMathTests::allElementsEqualBoolV(c, BFFFF())); + return _mm_or_ps(_mm_andnot_ps(c, b), _mm_and_ps(c, a)); +} + +PX_FORCE_INLINE VecShiftV VecI32V_PrepareShift(const VecI32VArg shift) +{ + VecShiftV preparedShift; + preparedShift.shift = _mm_or_ps(_mm_andnot_ps(BTFFF(), VecI32V_Zero()), _mm_and_ps(BTFFF(), shift)); + return preparedShift; +} + +PX_FORCE_INLINE VecI32V VecI32V_LeftShift(const VecI32VArg a, const VecShiftVArg count) +{ + return internalWindowsSimd::m128_I2F( + _mm_sll_epi32(internalWindowsSimd::m128_F2I(a), internalWindowsSimd::m128_F2I(count.shift))); +} + +PX_FORCE_INLINE VecI32V VecI32V_RightShift(const VecI32VArg a, const VecShiftVArg count) +{ + return internalWindowsSimd::m128_I2F( + _mm_srl_epi32(internalWindowsSimd::m128_F2I(a), internalWindowsSimd::m128_F2I(count.shift))); +} + +PX_FORCE_INLINE VecI32V VecI32V_LeftShift(const VecI32VArg a, const PxU32 count) +{ + return internalWindowsSimd::m128_I2F( + _mm_slli_epi32(internalWindowsSimd::m128_F2I(a), count)); +} + +PX_FORCE_INLINE VecI32V VecI32V_RightShift(const VecI32VArg a, const PxU32 count) +{ + return internalWindowsSimd::m128_I2F( + _mm_srai_epi32(internalWindowsSimd::m128_F2I(a), count)); +} + +PX_FORCE_INLINE VecI32V VecI32V_And(const VecI32VArg a, const VecI32VArg b) +{ + return internalWindowsSimd::m128_I2F( + _mm_and_si128(internalWindowsSimd::m128_F2I(a), internalWindowsSimd::m128_F2I(b))); +} + +PX_FORCE_INLINE VecI32V VecI32V_Or(const VecI32VArg a, const VecI32VArg b) +{ + return internalWindowsSimd::m128_I2F( + _mm_or_si128(internalWindowsSimd::m128_F2I(a), internalWindowsSimd::m128_F2I(b))); +} + +PX_FORCE_INLINE VecI32V VecI32V_GetX(const VecI32VArg a) +{ + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(0, 0, 0, 0)); +} + +PX_FORCE_INLINE VecI32V VecI32V_GetY(const VecI32VArg a) +{ + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(1, 1, 1, 1)); +} + +PX_FORCE_INLINE VecI32V VecI32V_GetZ(const VecI32VArg a) +{ + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(2, 2, 2, 2)); +} + +PX_FORCE_INLINE VecI32V VecI32V_GetW(const VecI32VArg a) +{ + return _mm_shuffle_ps(a, a, _MM_SHUFFLE(3, 3, 3, 3)); +} + +PX_FORCE_INLINE void PxI32_From_VecI32V(const VecI32VArg a, PxI32* i) +{ + _mm_store_ss((PxF32*)i, a); +} + +PX_FORCE_INLINE VecI32V VecI32V_From_BoolV(const BoolVArg a) +{ + return a; +} + +PX_FORCE_INLINE VecU32V VecU32V_From_BoolV(const BoolVArg a) +{ + return a; +} + +PX_FORCE_INLINE VecI32V VecI32V_Merge(const VecI32VArg a, const VecI32VArg b, const VecI32VArg c, const VecI32VArg d) +{ + const __m128 xw = _mm_move_ss(b, a); // y, y, y, x + const __m128 yz = _mm_move_ss(c, d); // z, z, z, w + return _mm_shuffle_ps(xw, yz, _MM_SHUFFLE(0, 2, 1, 0)); +} + +PX_FORCE_INLINE void V4U32StoreAligned(VecU32V val, VecU32V* address) +{ + *address = val; +} + +PX_FORCE_INLINE Vec4V V4Andc(const Vec4V a, const VecU32V b) +{ + VecU32V result32(a); + result32 = V4U32Andc(result32, b); + return Vec4V(result32); +} + +PX_FORCE_INLINE VecU32V V4IsGrtrV32u(const Vec4V a, const Vec4V b) +{ + return V4IsGrtr(a, b); +} + +PX_FORCE_INLINE VecU16V V4U16LoadAligned(VecU16V* addr) +{ + return *addr; +} + +PX_FORCE_INLINE VecU16V V4U16LoadUnaligned(VecU16V* addr) +{ + return *addr; +} + +// unsigned compares are not supported on x86 +PX_FORCE_INLINE VecU16V V4U16CompareGt(VecU16V a, VecU16V b) +{ + // _mm_cmpgt_epi16 doesn't work for unsigned values unfortunately + // return m128_I2F(_mm_cmpgt_epi16(internalWindowsSimd::m128_F2I(a), internalWindowsSimd::m128_F2I(b))); + VecU16V result; + result.m128_u16[0] = PxU16((a).m128_u16[0] > (b).m128_u16[0]); + result.m128_u16[1] = PxU16((a).m128_u16[1] > (b).m128_u16[1]); + result.m128_u16[2] = PxU16((a).m128_u16[2] > (b).m128_u16[2]); + result.m128_u16[3] = PxU16((a).m128_u16[3] > (b).m128_u16[3]); + result.m128_u16[4] = PxU16((a).m128_u16[4] > (b).m128_u16[4]); + result.m128_u16[5] = PxU16((a).m128_u16[5] > (b).m128_u16[5]); + result.m128_u16[6] = PxU16((a).m128_u16[6] > (b).m128_u16[6]); + result.m128_u16[7] = PxU16((a).m128_u16[7] > (b).m128_u16[7]); + return result; +} + +PX_FORCE_INLINE VecU16V V4I16CompareGt(VecU16V a, VecU16V b) +{ + return internalWindowsSimd::m128_I2F( + _mm_cmpgt_epi16(internalWindowsSimd::m128_F2I(a), internalWindowsSimd::m128_F2I(b))); +} + +PX_FORCE_INLINE Vec4V Vec4V_From_VecU32V(VecU32V a) +{ + Vec4V result = V4LoadXYZW(PxF32(a.m128_u32[0]), PxF32(a.m128_u32[1]), PxF32(a.m128_u32[2]), PxF32(a.m128_u32[3])); + return result; +} + +PX_FORCE_INLINE Vec4V Vec4V_From_VecI32V(VecI32V a) +{ + return _mm_cvtepi32_ps(internalWindowsSimd::m128_F2I(a)); +} + +PX_FORCE_INLINE VecI32V VecI32V_From_Vec4V(Vec4V a) +{ + return internalWindowsSimd::m128_I2F(_mm_cvttps_epi32(a)); +} + +PX_FORCE_INLINE Vec4V Vec4V_ReinterpretFrom_VecU32V(VecU32V a) +{ + return Vec4V(a); +} + +PX_FORCE_INLINE Vec4V Vec4V_ReinterpretFrom_VecI32V(VecI32V a) +{ + return Vec4V(a); +} + +PX_FORCE_INLINE VecU32V VecU32V_ReinterpretFrom_Vec4V(Vec4V a) +{ + return VecU32V(a); +} + +PX_FORCE_INLINE VecI32V VecI32V_ReinterpretFrom_Vec4V(Vec4V a) +{ + return VecI32V(a); +} + +template +PX_FORCE_INLINE VecU32V V4U32SplatElement(VecU32V a) +{ + return internalWindowsSimd::m128_I2F( + _mm_shuffle_epi32(internalWindowsSimd::m128_F2I(a), _MM_SHUFFLE(index, index, index, index))); +} + +template +PX_FORCE_INLINE Vec4V V4SplatElement(Vec4V a) +{ + return internalWindowsSimd::m128_I2F( + _mm_shuffle_epi32(internalWindowsSimd::m128_F2I(a), _MM_SHUFFLE(index, index, index, index))); +} + +PX_FORCE_INLINE VecU32V U4LoadXYZW(PxU32 x, PxU32 y, PxU32 z, PxU32 w) +{ + VecU32V result; + result.m128_u32[0] = x; + result.m128_u32[1] = y; + result.m128_u32[2] = z; + result.m128_u32[3] = w; + return result; +} + +PX_FORCE_INLINE Vec4V V4ConvertFromI32V(const VecI32V in) +{ + return _mm_cvtepi32_ps(internalWindowsSimd::m128_F2I(in)); +} + +} // namespace aos +} // namespace physx + +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/windows/PxWindowsIntrinsics.h b/Source/ThirdParty/PhysX/foundation/windows/PxWindowsIntrinsics.h index 804c20b0d..9d79d3568 100644 --- a/Source/ThirdParty/PhysX/foundation/windows/PxWindowsIntrinsics.h +++ b/Source/ThirdParty/PhysX/foundation/windows/PxWindowsIntrinsics.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,166 +22,151 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PXFOUNDATION_PXWINDOWSINTRINSICS_H -#define PXFOUNDATION_PXWINDOWSINTRINSICS_H +#ifndef PX_WINDOWS_INTRINSICS_H +#define PX_WINDOWS_INTRINSICS_H -#include "foundation/Px.h" -#include "foundation/PxSharedAssert.h" +#include "foundation/PxAssert.h" + +// this file is for internal intrinsics - that is, intrinsics that are used in +// cross platform code but do not appear in the API #if !PX_WINDOWS_FAMILY #error "This file should only be included by Windows builds!!" #endif +#pragma warning(push) +//'symbol' is not defined as a preprocessor macro, replacing with '0' for 'directives' +#pragma warning(disable : 4668) +#if PX_VC == 10 +#pragma warning(disable : 4987) // nonstandard extension used: 'throw (...)' +#endif +#include +#pragma warning(pop) + +#pragma warning(push) +#pragma warning(disable : 4985) // 'symbol name': attributes not present on previous declaration #include +#pragma warning(pop) + #include +// do not include for ARM target +#if !PX_ARM && !PX_A64 +#include +#endif + +#pragma intrinsic(_BitScanForward) +#pragma intrinsic(_BitScanReverse) #if !PX_DOXYGEN namespace physx { -namespace intrinsics -{ #endif -//! \brief platform-specific absolute value -PX_CUDA_CALLABLE PX_FORCE_INLINE float abs(float a) +/* +* Implements a memory barrier +*/ +PX_FORCE_INLINE void PxMemoryBarrier() { - return ::fabsf(a); + _ReadWriteBarrier(); + /* long Barrier; + __asm { + xchg Barrier, eax + }*/ } -//! \brief platform-specific select float -PX_CUDA_CALLABLE PX_FORCE_INLINE float fsel(float a, float b, float c) +/*! +Returns the index of the highest set bit. Not valid for zero arg. +*/ +PX_FORCE_INLINE uint32_t PxHighestSetBitUnsafe(uint32_t v) { - return (a >= 0.0f) ? b : c; + unsigned long retval; + _BitScanReverse(&retval, v); + return retval; } -//! \brief platform-specific sign -PX_CUDA_CALLABLE PX_FORCE_INLINE float sign(float a) +/*! +Returns the index of the highest set bit. Undefined for zero arg. +*/ +PX_FORCE_INLINE uint32_t PxLowestSetBitUnsafe(uint32_t v) { - return (a >= 0.0f) ? 1.0f : -1.0f; + unsigned long retval; + _BitScanForward(&retval, v); + return retval; } -//! \brief platform-specific reciprocal -PX_CUDA_CALLABLE PX_FORCE_INLINE float recip(float a) +/*! +Returns the number of leading zeros in v. Returns 32 for v=0. +*/ +PX_FORCE_INLINE uint32_t PxCountLeadingZeros(uint32_t v) { - return 1.0f / a; + if(v) + { + unsigned long bsr = (unsigned long)-1; + _BitScanReverse(&bsr, v); + return 31 - bsr; + } + else + return 32; } -//! \brief platform-specific reciprocal estimate -PX_CUDA_CALLABLE PX_FORCE_INLINE float recipFast(float a) +/*! +Prefetch aligned cache size around \c ptr+offset. +*/ +#if !PX_ARM && !PX_A64 +PX_FORCE_INLINE void PxPrefetchLine(const void* ptr, uint32_t offset = 0) { - return 1.0f / a; + // cache line on X86/X64 is 64-bytes so a 128-byte prefetch would require 2 prefetches. + // However, we can only dispatch a limited number of prefetch instructions so we opt to prefetch just 1 cache line + /*_mm_prefetch(((const char*)ptr + offset), _MM_HINT_T0);*/ + // We get slightly better performance prefetching to non-temporal addresses instead of all cache levels + _mm_prefetch(((const char*)ptr + offset), _MM_HINT_NTA); } - -//! \brief platform-specific square root -PX_CUDA_CALLABLE PX_FORCE_INLINE float sqrt(float a) -{ - return ::sqrtf(a); -} - -//! \brief platform-specific reciprocal square root -PX_CUDA_CALLABLE PX_FORCE_INLINE float recipSqrt(float a) -{ - return 1.0f / ::sqrtf(a); -} - -//! \brief platform-specific reciprocal square root estimate -PX_CUDA_CALLABLE PX_FORCE_INLINE float recipSqrtFast(float a) -{ - return 1.0f / ::sqrtf(a); -} - -//! \brief platform-specific sine -PX_CUDA_CALLABLE PX_FORCE_INLINE float sin(float a) -{ - return ::sinf(a); -} - -//! \brief platform-specific cosine -PX_CUDA_CALLABLE PX_FORCE_INLINE float cos(float a) -{ - return ::cosf(a); -} - -//! \brief platform-specific minimum -PX_CUDA_CALLABLE PX_FORCE_INLINE float selectMin(float a, float b) -{ - return a < b ? a : b; -} - -//! \brief platform-specific maximum -PX_CUDA_CALLABLE PX_FORCE_INLINE float selectMax(float a, float b) -{ - return a > b ? a : b; -} - -//! \brief platform-specific finiteness check (not INF or NAN) -PX_CUDA_CALLABLE PX_FORCE_INLINE bool isFinite(float a) -{ -#ifdef __CUDACC__ - return !!isfinite(a); #else - return (0 == ((_FPCLASS_SNAN | _FPCLASS_QNAN | _FPCLASS_NINF | _FPCLASS_PINF) & _fpclass(a))); -#endif -} - -//! \brief platform-specific finiteness check (not INF or NAN) -PX_CUDA_CALLABLE PX_FORCE_INLINE bool isFinite(double a) +PX_FORCE_INLINE void PxPrefetchLine(const void* ptr, uint32_t offset = 0) { -#ifdef __CUDACC__ - return !!isfinite(a); + // arm does have 32b cache line size + __prefetch(((const char*)ptr + offset)); +} +#endif + +/*! +Prefetch \c count bytes starting at \c ptr. +*/ +#if !PX_ARM +PX_FORCE_INLINE void PxPrefetch(const void* ptr, uint32_t count = 1) +{ + const char* cp = (char*)ptr; + uint64_t p = size_t(ptr); + uint64_t startLine = p >> 6, endLine = (p + count - 1) >> 6; + uint64_t lines = endLine - startLine + 1; + do + { + PxPrefetchLine(cp); + cp += 64; + } while(--lines); +} #else - return (0 == ((_FPCLASS_SNAN | _FPCLASS_QNAN | _FPCLASS_NINF | _FPCLASS_PINF) & _fpclass(a))); +PX_FORCE_INLINE void PxPrefetch(const void* ptr, uint32_t count = 1) +{ + const char* cp = (char*)ptr; + uint32_t p = size_t(ptr); + uint32_t startLine = p >> 5, endLine = (p + count - 1) >> 5; + uint32_t lines = endLine - startLine + 1; + do + { + PxPrefetchLine(cp); + cp += 32; + } while(--lines); +} #endif -} - -/*! -Sets \c count bytes starting at \c dst to zero. -*/ -PX_FORCE_INLINE void* memZero(void* dest, uint32_t count) -{ - return memset(dest, 0, count); -} - -/*! -Sets \c count bytes starting at \c dst to \c c. -*/ -PX_FORCE_INLINE void* memSet(void* dest, int32_t c, uint32_t count) -{ - return memset(dest, c, count); -} - -/*! -Copies \c count bytes from \c src to \c dst. User memMove if regions overlap. -*/ -PX_FORCE_INLINE void* memCopy(void* dest, const void* src, uint32_t count) -{ - return memcpy(dest, src, count); -} - -/*! -Copies \c count bytes from \c src to \c dst. Supports overlapping regions. -*/ -PX_FORCE_INLINE void* memMove(void* dest, const void* src, uint32_t count) -{ - return memmove(dest, src, count); -} - -/*! -Set 128B to zero starting at \c dst+offset. Must be aligned. -*/ -PX_FORCE_INLINE void memZero128(void* dest, uint32_t offset = 0) -{ - PX_SHARED_ASSERT(((size_t(dest) + offset) & 0x7f) == 0); - memSet(reinterpret_cast(dest) + offset, 0, 128); -} #if !PX_DOXYGEN -} // namespace intrinsics } // namespace physx #endif -#endif // #ifndef PXFOUNDATION_PXWINDOWSINTRINSICS_H +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/windows/PxWindowsMathIntrinsics.h b/Source/ThirdParty/PhysX/foundation/windows/PxWindowsMathIntrinsics.h new file mode 100644 index 000000000..1eed28188 --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/windows/PxWindowsMathIntrinsics.h @@ -0,0 +1,179 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_WINDOWS_MATH_INTRINSICS_H +#define PX_WINDOWS_MATH_INTRINSICS_H + +#include "foundation/Px.h" +#include "foundation/PxAssert.h" + +#if !PX_WINDOWS_FAMILY +#error "This file should only be included by Windows builds!!" +#endif + +#include +#include + +#if !PX_DOXYGEN +namespace physx +{ +namespace intrinsics +{ +#endif + +//! \brief platform-specific absolute value +PX_CUDA_CALLABLE PX_FORCE_INLINE float abs(float a) +{ + return ::fabsf(a); +} + +//! \brief platform-specific select float +PX_CUDA_CALLABLE PX_FORCE_INLINE float fsel(float a, float b, float c) +{ + return (a >= 0.0f) ? b : c; +} + +//! \brief platform-specific sign +PX_CUDA_CALLABLE PX_FORCE_INLINE float sign(float a) +{ + return (a >= 0.0f) ? 1.0f : -1.0f; +} + +//! \brief platform-specific reciprocal +PX_CUDA_CALLABLE PX_FORCE_INLINE float recip(float a) +{ + return 1.0f / a; +} + +//! \brief platform-specific reciprocal estimate +PX_CUDA_CALLABLE PX_FORCE_INLINE float recipFast(float a) +{ + return 1.0f / a; +} + +//! \brief platform-specific square root +PX_CUDA_CALLABLE PX_FORCE_INLINE float sqrt(float a) +{ + return ::sqrtf(a); +} + +//! \brief platform-specific reciprocal square root +PX_CUDA_CALLABLE PX_FORCE_INLINE float recipSqrt(float a) +{ + return 1.0f / ::sqrtf(a); +} + +//! \brief platform-specific reciprocal square root estimate +PX_CUDA_CALLABLE PX_FORCE_INLINE float recipSqrtFast(float a) +{ + return 1.0f / ::sqrtf(a); +} + +//! \brief platform-specific sine +PX_CUDA_CALLABLE PX_FORCE_INLINE float sin(float a) +{ + return ::sinf(a); +} + +//! \brief platform-specific cosine +PX_CUDA_CALLABLE PX_FORCE_INLINE float cos(float a) +{ + return ::cosf(a); +} + +//! \brief platform-specific minimum +PX_CUDA_CALLABLE PX_FORCE_INLINE float selectMin(float a, float b) +{ + return a < b ? a : b; +} + +//! \brief platform-specific maximum +PX_CUDA_CALLABLE PX_FORCE_INLINE float selectMax(float a, float b) +{ + return a > b ? a : b; +} + +//! \brief platform-specific finiteness check (not INF or NAN) +PX_CUDA_CALLABLE PX_FORCE_INLINE bool isFinite(float a) +{ +#ifdef __CUDACC__ + return !!isfinite(a); +#else + return (0 == ((_FPCLASS_SNAN | _FPCLASS_QNAN | _FPCLASS_NINF | _FPCLASS_PINF) & _fpclass(a))); +#endif +} + +//! \brief platform-specific finiteness check (not INF or NAN) +PX_CUDA_CALLABLE PX_FORCE_INLINE bool isFinite(double a) +{ +#ifdef __CUDACC__ + return !!isfinite(a); +#else + return (0 == ((_FPCLASS_SNAN | _FPCLASS_QNAN | _FPCLASS_NINF | _FPCLASS_PINF) & _fpclass(a))); +#endif +} + +/*! +Sets \c count bytes starting at \c dst to zero. +*/ +PX_FORCE_INLINE void* memZero(void* dest, uint32_t count) +{ + return memset(dest, 0, count); +} + +/*! +Sets \c count bytes starting at \c dst to \c c. +*/ +PX_FORCE_INLINE void* memSet(void* dest, int32_t c, uint32_t count) +{ + return memset(dest, c, count); +} + +/*! +Copies \c count bytes from \c src to \c dst. User memMove if regions overlap. +*/ +PX_FORCE_INLINE void* memCopy(void* dest, const void* src, uint32_t count) +{ + return memcpy(dest, src, count); +} + +/*! +Copies \c count bytes from \c src to \c dst. Supports overlapping regions. +*/ +PX_FORCE_INLINE void* memMove(void* dest, const void* src, uint32_t count) +{ + return memmove(dest, src, count); +} + +#if !PX_DOXYGEN +} // namespace intrinsics +} // namespace physx +#endif + +#endif + diff --git a/Source/ThirdParty/PhysX/foundation/windows/PxWindowsTrigConstants.h b/Source/ThirdParty/PhysX/foundation/windows/PxWindowsTrigConstants.h new file mode 100644 index 000000000..673244d03 --- /dev/null +++ b/Source/ThirdParty/PhysX/foundation/windows/PxWindowsTrigConstants.h @@ -0,0 +1,60 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_WINDOWS_TRIG_CONSTANTS_H +#define PX_WINDOWS_TRIG_CONSTANTS_H + +namespace physx +{ +namespace aos +{ + +#define PX_GLOBALCONST extern const __declspec(selectany) + +__declspec(align(16)) struct PX_VECTORF32 +{ + float f[4]; +}; + +PX_GLOBALCONST PX_VECTORF32 g_PXSinCoefficients0 = { { 1.0f, -0.166666667f, 8.333333333e-3f, -1.984126984e-4f } }; +PX_GLOBALCONST PX_VECTORF32 +g_PXSinCoefficients1 = { { 2.755731922e-6f, -2.505210839e-8f, 1.605904384e-10f, -7.647163732e-13f } }; +PX_GLOBALCONST PX_VECTORF32 +g_PXSinCoefficients2 = { { 2.811457254e-15f, -8.220635247e-18f, 1.957294106e-20f, -3.868170171e-23f } }; +PX_GLOBALCONST PX_VECTORF32 g_PXCosCoefficients0 = { { 1.0f, -0.5f, 4.166666667e-2f, -1.388888889e-3f } }; +PX_GLOBALCONST PX_VECTORF32 +g_PXCosCoefficients1 = { { 2.480158730e-5f, -2.755731922e-7f, 2.087675699e-9f, -1.147074560e-11f } }; +PX_GLOBALCONST PX_VECTORF32 +g_PXCosCoefficients2 = { { 4.779477332e-14f, -1.561920697e-16f, 4.110317623e-19f, -8.896791392e-22f } }; +PX_GLOBALCONST PX_VECTORF32 g_PXReciprocalTwoPi = { { PxInvTwoPi, PxInvTwoPi, PxInvTwoPi, PxInvTwoPi } }; +PX_GLOBALCONST PX_VECTORF32 g_PXTwoPi = { { PxTwoPi, PxTwoPi, PxTwoPi, PxTwoPi } }; + +} // namespace aos +} // namespace physx + +#endif diff --git a/Source/ThirdParty/PhysX/geometry/PxBVH.h b/Source/ThirdParty/PhysX/geometry/PxBVH.h new file mode 100644 index 000000000..70d40e5c5 --- /dev/null +++ b/Source/ThirdParty/PhysX/geometry/PxBVH.h @@ -0,0 +1,329 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_BVH_H +#define PX_BVH_H +/** \addtogroup geomutils +@{ +*/ + +#include "common/PxBase.h" +#include "foundation/PxTransform.h" +#include "foundation/PxBounds3.h" +#include "geometry/PxGeometryQueryFlags.h" +#include "geometry/PxReportCallback.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +class PxGeometry; + +/** +\brief Class representing a bounding volume hierarchy. + +PxBVH can be provided to PxScene::addActor. In this case the scene query +pruning structure inside PhysX SDK will store/update one bound per actor. +The scene queries against such an actor will query actor bounds and then +make a local space query against the provided BVH, which is in actor's +local space. + +PxBVH can also be used as a standalone data-structure for arbitrary +purposes, unrelated to PxScene / PxActor. + +@see PxScene::addActor +*/ +class PxBVH : public PxBase +{ +public: + + /** + \brief Raycast test against a BVH. + + \param[in] origin The origin of the ray. + \param[in] unitDir Normalized direction of the ray. + \param[in] maxDist Maximum ray length, has to be in the [0, inf) range + \param[in] maxHits Max number of returned hits = size of 'rayHits' buffer + \param[out] rayHits Raycast hits information, bounds indices + \return Number of hits + @deprecated + */ + PX_DEPRECATED virtual PxU32 raycast(const PxVec3& origin, const PxVec3& unitDir, PxReal maxDist, PxU32 maxHits, PxU32* PX_RESTRICT rayHits) const = 0; + + /** + \brief Sweep test against a BVH. + + \param[in] aabb The axis aligned bounding box to sweep + \param[in] unitDir Normalized direction of the sweep. + \param[in] maxDist Maximum sweep length, has to be in the [0, inf) range + \param[in] maxHits Max number of returned hits = size of 'sweepHits' buffer + \param[out] sweepHits Sweep hits information, bounds indices + \return Number of hits + @deprecated + */ + PX_DEPRECATED virtual PxU32 sweep(const PxBounds3& aabb, const PxVec3& unitDir, PxReal maxDist, PxU32 maxHits, PxU32* PX_RESTRICT sweepHits) const = 0; + + /** + \brief AABB overlap test against a BVH. + + \param[in] aabb The axis aligned bounding box + \param[in] maxHits Max number of returned hits = size of 'overlapHits' buffer + \param[out] overlapHits Overlap hits information, bounds indices + \return Number of hits + @deprecated + */ + PX_DEPRECATED virtual PxU32 overlap(const PxBounds3& aabb, PxU32 maxHits, PxU32* PX_RESTRICT overlapHits) const = 0; + + struct RaycastCallback + { + RaycastCallback() {} + virtual ~RaycastCallback() {} + + // Reports one raycast or sweep hit. + // boundsIndex [in] Index of touched bounds + // distance [in/out] Impact distance. Shrinks the ray if written out. + // return false to abort the query + virtual bool reportHit(PxU32 boundsIndex, PxReal& distance) = 0; + }; + + struct OverlapCallback + { + OverlapCallback() {} + virtual ~OverlapCallback() {} + + // Reports one overlap hit. + // boundsIndex [in] Index of touched bounds + // return false to abort the query + virtual bool reportHit(PxU32 boundsIndex) = 0; + }; + + struct TraversalCallback + { + TraversalCallback() {} + virtual ~TraversalCallback() {} + + // Reports one visited node. + // bounds [in] node bounds + // return true to continue traversing this branch + virtual bool visitNode(const PxBounds3& bounds) = 0; + + // Reports one validated leaf node. Called on leaf nodes after visitNode returns true on them. + // nbPrims [in] number of primitives in the node + // prims [in] primitives in the node (nbPrims entries) + // return false to abort the query + virtual bool reportLeaf(PxU32 nbPrims, const PxU32* prims) = 0; + }; + + /** + \brief Raycast test against a BVH. + + \param[in] origin The origin of the ray. + \param[in] unitDir Normalized direction of the ray. + \param[in] maxDist Maximum ray length, has to be in the [0, inf) range + \param[in] cb Raycast callback, called once per hit + \param[in] queryFlags Optional flags controlling the query. + \return false if query has been aborted + */ + virtual bool raycast(const PxVec3& origin, const PxVec3& unitDir, float maxDist, RaycastCallback& cb, PxGeometryQueryFlags queryFlags = PxGeometryQueryFlag::eDEFAULT) const = 0; + + /** + \brief Sweep test against a BVH. + + \param[in] geom The query volume + \param[in] pose The pose of the query volume + \param[in] unitDir Normalized direction of the sweep. + \param[in] maxDist Maximum sweep length, has to be in the [0, inf) range + \param[in] cb Raycast callback, called once per hit + \param[in] queryFlags Optional flags controlling the query. + \return false if query has been aborted + */ + virtual bool sweep(const PxGeometry& geom, const PxTransform& pose, const PxVec3& unitDir, float maxDist, RaycastCallback& cb, PxGeometryQueryFlags queryFlags = PxGeometryQueryFlag::eDEFAULT) const = 0; + + /** + \brief Overlap test against a BVH. + + \param[in] geom The query volume + \param[in] pose The pose of the query volume + \param[in] cb Overlap callback, called once per hit + \param[in] queryFlags Optional flags controlling the query. + \return false if query has been aborted + */ + virtual bool overlap(const PxGeometry& geom, const PxTransform& pose, OverlapCallback& cb, PxGeometryQueryFlags queryFlags = PxGeometryQueryFlag::eDEFAULT) const = 0; + + /** + \brief Frustum culling test against a BVH. + + This is similar in spirit to an overlap query using a convex object around the frustum. + However this specialized query has better performance, and can support more than the 6 planes + of a frustum, which can be useful in portal-based engines. + + On the other hand this test only returns a conservative number of bounds, i.e. some of the returned + bounds may actually be outside the frustum volume, close to it but not touching it. This is usually + an ok performance trade-off when the function is used for view-frustum culling. + + \param[in] nbPlanes Number of planes. Only 32 planes max are supported. + \param[in] planes Array of planes, should be in the same space as the BVH. + \param[in] cb Overlap callback, called once per visible object + \param[in] queryFlags Optional flags controlling the query. + \return false if query has been aborted + */ + virtual bool cull(PxU32 nbPlanes, const PxPlane* planes, OverlapCallback& cb, PxGeometryQueryFlags queryFlags = PxGeometryQueryFlag::eDEFAULT) const = 0; + + /** + \brief Returns the number of bounds in the BVH. + + You can use #getBounds() to retrieve the bounds. + + \note These are the user-defined bounds passed to the BVH builder, not the internal bounds around each BVH node. + + \return Number of bounds in the BVH. + + @see getBounds() getBoundsForModification() + */ + virtual PxU32 getNbBounds() const = 0; + + /** + \brief Retrieve the read-only bounds in the BVH. + + \note These are the user-defined bounds passed to the BVH builder, not the internal bounds around each BVH node. + + @see PxBounds3 getNbBounds() getBoundsForModification() + */ + virtual const PxBounds3* getBounds() const = 0; + + /** + \brief Retrieve the bounds in the BVH. + + These bounds can be modified. Call refit() after modifications are done. + + \note These are the user-defined bounds passed to the BVH builder, not the internal bounds around each BVH node. + + @see PxBounds3 getNbBounds() getBounds() refit() updateBounds() partialRefit() + */ + PX_FORCE_INLINE PxBounds3* getBoundsForModification() + { + return const_cast(getBounds()); + } + + /** + \brief Refit the BVH. + + This function "refits" the tree, i.e. takes the new (leaf) bounding boxes into account and + recomputes all the BVH bounds accordingly. This is an O(n) operation with n = number of bounds in the BVH. + + This works best with minor bounds modifications, i.e. when the bounds remain close to their initial values. + With large modifications the tree quality degrades more and more, and subsequent query performance suffers. + It might be a better strategy to create a brand new BVH if bounds change drastically. + + This function refits the whole tree after an arbitrary number of bounds have potentially been modified by + users (via getBoundsForModification()). If you only have a small number of bounds to update, it might be + more efficient to use setBounds() and partialRefit() instead. + + @see getNbBounds() getBoundsForModification() updateBounds() partialRefit() + */ + virtual void refit() = 0; + + /** + \brief Update single bounds. + + This is an alternative to getBoundsForModification() / refit(). If you only have a small set of bounds to + update, it can be inefficient to call the refit() function, because it refits the whole BVH. + + Instead, one can update individual bounds with this updateBounds() function. It sets the new bounds and + marks the corresponding BVH nodes for partial refit. Once all the individual bounds have been updated, + call partialRefit() to only refit the subset of marked nodes. + + \param[in] boundsIndex Index of updated bounds. Valid range is between 0 and getNbBounds(). + \param[in] newBounds Updated bounds. + + \return true if success + + @see getNbBounds() getBoundsForModification() refit() partialRefit() + */ + virtual bool updateBounds(PxU32 boundsIndex, const PxBounds3& newBounds) = 0; + + /** + \brief Refits subset of marked nodes. + + This is an alternative to the refit() function, to be called after updateBounds() calls. + See updateBounds() for details. + + @see getNbBounds() getBoundsForModification() refit() updateBounds() + */ + virtual void partialRefit() = 0; + + /** + \brief Generic BVH traversal function. + + This can be used to implement custom BVH traversal functions if provided ones are not enough. + In particular this can be used to visualize the tree's bounds. + + \param[in] cb Traversal callback, called for each visited node + \return false if query has been aborted + */ + virtual bool traverse(TraversalCallback& cb) const = 0; + + virtual const char* getConcreteTypeName() const { return "PxBVH"; } +protected: + PX_INLINE PxBVH(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags) {} + PX_INLINE PxBVH(PxBaseFlags baseFlags) : PxBase(baseFlags) {} + virtual ~PxBVH() {} + + virtual bool isKindOf(const char* name) const { return !::strcmp("PxBVH", name) || PxBase::isKindOf(name); } +}; + + struct PxGeomIndexPair; + + /** + \brief BVH-vs-BVH overlap test + + This function returns pairs of box indices that belong to both the first & second input bvhs. + + \param[in] callback The callback object used to report results + \param[in] bvh0 First bvh + \param[in] bvh1 Second bvh + \return true if an overlap has been detected + + @see PxBVH PxReportCallback + */ + PX_C_EXPORT PX_PHYSX_COMMON_API bool PX_CALL_CONV PxFindOverlap(PxReportCallback& callback, const PxBVH& bvh0, const PxBVH& bvh1); + +//! @cond + /** + * @deprecated + */ + typedef PX_DEPRECATED PxBVH PxBVHStructure; +//! @endcond + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/geometry/PxBVHBuildStrategy.h b/Source/ThirdParty/PhysX/geometry/PxBVHBuildStrategy.h new file mode 100644 index 000000000..4397201b0 --- /dev/null +++ b/Source/ThirdParty/PhysX/geometry/PxBVHBuildStrategy.h @@ -0,0 +1,62 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_BVH_BUILD_STRATEGY_H +#define PX_BVH_BUILD_STRATEGY_H +/** \addtogroup geomutils +@{ +*/ + +#include "common/PxPhysXCommonConfig.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +/** +\brief Desired build strategy for bounding-volume hierarchies +*/ +struct PxBVHBuildStrategy +{ + enum Enum + { + eFAST = 0, //!< Fast build strategy. Fast build speed, good runtime performance in most cases. Recommended for runtime cooking. + eDEFAULT = 1, //!< Default build strategy. Medium build speed, good runtime performance in all cases. + eSAH = 2, //!< SAH build strategy. Slower builds, slightly improved runtime performance in some cases. + + eLAST + }; +}; + +#if !PX_DOXYGEN +} // namespace physx +#endif + + /** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/geometry/PxBVHStructure.h b/Source/ThirdParty/PhysX/geometry/PxBVHStructure.h deleted file mode 100644 index 1ff9d3f20..000000000 --- a/Source/ThirdParty/PhysX/geometry/PxBVHStructure.h +++ /dev/null @@ -1,138 +0,0 @@ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of NVIDIA CORPORATION nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. -// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. -// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - - -#ifndef PX_PHYSICS_BVH_STRUCTURE -#define PX_PHYSICS_BVH_STRUCTURE -/** \addtogroup geomutils -@{ -*/ - -#include "common/PxBase.h" -#include "foundation/PxTransform.h" -#include "foundation/PxBounds3.h" - -#if !PX_DOXYGEN -namespace physx -{ -#endif - -/** -\brief Class representing the bounding volume hierarchy structure. - -PxBVHStructure can be provided to PxScene::addActor. In this case the scene query -pruning structure inside PhysX SDK will store/update one bound per actor. -The scene queries against such an actor will query actor bounds and then -make a local space query against the provided BVH structure, which is in -actor's local space. - -@see PxScene::addActor -*/ -class PxBVHStructure: public PxBase -{ -public: - - /** - \brief Raycast test against a BVH structure. - - \param[in] origin The origin of the ray. - \param[in] unitDir Normalized direction of the ray. - \param[in] maxDist Maximum ray length, has to be in the [0, inf) range - \param[in] maxHits Max number of returned hits = size of 'rayHits' buffer - \param[out] rayHits Raycast hits information, bounds indices - \return Number of hits - */ - virtual PxU32 raycast(const PxVec3& origin, - const PxVec3& unitDir, - PxReal maxDist, - PxU32 maxHits, - PxU32* PX_RESTRICT rayHits) const = 0; - - /** - \brief Sweep test against a BVH structure. - - \param[in] aabb The axis aligned bounding box to sweep - \param[in] unitDir Normalized direction of the sweep. - \param[in] maxDist Maximum sweep length, has to be in the [0, inf) range - \param[in] maxHits Max number of returned hits = size of 'sweepHits' buffer - \param[out] sweepHits Sweep hits information, bounds indices - \return Number of hits - */ - virtual PxU32 sweep(const PxBounds3& aabb, - const PxVec3& unitDir, - PxReal maxDist, - PxU32 maxHits, - PxU32* PX_RESTRICT sweepHits) const = 0; - - /** - \brief AABB overlap test against a BVH structure. - - \param[in] aabb The axis aligned bounding box - \param[in] maxHits Max number of returned hits = size of 'overlapHits' buffer - \param[out] overlapHits Overlap hits information, bounds indices - \return Number of hits - */ - virtual PxU32 overlap(const PxBounds3& aabb, - PxU32 maxHits, - PxU32* PX_RESTRICT overlapHits) const = 0; - - /** - \brief Retrieve the bounds in the BVH. - - @see PxBounds3 - */ - virtual const PxBounds3* getBounds() const = 0; - - /** - \brief Returns the number of bounds in the BVH. - - You can use #getBounds() to retrieve the bounds. - - \return Number of bounds in the BVH. - - */ - virtual PxU32 getNbBounds() const = 0; - - virtual const char* getConcreteTypeName() const { return "PxBVHStructure"; } -protected: - PX_INLINE PxBVHStructure(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags) {} - PX_INLINE PxBVHStructure(PxBaseFlags baseFlags) : PxBase(baseFlags) {} - virtual ~PxBVHStructure() {} - - virtual bool isKindOf(const char* name) const { return !::strcmp("PxBVHStructure", name) || PxBase::isKindOf(name); } - -}; - - -#if !PX_DOXYGEN -} // namespace physx -#endif - -/** @} */ -#endif diff --git a/Source/ThirdParty/PhysX/geometry/PxBoxGeometry.h b/Source/ThirdParty/PhysX/geometry/PxBoxGeometry.h index 0c24790ee..de04acc06 100644 --- a/Source/ThirdParty/PhysX/geometry/PxBoxGeometry.h +++ b/Source/ThirdParty/PhysX/geometry/PxBoxGeometry.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_NX_BOX_GEOMETRY -#define PX_PHYSICS_NX_BOX_GEOMETRY +#ifndef PX_BOX_GEOMETRY_H +#define PX_BOX_GEOMETRY_H /** \addtogroup geomutils @{ */ @@ -50,24 +48,35 @@ The geometry of a box can be fully specified by its half extents. This is the h class PxBoxGeometry : public PxGeometry { public: - /** - \brief Default constructor, initializes to a box with zero dimensions. - */ - PX_INLINE PxBoxGeometry() : PxGeometry(PxGeometryType::eBOX), halfExtents(0,0,0) {} - /** \brief Constructor to initialize half extents from scalar parameters. \param hx Initial half extents' x component. \param hy Initial half extents' y component. \param hz Initial half extents' z component. */ - PX_INLINE PxBoxGeometry(PxReal hx, PxReal hy, PxReal hz) : PxGeometry(PxGeometryType::eBOX), halfExtents(hx, hy, hz) {} + PX_INLINE PxBoxGeometry(PxReal hx=0.0f, PxReal hy=0.0f, PxReal hz=0.0f) : PxGeometry(PxGeometryType::eBOX), halfExtents(hx, hy, hz) {} /** \brief Constructor to initialize half extents from vector parameter. \param halfExtents_ Initial half extents. */ - PX_INLINE PxBoxGeometry(PxVec3 halfExtents_) : PxGeometry(PxGeometryType::eBOX), halfExtents(halfExtents_) {} + PX_INLINE PxBoxGeometry(PxVec3 halfExtents_) : PxGeometry(PxGeometryType::eBOX), halfExtents(halfExtents_) {} + + /** + \brief Copy constructor. + + \param[in] that Other object + */ + PX_INLINE PxBoxGeometry(const PxBoxGeometry& that) : PxGeometry(that), halfExtents(that.halfExtents) {} + + /** + \brief Assignment operator + */ + PX_INLINE void operator=(const PxBoxGeometry& that) + { + mType = that.mType; + halfExtents = that.halfExtents; + } /** \brief Returns true if the geometry is valid. @@ -88,14 +97,13 @@ public: PxVec3 halfExtents; }; - PX_INLINE bool PxBoxGeometry::isValid() const { - if (mType != PxGeometryType::eBOX) + if(mType != PxGeometryType::eBOX) return false; - if (!halfExtents.isFinite()) + if(!halfExtents.isFinite()) return false; - if (halfExtents.x <= 0.0f || halfExtents.y <= 0.0f || halfExtents.z <= 0.0f) + if(halfExtents.x <= 0.0f || halfExtents.y <= 0.0f || halfExtents.z <= 0.0f) return false; return true; diff --git a/Source/ThirdParty/PhysX/geometry/PxCapsuleGeometry.h b/Source/ThirdParty/PhysX/geometry/PxCapsuleGeometry.h index 33774e1c3..69a59f9ff 100644 --- a/Source/ThirdParty/PhysX/geometry/PxCapsuleGeometry.h +++ b/Source/ThirdParty/PhysX/geometry/PxCapsuleGeometry.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_NX_CAPSULE_GEOMETRY -#define PX_PHYSICS_NX_CAPSULE_GEOMETRY +#ifndef PX_CAPSULE_GEOMETRY_H +#define PX_CAPSULE_GEOMETRY_H /** \addtogroup geomutils @{ */ @@ -55,22 +53,34 @@ The function PxTransformFromSegment is a helper for generating an appropriate tr class PxCapsuleGeometry : public PxGeometry { public: - /** - \brief Default constructor, initializes to a capsule with zero height and radius. - */ - PX_INLINE PxCapsuleGeometry() : PxGeometry(PxGeometryType::eCAPSULE), radius(0), halfHeight(0) {} - /** \brief Constructor, initializes to a capsule with passed radius and half height. */ - PX_INLINE PxCapsuleGeometry(PxReal radius_, PxReal halfHeight_) : PxGeometry(PxGeometryType::eCAPSULE), radius(radius_), halfHeight(halfHeight_) {} + PX_INLINE PxCapsuleGeometry(PxReal radius_=0.0f, PxReal halfHeight_=0.0f) : PxGeometry(PxGeometryType::eCAPSULE), radius(radius_), halfHeight(halfHeight_) {} + + /** + \brief Copy constructor. + + \param[in] that Other object + */ + PX_INLINE PxCapsuleGeometry(const PxCapsuleGeometry& that) : PxGeometry(that), radius(that.radius), halfHeight(that.halfHeight) {} + + /** + \brief Assignment operator + */ + PX_INLINE void operator=(const PxCapsuleGeometry& that) + { + mType = that.mType; + radius = that.radius; + halfHeight = that.halfHeight; + } /** \brief Returns true if the geometry is valid. \return True if the current settings are valid. - \note A valid capsule has radius > 0, halfHeight > 0. + \note A valid capsule has radius > 0, halfHeight >= 0. It is illegal to call PxRigidActor::createShape and PxPhysics::createShape with a capsule that has zero radius or height. @see PxRigidActor::createShape, PxPhysics::createShape @@ -89,31 +99,18 @@ public: PxReal halfHeight; }; - PX_INLINE bool PxCapsuleGeometry::isValid() const { - if (mType != PxGeometryType::eCAPSULE) + if(mType != PxGeometryType::eCAPSULE) return false; - if (!PxIsFinite(radius) || !PxIsFinite(halfHeight)) + if(!PxIsFinite(radius) || !PxIsFinite(halfHeight)) return false; - if (radius <= 0.0f || halfHeight <= 0.0f) + if(radius <= 0.0f || halfHeight < 0.0f) return false; return true; } - -/** \brief creates a transform from the endpoints of a segment, suitable for an actor transform for a PxCapsuleGeometry - -\param[in] p0 one end of major axis of the capsule -\param[in] p1 the other end of the axis of the capsule -\param[out] halfHeight the halfHeight of the capsule. This parameter is optional. -\return A PxTransform which will transform the vector (1,0,0) to the capsule axis shrunk by the halfHeight -*/ - -PX_FOUNDATION_API PxTransform PxTransformFromSegment(const PxVec3& p0, const PxVec3& p1, PxReal* halfHeight = NULL); - - #if !PX_DOXYGEN } // namespace physx #endif diff --git a/Source/ThirdParty/PhysX/geometry/PxConvexMesh.h b/Source/ThirdParty/PhysX/geometry/PxConvexMesh.h index 80434ed78..a0c945732 100644 --- a/Source/ThirdParty/PhysX/geometry/PxConvexMesh.h +++ b/Source/ThirdParty/PhysX/geometry/PxConvexMesh.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_GEOMUTILS_NX_CONVEXMESH -#define PX_PHYSICS_GEOMUTILS_NX_CONVEXMESH +#ifndef PX_CONVEX_MESH_H +#define PX_CONVEX_MESH_H /** \addtogroup geomutils @{ */ @@ -81,7 +79,7 @@ once you have released all of its #PxShape instances. @see PxConvexMeshDesc PxPhysics.createConvexMesh() */ -class PxConvexMesh : public PxBase +class PxConvexMesh : public PxRefCounted { public: @@ -90,28 +88,28 @@ public: \return Number of vertices. @see getVertices() */ - PX_PHYSX_COMMON_API virtual PxU32 getNbVertices() const = 0; + virtual PxU32 getNbVertices() const = 0; /** \brief Returns the vertices. \return Array of vertices. @see getNbVertices() */ - PX_PHYSX_COMMON_API virtual const PxVec3* getVertices() const = 0; + virtual const PxVec3* getVertices() const = 0; /** \brief Returns the index buffer. \return Index buffer. @see getNbPolygons() getPolygonData() */ - PX_PHYSX_COMMON_API virtual const PxU8* getIndexBuffer() const = 0; + virtual const PxU8* getIndexBuffer() const = 0; /** \brief Returns the number of polygons. \return Number of polygons. @see getIndexBuffer() getPolygonData() */ - PX_PHYSX_COMMON_API virtual PxU32 getNbPolygons() const = 0; + virtual PxU32 getNbPolygons() const = 0; /** \brief Returns the polygon data. @@ -120,31 +118,14 @@ public: \return True if success. @see getIndexBuffer() getNbPolygons() */ - PX_PHYSX_COMMON_API virtual bool getPolygonData(PxU32 index, PxHullPolygon& data) const = 0; + virtual bool getPolygonData(PxU32 index, PxHullPolygon& data) const = 0; /** \brief Decrements the reference count of a convex mesh and releases it if the new reference count is zero. @see PxPhysics.createConvexMesh() PxConvexMeshGeometry PxShape */ - PX_PHYSX_COMMON_API virtual void release() = 0; - - /** - \brief Returns the reference count of a convex mesh. - - At creation, the reference count of the convex mesh is 1. Every shape referencing this convex mesh increments the - count by 1. When the reference count reaches 0, and only then, the convex mesh gets destroyed automatically. - - \return the current reference count. - */ - PX_PHYSX_COMMON_API virtual PxU32 getReferenceCount() const = 0; - - /** - \brief Acquires a counted reference to a convex mesh. - - This method increases the reference count of the convex mesh by 1. Decrement the reference count by calling release() - */ - PX_PHYSX_COMMON_API virtual void acquireReference() = 0; + virtual void release() = 0; /** \brief Returns the mass properties of the mesh assuming unit density. @@ -162,16 +143,23 @@ public: \param[out] localInertia The inertia tensor in mesh local space assuming unit density. \param[out] localCenterOfMass Position of center of mass (or centroid) in mesh local space. */ - PX_PHYSX_COMMON_API virtual void getMassInformation(PxReal& mass, PxMat33& localInertia, PxVec3& localCenterOfMass) const = 0; + virtual void getMassInformation(PxReal& mass, PxMat33& localInertia, PxVec3& localCenterOfMass) const = 0; /** \brief Returns the local-space (vertex space) AABB from the convex mesh. \return local-space bounds */ - PX_PHYSX_COMMON_API virtual PxBounds3 getLocalBounds() const = 0; + virtual PxBounds3 getLocalBounds() const = 0; - PX_PHYSX_COMMON_API virtual const char* getConcreteTypeName() const { return "PxConvexMesh"; } + /** + \brief Returns the local-space Signed Distance Field for this mesh if it has one. + \return local-space SDF. + */ + virtual const PxReal* getSDF() const = 0; + + + virtual const char* getConcreteTypeName() const { return "PxConvexMesh"; } /** \brief This method decides whether a convex mesh is gpu compatible. If the total number of vertices are more than 64 or any number of vertices in a polygon is more than 32, or @@ -180,13 +168,14 @@ public: \return True if the convex hull is gpu compatible */ - PX_PHYSX_COMMON_API virtual bool isGpuCompatible() const = 0; + virtual bool isGpuCompatible() const = 0; + protected: - PX_INLINE PxConvexMesh(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags) {} - PX_INLINE PxConvexMesh(PxBaseFlags baseFlags) : PxBase(baseFlags) {} - PX_PHYSX_COMMON_API virtual ~PxConvexMesh() {} - PX_PHYSX_COMMON_API virtual bool isKindOf(const char* name) const { return !::strcmp("PxConvexMesh", name) || PxBase::isKindOf(name); } + PX_INLINE PxConvexMesh(PxType concreteType, PxBaseFlags baseFlags) : PxRefCounted(concreteType, baseFlags) {} + PX_INLINE PxConvexMesh(PxBaseFlags baseFlags) : PxRefCounted(baseFlags) {} + virtual ~PxConvexMesh() {} + virtual bool isKindOf(const char* name) const { return !::strcmp("PxConvexMesh", name) || PxRefCounted::isKindOf(name); } }; #if !PX_DOXYGEN diff --git a/Source/ThirdParty/PhysX/geometry/PxConvexMeshGeometry.h b/Source/ThirdParty/PhysX/geometry/PxConvexMeshGeometry.h index 625337498..1a35d3397 100644 --- a/Source/ThirdParty/PhysX/geometry/PxConvexMeshGeometry.h +++ b/Source/ThirdParty/PhysX/geometry/PxConvexMeshGeometry.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_NX_CONVEXMESH_GEOMETRY -#define PX_PHYSICS_NX_CONVEXMESH_GEOMETRY +#ifndef PX_CONVEX_MESH_GEOMETRY_H +#define PX_CONVEX_MESH_GEOMETRY_H /** \addtogroup geomutils @{ */ @@ -81,25 +79,14 @@ class PxConvexMeshGeometry : public PxGeometry { public: /** - \brief Default constructor. + \brief Constructor. By default creates an empty object with a NULL mesh and identity scale. - Creates an empty object with a NULL mesh and identity scale. - */ - PX_INLINE PxConvexMeshGeometry() : - PxGeometry (PxGeometryType::eCONVEXMESH), - scale (PxMeshScale(1.0f)), - convexMesh (NULL), - meshFlags (PxConvexMeshGeometryFlag::eTIGHT_BOUNDS) - {} - - /** - \brief Constructor. \param[in] mesh Mesh pointer. May be NULL, though this will not make the object valid for shape construction. \param[in] scaling Scale factor. \param[in] flags Mesh flags. \ */ - PX_INLINE PxConvexMeshGeometry( PxConvexMesh* mesh, + PX_INLINE PxConvexMeshGeometry( PxConvexMesh* mesh = NULL, const PxMeshScale& scaling = PxMeshScale(), PxConvexMeshGeometryFlags flags = PxConvexMeshGeometryFlag::eTIGHT_BOUNDS) : PxGeometry (PxGeometryType::eCONVEXMESH), @@ -109,6 +96,30 @@ public: { } + /** + \brief Copy constructor. + + \param[in] that Other object + */ + PX_INLINE PxConvexMeshGeometry(const PxConvexMeshGeometry& that) : + PxGeometry (that), + scale (that.scale), + convexMesh (that.convexMesh), + meshFlags (that.meshFlags) + { + } + + /** + \brief Assignment operator + */ + PX_INLINE void operator=(const PxConvexMeshGeometry& that) + { + mType = that.mType; + scale = that.scale; + convexMesh = that.convexMesh; + meshFlags = that.meshFlags; + } + /** \brief Returns true if the geometry is valid. diff --git a/Source/ThirdParty/PhysX/geometry/PxCustomGeometry.h b/Source/ThirdParty/PhysX/geometry/PxCustomGeometry.h new file mode 100644 index 000000000..2fb9f686b --- /dev/null +++ b/Source/ThirdParty/PhysX/geometry/PxCustomGeometry.h @@ -0,0 +1,310 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_CUSTOMGEOMETRY_H +#define PX_CUSTOMGEOMETRY_H +/** \addtogroup geomutils +@{ +*/ + +#include "geometry/PxGeometry.h" +#include "geometry/PxGeometryHit.h" +#include "geometry/PxGeometryQueryContext.h" +#include "foundation/PxFoundationConfig.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + class PxContactBuffer; + class PxRenderOutput; + class PxMassProperties; + + /** + \brief Custom geometry class. This class allows user to create custom geometries by providing a set of virtual callback functions. + */ + class PxCustomGeometry : public PxGeometry + { + public: + /** + \brief For internal use + */ + PX_PHYSX_COMMON_API static PxU32 getUniqueID(); + + /** + \brief The type of a custom geometry. Allows to identify a particular kind of it. + */ + struct Type + { + /** + \brief Default constructor + */ + PX_INLINE Type() : mID(getUniqueID()) {} + + /** + \brief Default constructor + */ + PX_INLINE Type(const Type& t) : mID(t.mID) {} + + /** + \brief Assigment operator + */ + PX_INLINE Type& operator = (const Type& t) { mID = t.mID; return *this; } + + /** + \brief Equality operator + */ + PX_INLINE bool operator == (const Type& t) const { return mID == t.mID; } + + /** + \brief Inequality operator + */ + PX_INLINE bool operator != (const Type& t) const { return mID != t.mID; } + + /** + \brief Invalid type + */ + PX_INLINE static Type INVALID() { PxU32 z(0); return reinterpret_cast(z); } + + private: + PxU32 mID; + }; + + /** + \brief Custom geometry callbacks structure. User should inherit this and implement all pure virtual functions. + */ + struct Callbacks + { + /** + \brief Return custom type. The type purpose is for user to differentiate custom geometries. Not used by PhysX. + + \return Unique ID of a custom geometry type. + + \note User should use DECLARE_CUSTOM_GEOMETRY_TYPE and IMPLEMENT_CUSTOM_GEOMETRY_TYPE intead of overwriting this function. + */ + virtual Type getCustomType() const = 0; + + /** + \brief Return local bounds. + + \param[in] geometry This geometry. + + \return Bounding box in the geometry local space. + */ + virtual PxBounds3 getLocalBounds(const PxGeometry& geometry) const = 0; + + /** + \brief Contacts generation. Generate collision contacts between two geometries in given poses. + + \param[in] geom0 This custom geometry + \param[in] geom1 The other geometry + \param[in] pose0 This custom geometry pose + \param[in] pose1 The other geometry pose + \param[in] contactDistance The distance at which contacts begin to be generated between the pairs + \param[in] meshContactMargin The mesh contact margin. + \param[in] toleranceLength The toleranceLength. Used for scaling distance-based thresholds internally to produce appropriate results given simulations in different units + \param[out] contactBuffer A buffer to write contacts to. + + \return True if there are contacts. False otherwise. + */ + virtual bool generateContacts(const PxGeometry& geom0, const PxGeometry& geom1, const PxTransform& pose0, const PxTransform& pose1, + const PxReal contactDistance, const PxReal meshContactMargin, const PxReal toleranceLength, + PxContactBuffer& contactBuffer) const = 0; + + /** + \brief Raycast. Cast a ray against the geometry in given pose. + + \param[in] origin Origin of the ray. + \param[in] unitDir Normalized direction of the ray. + \param[in] geom This custom geometry + \param[in] pose This custom geometry pose + \param[in] maxDist Length of the ray. Has to be in the [0, inf) range. + \param[in] hitFlags Specifies which properties per hit should be computed and returned via the hit callback. + \param[in] maxHits max number of returned hits = size of 'rayHits' buffer + \param[out] rayHits Ray hits. + \param[in] stride Ray hit structure stride. + \param[in] threadContext Optional user-defined per-thread context. + + \return Number of hits. + */ + virtual PxU32 raycast(const PxVec3& origin, const PxVec3& unitDir, const PxGeometry& geom, const PxTransform& pose, + PxReal maxDist, PxHitFlags hitFlags, PxU32 maxHits, PxGeomRaycastHit* rayHits, PxU32 stride, PxRaycastThreadContext* threadContext) const = 0; + + /** + \brief Overlap. Test if geometries overlap. + + \param[in] geom0 This custom geometry + \param[in] pose0 This custom geometry pose + \param[in] geom1 The other geometry + \param[in] pose1 The other geometry pose + \param[in] threadContext Optional user-defined per-thread context. + + \return True if there is overlap. False otherwise. + */ + virtual bool overlap(const PxGeometry& geom0, const PxTransform& pose0, const PxGeometry& geom1, const PxTransform& pose1, PxOverlapThreadContext* threadContext) const = 0; + + /** + \brief Sweep. Sweep one geometry against the other. + + \param[in] unitDir Normalized direction of the sweep. + \param[in] maxDist Length of the sweep. Has to be in the [0, inf) range. + \param[in] geom0 This custom geometry + \param[in] pose0 This custom geometry pose + \param[in] geom1 The other geometry + \param[in] pose1 The other geometry pose + \param[out] sweepHit Used to report the sweep hit. + \param[in] hitFlags Specifies which properties per hit should be computed and returned via the hit callback. + \param[in] inflation This parameter creates a skin around the swept geometry which increases its extents for sweeping. + \param[in] threadContext Optional user-defined per-thread context. + + \return True if there is hit. False otherwise. + */ + virtual bool sweep(const PxVec3& unitDir, const PxReal maxDist, + const PxGeometry& geom0, const PxTransform& pose0, const PxGeometry& geom1, const PxTransform& pose1, + PxGeomSweepHit& sweepHit, PxHitFlags hitFlags, const PxReal inflation, PxSweepThreadContext* threadContext) const = 0; + + /** + \brief Visualize custom geometry for debugging. Optional. + + \param[in] geometry This geometry. + \param[in] out Render output. + \param[in] absPose Geometry absolute transform. + \param[in] cullbox Region to visualize. + */ + virtual void visualize(const PxGeometry& geometry, PxRenderOutput& out, const PxTransform& absPose, const PxBounds3& cullbox) const = 0; + + /** + \brief Compute custom geometry mass properties. For geometries usable with dynamic rigidbodies. + + \param[in] geometry This geometry. + \param[out] massProperties Mass properties to compute. + */ + virtual void computeMassProperties(const PxGeometry& geometry, PxMassProperties& massProperties) const = 0; + + /** + \brief Compatible with PhysX's PCM feature. Allows to optimize contact generation. + + \param[in] geometry This geometry. + \param[out] breakingThreshold The threshold to trigger contacts re-generation. + */ + virtual bool usePersistentContactManifold(const PxGeometry& geometry, PxReal& breakingThreshold) const = 0; + + /* Destructor */ + virtual ~Callbacks() {} + }; + + /** + \brief Default constructor. + + Creates an empty object with a NULL callbacks pointer. + */ + PX_INLINE PxCustomGeometry() : + PxGeometry(PxGeometryType::eCUSTOM), + callbacks(NULL) + {} + + /** + \brief Constructor. + */ + PX_INLINE PxCustomGeometry(Callbacks& _callbacks) : + PxGeometry(PxGeometryType::eCUSTOM), + callbacks(&_callbacks) + {} + + /** + \brief Copy constructor. + + \param[in] that Other object + */ + PX_INLINE PxCustomGeometry(const PxCustomGeometry& that) : + PxGeometry(that), + callbacks(that.callbacks) + {} + + /** + \brief Assignment operator + */ + PX_INLINE void operator=(const PxCustomGeometry& that) + { + mType = that.mType; + callbacks = that.callbacks; + } + + /** + \brief Returns true if the geometry is valid. + + \return True if the current settings are valid for shape creation. + + @see PxRigidActor::createShape, PxPhysics::createShape + */ + PX_INLINE bool isValid() const; + + /** + \brief Returns the custom type of the custom geometry. + */ + PX_INLINE Type getCustomType() const + { + return callbacks ? callbacks->getCustomType() : Type::INVALID(); + } + + public: + Callbacks* callbacks; //!< A reference to the callbacks object. + }; + + PX_INLINE bool PxCustomGeometry::isValid() const + { + return mType == PxGeometryType::eCUSTOM && callbacks != NULL; + } + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** +\brief Used in pair with IMPLEMENT_CUSTOM_GEOMETRY_TYPE to overwrite Callbacks::getCustomType() callback. +*/ +#define DECLARE_CUSTOM_GEOMETRY_TYPE \ + static ::physx::PxCustomGeometry::Type TYPE(); \ + virtual ::physx::PxCustomGeometry::Type getCustomType() const; + +/** +\brief Used in pair with DECLARE_CUSTOM_GEOMETRY_TYPE to overwrite Callbacks::getCustomType() callback. +*/ +#define IMPLEMENT_CUSTOM_GEOMETRY_TYPE(CLASS) \ +::physx::PxCustomGeometry::Type CLASS::TYPE() \ +{ \ + static ::physx::PxCustomGeometry::Type customType; \ + return customType; \ +} \ +::physx::PxCustomGeometry::Type CLASS::getCustomType() const \ +{ \ + return TYPE(); \ +} + +/** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/geometry/PxGeometry.h b/Source/ThirdParty/PhysX/geometry/PxGeometry.h index 2ef93b94c..043484c66 100644 --- a/Source/ThirdParty/PhysX/geometry/PxGeometry.h +++ b/Source/ThirdParty/PhysX/geometry/PxGeometry.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_NX_GEOMETRY -#define PX_PHYSICS_NX_GEOMETRY +#ifndef PX_GEOMETRY_H +#define PX_GEOMETRY_H /** \addtogroup geomutils @{ */ @@ -57,8 +55,13 @@ struct PxGeometryType eCAPSULE, eBOX, eCONVEXMESH, + ePARTICLESYSTEM, + eTETRAHEDRONMESH, eTRIANGLEMESH, eHEIGHTFIELD, + eHAIRSYSTEM, + eCUSTOM, + eGEOMETRY_COUNT, //!< internal use only! eINVALID = -1 //!< internal use only! }; @@ -72,8 +75,8 @@ about its placement in the world. \note This is an abstract class. You cannot create instances directly. Create an instance of one of the derived classes instead. */ -class PxGeometry -{ +class PxGeometry +{ public: /** \brief Returns the type of the geometry. @@ -81,9 +84,22 @@ public: */ PX_CUDA_CALLABLE PX_FORCE_INLINE PxGeometryType::Enum getType() const { return mType; } + /** + \brief Assignment operator + */ + PX_INLINE void operator=(const PxGeometry& that) + { + mType = that.mType; + } + protected: - PX_CUDA_CALLABLE PX_FORCE_INLINE PxGeometry(PxGeometryType::Enum type) : mType(type) {} - PxGeometryType::Enum mType; + PX_CUDA_CALLABLE PX_FORCE_INLINE PxGeometry(PxGeometryType::Enum type) : mType(type) {} + PX_CUDA_CALLABLE PX_FORCE_INLINE PxGeometry(const PxGeometry& that) : mType(that.mType) {} + + PxGeometryType::Enum mType; + +public: + float mTypePadding; // PT: padding bytes on x64, used internally }; #if !PX_DOXYGEN diff --git a/Source/ThirdParty/PhysX/geometry/PxGeometryHelpers.h b/Source/ThirdParty/PhysX/geometry/PxGeometryHelpers.h index 5681a930d..02983c1a8 100644 --- a/Source/ThirdParty/PhysX/geometry/PxGeometryHelpers.h +++ b/Source/ThirdParty/PhysX/geometry/PxGeometryHelpers.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_GEOMETRYHELPERS -#define PX_PHYSICS_GEOMETRYHELPERS +#ifndef PX_GEOMETRY_HELPERS_H +#define PX_GEOMETRY_HELPERS_H /** \addtogroup geomutils @{ */ @@ -45,6 +43,10 @@ #include "geometry/PxPlaneGeometry.h" #include "geometry/PxConvexMeshGeometry.h" #include "geometry/PxHeightFieldGeometry.h" +#include "geometry/PxParticleSystemGeometry.h" +#include "geometry/PxHairSystemGeometry.h" +#include "geometry/PxTetrahedronMeshGeometry.h" +#include "geometry/PxCustomGeometry.h" #if !PX_DOXYGEN namespace physx @@ -56,98 +58,68 @@ namespace physx This class contains enough space to hold a value of any PxGeometry subtype. -Its principal use is as a convenience class to allow geometries to be returned polymorphically -from functions. See PxShape::getGeometry(); +Its principal use is as a convenience class to allow geometries to be returned polymorphically from functions. */ PX_ALIGN_PREFIX(4) class PxGeometryHolder { + class PxInvalidGeometry : public PxGeometry + { + public: + PX_INLINE PxInvalidGeometry() : PxGeometry(PxGeometryType::eINVALID) {} + }; + public: PX_FORCE_INLINE PxGeometryType::Enum getType() const { return any().getType(); } - PX_FORCE_INLINE PxGeometry& any() - { - return *PxUnionCast(&bytes.geometry); - } - - PX_FORCE_INLINE const PxGeometry& any() const - { - return *PxUnionCast(&bytes.geometry); - } - - PX_FORCE_INLINE PxSphereGeometry& sphere() + PX_FORCE_INLINE PxGeometry& any() { - return get(); + return *PxUnionCast(&bytes.geometry); } - PX_FORCE_INLINE const PxSphereGeometry& sphere() const + PX_FORCE_INLINE const PxGeometry& any() const { - return get(); + return *PxUnionCast(&bytes.geometry); } - PX_FORCE_INLINE PxPlaneGeometry& plane() - { - return get(); - } +//! @cond + PX_FORCE_INLINE PxSphereGeometry& sphere() { return get(); } + PX_FORCE_INLINE const PxSphereGeometry& sphere() const { return get(); } - PX_FORCE_INLINE const PxPlaneGeometry& plane() const - { - return get(); - } + PX_FORCE_INLINE PxPlaneGeometry& plane() { return get(); } + PX_FORCE_INLINE const PxPlaneGeometry& plane() const { return get(); } - PX_FORCE_INLINE PxCapsuleGeometry& capsule() - { - return get(); - } + PX_FORCE_INLINE PxCapsuleGeometry& capsule() { return get(); } + PX_FORCE_INLINE const PxCapsuleGeometry& capsule() const { return get(); } - PX_FORCE_INLINE const PxCapsuleGeometry& capsule() const - { - return get(); - } + PX_FORCE_INLINE PxBoxGeometry& box() { return get(); } + PX_FORCE_INLINE const PxBoxGeometry& box() const { return get(); } - PX_FORCE_INLINE PxBoxGeometry& box() - { - return get(); - } + PX_FORCE_INLINE PxConvexMeshGeometry& convexMesh() { return get(); } + PX_FORCE_INLINE const PxConvexMeshGeometry& convexMesh() const { return get(); } - PX_FORCE_INLINE const PxBoxGeometry& box() const - { - return get(); - } + PX_FORCE_INLINE PxTetrahedronMeshGeometry& tetMesh() { return get(); } + PX_FORCE_INLINE const PxTetrahedronMeshGeometry& tetMesh() const { return get(); } - PX_FORCE_INLINE PxConvexMeshGeometry& convexMesh() - { - return get(); - } + PX_FORCE_INLINE PxTriangleMeshGeometry& triangleMesh() { return get(); } + PX_FORCE_INLINE const PxTriangleMeshGeometry& triangleMesh() const { return get(); } - PX_FORCE_INLINE const PxConvexMeshGeometry& convexMesh() const - { - return get(); - } + PX_FORCE_INLINE PxHeightFieldGeometry& heightField() { return get(); } + PX_FORCE_INLINE const PxHeightFieldGeometry& heightField() const { return get(); } - PX_FORCE_INLINE PxTriangleMeshGeometry& triangleMesh() - { - return get(); - } + PX_FORCE_INLINE PxParticleSystemGeometry& particleSystem() { return get(); } + PX_FORCE_INLINE const PxParticleSystemGeometry& particleSystem() const { return get(); } - PX_FORCE_INLINE const PxTriangleMeshGeometry& triangleMesh() const - { - return get(); - } + PX_FORCE_INLINE PxHairSystemGeometry& hairSystem() { return get(); } + PX_FORCE_INLINE const PxHairSystemGeometry& hairSystem() const { return get(); } - PX_FORCE_INLINE PxHeightFieldGeometry& heightField() - { - return get(); - } - - PX_FORCE_INLINE const PxHeightFieldGeometry& heightField() const - { - return get(); - } + PX_FORCE_INLINE PxCustomGeometry& custom() { return get(); } + PX_FORCE_INLINE const PxCustomGeometry& custom() const { return get(); } +//! @endcond PX_FORCE_INLINE void storeAny(const PxGeometry& geometry) { @@ -157,20 +129,24 @@ public: switch(geometry.getType()) { - case PxGeometryType::eSPHERE: put(geometry); break; - case PxGeometryType::ePLANE: put(geometry); break; - case PxGeometryType::eCAPSULE: put(geometry); break; - case PxGeometryType::eBOX: put(geometry); break; - case PxGeometryType::eCONVEXMESH: put(geometry); break; - case PxGeometryType::eTRIANGLEMESH: put(geometry); break; - case PxGeometryType::eHEIGHTFIELD: put(geometry); break; + case PxGeometryType::eSPHERE: put(geometry); break; + case PxGeometryType::ePLANE: put(geometry); break; + case PxGeometryType::eCAPSULE: put(geometry); break; + case PxGeometryType::eBOX: put(geometry); break; + case PxGeometryType::eCONVEXMESH: put(geometry); break; + case PxGeometryType::eTRIANGLEMESH: put(geometry); break; + case PxGeometryType::eTETRAHEDRONMESH: put(geometry); break; + case PxGeometryType::eHEIGHTFIELD: put(geometry); break; + case PxGeometryType::ePARTICLESYSTEM: put(geometry); break; + case PxGeometryType::eHAIRSYSTEM: put(geometry); break; + case PxGeometryType::eCUSTOM: put(geometry); break; case PxGeometryType::eGEOMETRY_COUNT: - case PxGeometryType::eINVALID: break; + case PxGeometryType::eINVALID: break; } } - PX_FORCE_INLINE PxGeometryHolder() {} - PX_FORCE_INLINE PxGeometryHolder(const PxGeometry& geometry){ storeAny(geometry); } + PX_FORCE_INLINE PxGeometryHolder() { put(PxInvalidGeometry()); } + PX_FORCE_INLINE PxGeometryHolder(const PxGeometry& geometry){ storeAny(geometry); } private: template void put(const PxGeometry& geometry) @@ -197,15 +173,16 @@ public: PxU8 capsule[sizeof(PxCapsuleGeometry)]; PxU8 plane[sizeof(PxPlaneGeometry)]; PxU8 convex[sizeof(PxConvexMeshGeometry)]; + PxU8 tetMesh[sizeof(PxTetrahedronMeshGeometry)]; PxU8 mesh[sizeof(PxTriangleMeshGeometry)]; PxU8 heightfield[sizeof(PxHeightFieldGeometry)]; + PxU8 particleSystem[sizeof(PxParticleSystemGeometry)]; + PxU8 hairSystem[sizeof(PxHairSystemGeometry)]; + PxU8 custom[sizeof(PxCustomGeometry)]; } bytes; } PX_ALIGN_SUFFIX(4); - - - #if !PX_DOXYGEN } // namespace physx #endif diff --git a/Source/ThirdParty/PhysX/geometry/PxGeometryHit.h b/Source/ThirdParty/PhysX/geometry/PxGeometryHit.h new file mode 100644 index 000000000..2fcd83f93 --- /dev/null +++ b/Source/ThirdParty/PhysX/geometry/PxGeometryHit.h @@ -0,0 +1,195 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_GEOMETRY_HIT_H +#define PX_GEOMETRY_HIT_H +/** \addtogroup scenequery +@{ +*/ +#include "foundation/PxVec3.h" +#include "foundation/PxFlags.h" +#include "common/PxPhysXCommonConfig.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +/** +\brief Scene query and geometry query behavior flags. + +PxHitFlags are used for 3 different purposes: + +1) To request hit fields to be filled in by scene queries (such as hit position, normal, face index or UVs). +2) Once query is completed, to indicate which fields are valid (note that a query may produce more valid fields than requested). +3) To specify additional options for the narrow phase and mid-phase intersection routines. + +All these flags apply to both scene queries and geometry queries (PxGeometryQuery). + +@see PxRaycastHit PxSweepHit PxOverlapHit PxScene.raycast PxScene.sweep PxScene.overlap PxGeometryQuery PxFindFaceIndex +*/ +struct PxHitFlag +{ + enum Enum + { + ePOSITION = (1<<0), //!< "position" member of #PxQueryHit is valid + eNORMAL = (1<<1), //!< "normal" member of #PxQueryHit is valid + eUV = (1<<3), //!< "u" and "v" barycentric coordinates of #PxQueryHit are valid. Not applicable to sweep queries. + eASSUME_NO_INITIAL_OVERLAP = (1<<4), //!< Performance hint flag for sweeps when it is known upfront there's no initial overlap. + //!< NOTE: using this flag may cause undefined results if shapes are initially overlapping. + eANY_HIT = (1<<5), //!< Report any first hit. Used for geometries that contain more than one primitive. For meshes, + //!< if neither eMESH_MULTIPLE nor eANY_HIT is specified, a single closest hit will be reported. + eMESH_MULTIPLE = (1<<6), //!< Report all hits for meshes rather than just the first. Not applicable to sweep queries. + eMESH_ANY = eANY_HIT, //!< @deprecated Deprecated, please use eANY_HIT instead. + eMESH_BOTH_SIDES = (1<<7), //!< Report hits with back faces of mesh triangles. Also report hits for raycast + //!< originating on mesh surface and facing away from the surface normal. Not applicable to sweep queries. + //!< Please refer to the user guide for heightfield-specific differences. + ePRECISE_SWEEP = (1<<8), //!< Use more accurate but slower narrow phase sweep tests. + //!< May provide better compatibility with PhysX 3.2 sweep behavior. + eMTD = (1<<9), //!< Report the minimum translation depth, normal and contact point. + eFACE_INDEX = (1<<10), //!< "face index" member of #PxQueryHit is valid + + eDEFAULT = ePOSITION|eNORMAL|eFACE_INDEX, + + /** \brief Only this subset of flags can be modified by pre-filter. Other modifications will be discarded. */ + eMODIFIABLE_FLAGS = eMESH_MULTIPLE|eMESH_BOTH_SIDES|eASSUME_NO_INITIAL_OVERLAP|ePRECISE_SWEEP + }; +}; + +/** +\brief collection of set bits defined in PxHitFlag. + +@see PxHitFlag +*/ +PX_FLAGS_TYPEDEF(PxHitFlag, PxU16) + +/** +\brief Scene query hit information. +*/ +struct PxQueryHit +{ + PX_INLINE PxQueryHit() : faceIndex(0xFFFFffff) {} + + /** + Face index of touched triangle, for triangle meshes, convex meshes and height fields. + + \note This index will default to 0xFFFFffff value for overlap queries. + \note Please refer to the user guide for more details for sweep queries. + \note This index is remapped by mesh cooking. Use #PxTriangleMesh::getTrianglesRemap() to convert to original mesh index. + \note For convex meshes use #PxConvexMesh::getPolygonData() to retrieve touched polygon data. + */ + PxU32 faceIndex; +}; + +/** +\brief Scene query hit information for raycasts and sweeps returning hit position and normal information. + +::PxHitFlag flags can be passed to scene query functions, as an optimization, to cause the SDK to +only generate specific members of this structure. +*/ +struct PxLocationHit : PxQueryHit +{ + PX_INLINE PxLocationHit() : flags(0), position(PxVec3(0)), normal(PxVec3(0)), distance(PX_MAX_REAL) {} + + /** + \note For raycast hits: true for shapes overlapping with raycast origin. + \note For sweep hits: true for shapes overlapping at zero sweep distance. + + @see PxRaycastHit PxSweepHit + */ + PX_INLINE bool hadInitialOverlap() const { return (distance <= 0.0f); } + + // the following fields are set in accordance with the #PxHitFlags + PxHitFlags flags; //!< Hit flags specifying which members contain valid values. + PxVec3 position; //!< World-space hit position (flag: #PxHitFlag::ePOSITION) + PxVec3 normal; //!< World-space hit normal (flag: #PxHitFlag::eNORMAL) + + /** + \brief Distance to hit. + \note If the eMTD flag is used, distance will be a negative value if shapes are overlapping indicating the penetration depth. + \note Otherwise, this value will be >= 0 */ + PxF32 distance; +}; + +/** +\brief Stores results of raycast queries. + +::PxHitFlag flags can be passed to raycast function, as an optimization, to cause the SDK to only compute specified members of this +structure. + +Some members like barycentric coordinates are currently only computed for triangle meshes and height fields, but next versions +might provide them in other cases. The client code should check #flags to make sure returned values are valid. + +@see PxScene.raycast +*/ +struct PxGeomRaycastHit : PxLocationHit +{ + PX_INLINE PxGeomRaycastHit() : u(0.0f), v(0.0f) {} + + // the following fields are set in accordance with the #PxHitFlags + + PxReal u, v; //!< barycentric coordinates of hit point, for triangle mesh and height field (flag: #PxHitFlag::eUV) +}; + +/** +\brief Stores results of overlap queries. + +@see PxScene.overlap +*/ +struct PxGeomOverlapHit : PxQueryHit +{ + PX_INLINE PxGeomOverlapHit() {} +}; + +/** +\brief Stores results of sweep queries. + +@see PxScene.sweep +*/ +struct PxGeomSweepHit : PxLocationHit +{ + PX_INLINE PxGeomSweepHit() {} +}; + +/** +\brief Pair of indices, typically either object or triangle indices. +*/ +struct PxGeomIndexPair +{ + PX_FORCE_INLINE PxGeomIndexPair() {} + PX_FORCE_INLINE PxGeomIndexPair(PxU32 _id0, PxU32 _id1) : id0(_id0), id1(_id1) {} + + PxU32 id0, id1; +}; + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/geometry/PxGeometryInternal.h b/Source/ThirdParty/PhysX/geometry/PxGeometryInternal.h new file mode 100644 index 000000000..b269b02a9 --- /dev/null +++ b/Source/ThirdParty/PhysX/geometry/PxGeometryInternal.h @@ -0,0 +1,123 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_GEOMETRY_INTERNAL_H +#define PX_GEOMETRY_INTERNAL_H +/** \addtogroup geomutils +@{ */ + +#include "common/PxPhysXCommonConfig.h" +#include "foundation/PxVec3.h" +#include "geometry/PxTriangleMesh.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + class PxTriangleMesh; + + struct PxTriangleMeshInternalData + { + PxU32 mNbVertices; + PxU32 mNbTriangles; + PxVec3* mVertices; + void* mTriangles; + PxU32* mFaceRemap; + PxVec3 mAABB_Center; + PxVec3 mAABB_Extents; + PxReal mGeomEpsilon; + PxU8 mFlags; + // + PxU32 mNbNodes; + PxU32 mNodeSize; + void* mNodes; + PxU32 mInitData; + PxVec3 mCenterOrMinCoeff; + PxVec3 mExtentsOrMaxCoeff; + bool mQuantized; + + PX_FORCE_INLINE PxU32 getSizeofVerticesInBytes() const + { + return mNbVertices * sizeof(PxVec3); + } + + PX_FORCE_INLINE PxU32 getSizeofTrianglesInBytes() const + { + const PxU32 triangleSize = mFlags & PxTriangleMeshFlag::e16_BIT_INDICES ? sizeof(PxU16) : sizeof(PxU32); + return mNbTriangles * 3 * triangleSize; + } + + PX_FORCE_INLINE PxU32 getSizeofFaceRemapInBytes() const + { + return mNbTriangles * sizeof(PxU32); + } + + PX_FORCE_INLINE PxU32 getSizeofNodesInBytes() const + { + return mNbNodes * mNodeSize; + } + }; + + PX_C_EXPORT PX_PHYSX_COMMON_API bool PX_CALL_CONV PxGetTriangleMeshInternalData(PxTriangleMeshInternalData& data, const PxTriangleMesh& mesh, bool takeOwnership); + + class PxBVH; + + struct PxBVHInternalData + { + PxU32 mNbIndices; + PxU32 mNbNodes; + PxU32 mNodeSize; + void* mNodes; + PxU32* mIndices; // Can be null + void* mBounds; + + PX_FORCE_INLINE PxU32 getSizeofNodesInBytes() const + { + return mNbNodes * mNodeSize; + } + + PX_FORCE_INLINE PxU32 getSizeofIndicesInBytes() const + { + return mNbIndices * sizeof(PxU32); + } + + PX_FORCE_INLINE PxU32 getSizeofBoundsInBytes() const + { + return (mNbIndices+1)*6; + } + }; + + PX_C_EXPORT PX_PHYSX_COMMON_API bool PX_CALL_CONV PxGetBVHInternalData(PxBVHInternalData& data, const PxBVH& bvh, bool takeOwnership); + +#if !PX_DOXYGEN +} // namespace physx +#endif + +/** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/geometry/PxGeometryQuery.h b/Source/ThirdParty/PhysX/geometry/PxGeometryQuery.h index a4cab1a71..1cb4a615b 100644 --- a/Source/ThirdParty/PhysX/geometry/PxGeometryQuery.h +++ b/Source/ThirdParty/PhysX/geometry/PxGeometryQuery.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_GEOMUTILS_PX_GEOMETRY_QUERY -#define PX_PHYSICS_GEOMUTILS_PX_GEOMETRY_QUERY +#ifndef PX_GEOMETRY_QUERY_H +#define PX_GEOMETRY_QUERY_H /** \brief Maximum sweep distance for scene sweeps. The distance parameter for sweep functions will be clamped to this value. @@ -44,7 +42,9 @@ The reason for this is GJK support cannot be evaluated near infinity. A viable a */ #include "common/PxPhysXCommonConfig.h" -#include "PxQueryReport.h" +#include "geometry/PxGeometryHit.h" +#include "geometry/PxGeometryQueryFlags.h" +#include "geometry/PxGeometryQueryContext.h" #if !PX_DOXYGEN namespace physx @@ -52,10 +52,7 @@ namespace physx #endif class PxGeometry; -struct PxSweepHit; -struct PxRaycastHit; - -class PxTriangle; +class PxContactBuffer; /** \brief Collection of geometry object queries (sweeps, raycasts, overlaps, ...). @@ -64,6 +61,70 @@ class PxGeometryQuery { public: + /** + \brief Raycast test against a geometry object. + + All geometry types are supported except PxParticleSystemGeometry, PxTetrahedronMeshGeometry and PxHairSystemGeometry. + + \param[in] origin The origin of the ray to test the geometry object against + \param[in] unitDir Normalized direction of the ray to test the geometry object against + \param[in] geom The geometry object to test the ray against + \param[in] pose Pose of the geometry object + \param[in] maxDist Maximum ray length, has to be in the [0, inf) range + \param[in] hitFlags Specification of the kind of information to retrieve on hit. Combination of #PxHitFlag flags + \param[in] maxHits max number of returned hits = size of 'rayHits' buffer + \param[out] rayHits Raycast hits information + \param[in] stride Stride value (in number of bytes) for rayHits array. Typically sizeof(PxGeomRaycastHit) for packed arrays. + \param[in] queryFlags Optional flags controlling the query. + \param[in] threadContext Optional user-defined per-thread context. + + \return Number of hits between the ray and the geometry object + + @see PxGeomRaycastHit PxGeometry PxTransform + */ + PX_PHYSX_COMMON_API static PxU32 raycast( const PxVec3& origin, const PxVec3& unitDir, + const PxGeometry& geom, const PxTransform& pose, + PxReal maxDist, PxHitFlags hitFlags, + PxU32 maxHits, PxGeomRaycastHit* PX_RESTRICT rayHits, PxU32 stride, PxGeometryQueryFlags queryFlags = PxGeometryQueryFlag::eDEFAULT, + PxRaycastThreadContext* threadContext = NULL); + + /** + * @brief Backward compatibility helper + * @deprecated + */ + template + PX_DEPRECATED PX_FORCE_INLINE static PxU32 raycast( const PxVec3& origin, const PxVec3& unitDir, + const PxGeometry& geom, const PxTransform& pose, + PxReal maxDist, PxHitFlags hitFlags, + PxU32 maxHits, HitT* PX_RESTRICT rayHits) + { + return raycast(origin, unitDir, geom, pose, maxDist, hitFlags, maxHits, rayHits, sizeof(HitT)); + } + + /** + \brief Overlap test for two geometry objects. + + All combinations are supported except: + \li PxPlaneGeometry vs. {PxPlaneGeometry, PxTriangleMeshGeometry, PxHeightFieldGeometry} + \li PxTriangleMeshGeometry vs. PxHeightFieldGeometry + \li PxHeightFieldGeometry vs. PxHeightFieldGeometry + \li Anything involving PxParticleSystemGeometry, PxTetrahedronMeshGeometry or PxHairSystemGeometry. + + \param[in] geom0 The first geometry object + \param[in] pose0 Pose of the first geometry object + \param[in] geom1 The second geometry object + \param[in] pose1 Pose of the second geometry object + \param[in] queryFlags Optional flags controlling the query. + \param[in] threadContext Optional user-defined per-thread context. + + \return True if the two geometry objects overlap + + @see PxGeometry PxTransform + */ + PX_PHYSX_COMMON_API static bool overlap(const PxGeometry& geom0, const PxTransform& pose0, + const PxGeometry& geom1, const PxTransform& pose1, + PxGeometryQueryFlags queryFlags = PxGeometryQueryFlag::eDEFAULT, PxOverlapThreadContext* threadContext=NULL); + /** \brief Sweep a specified geometry object in space and test for collision with a given object. @@ -74,74 +135,28 @@ public: \li PxBoxGeometry vs. {PxSphereGeometry, PxPlaneGeometry, PxCapsuleGeometry, PxBoxGeometry, PxConvexMeshGeometry, PxTriangleMeshGeometry, PxHeightFieldGeometry} \li PxConvexMeshGeometry vs. {PxSphereGeometry, PxPlaneGeometry, PxCapsuleGeometry, PxBoxGeometry, PxConvexMeshGeometry, PxTriangleMeshGeometry, PxHeightFieldGeometry} - \param[in] unitDir Normalized direction along which object geom0 should be swept - \param[in] maxDist Maximum sweep distance, has to be in the [0, inf) range - \param[in] geom0 The geometry object to sweep. Supported geometries are #PxSphereGeometry, #PxCapsuleGeometry, #PxBoxGeometry and #PxConvexMeshGeometry - \param[in] pose0 Pose of the geometry object to sweep - \param[in] geom1 The geometry object to test the sweep against - \param[in] pose1 Pose of the geometry object to sweep against - \param[out] sweepHit The sweep hit information. Only valid if this method returns true. - \param[in] hitFlags Specify which properties per hit should be computed and written to result hit array. Combination of #PxHitFlag flags - \param[in] inflation Surface of the swept shape is additively extruded in the normal direction, rounding corners and edges. + \param[in] unitDir Normalized direction along which object geom0 should be swept + \param[in] maxDist Maximum sweep distance, has to be in the [0, inf) range + \param[in] geom0 The geometry object to sweep. Supported geometries are #PxSphereGeometry, #PxCapsuleGeometry, #PxBoxGeometry and #PxConvexMeshGeometry + \param[in] pose0 Pose of the geometry object to sweep + \param[in] geom1 The geometry object to test the sweep against + \param[in] pose1 Pose of the geometry object to sweep against + \param[out] sweepHit The sweep hit information. Only valid if this method returns true. + \param[in] hitFlags Specify which properties per hit should be computed and written to result hit array. Combination of #PxHitFlag flags + \param[in] inflation Surface of the swept shape is additively extruded in the normal direction, rounding corners and edges. + \param[in] queryFlags Optional flags controlling the query. + \param[in] threadContext Optional user-defined per-thread context. \return True if the swept geometry object geom0 hits the object geom1 - @see PxSweepHit PxGeometry PxTransform + @see PxGeomSweepHit PxGeometry PxTransform */ - PX_PHYSX_COMMON_API static bool sweep(const PxVec3& unitDir, - const PxReal maxDist, - const PxGeometry& geom0, - const PxTransform& pose0, - const PxGeometry& geom1, - const PxTransform& pose1, - PxSweepHit& sweepHit, - PxHitFlags hitFlags = PxHitFlag::eDEFAULT, - const PxReal inflation = 0.f); - - - /** - \brief Overlap test for two geometry objects. - - All combinations are supported except: - \li PxPlaneGeometry vs. {PxPlaneGeometry, PxTriangleMeshGeometry, PxHeightFieldGeometry} - \li PxTriangleMeshGeometry vs. {PxTriangleMeshGeometry, PxHeightFieldGeometry} - \li PxHeightFieldGeometry vs. {PxHeightFieldGeometry} - - \param[in] geom0 The first geometry object - \param[in] pose0 Pose of the first geometry object - \param[in] geom1 The second geometry object - \param[in] pose1 Pose of the second geometry object - \return True if the two geometry objects overlap - - @see PxGeometry PxTransform - */ - PX_PHYSX_COMMON_API static bool overlap(const PxGeometry& geom0, const PxTransform& pose0, - const PxGeometry& geom1, const PxTransform& pose1); - - - /** - \brief Raycast test against a geometry object. - - \param[in] origin The origin of the ray to test the geometry object against - \param[in] unitDir Normalized direction of the ray to test the geometry object against - \param[in] geom The geometry object to test the ray against - \param[in] pose Pose of the geometry object - \param[in] maxDist Maximum ray length, has to be in the [0, inf) range - \param[in] hitFlags Specification of the kind of information to retrieve on hit. Combination of #PxHitFlag flags - \param[in] maxHits max number of returned hits = size of 'rayHits' buffer - \param[out] rayHits Raycast hits information - \return Number of hits between the ray and the geometry object - - @see PxRaycastHit PxGeometry PxTransform - */ - PX_PHYSX_COMMON_API static PxU32 raycast(const PxVec3& origin, - const PxVec3& unitDir, - const PxGeometry& geom, - const PxTransform& pose, - PxReal maxDist, - PxHitFlags hitFlags, - PxU32 maxHits, - PxRaycastHit* PX_RESTRICT rayHits); + PX_PHYSX_COMMON_API static bool sweep( const PxVec3& unitDir, const PxReal maxDist, + const PxGeometry& geom0, const PxTransform& pose0, + const PxGeometry& geom1, const PxTransform& pose1, + PxGeomSweepHit& sweepHit, PxHitFlags hitFlags = PxHitFlag::eDEFAULT, + const PxReal inflation = 0.0f, PxGeometryQueryFlags queryFlags = PxGeometryQueryFlag::eDEFAULT, + PxSweepThreadContext* threadContext = NULL); /** \brief Compute minimum translational distance (MTD) between two geometry objects. @@ -153,6 +168,7 @@ public: - mesh/mesh - mesh/heightfield - heightfield/heightfield + - anything involving PxParticleSystemGeometry, PxTetrahedronMeshGeometry or PxHairSystemGeometry The function returns a unit vector ('direction') and a penetration depth ('depth'). @@ -163,60 +179,97 @@ public: If objects do not overlap, the function can not compute the MTD and returns false. - \param[out] direction Computed MTD unit direction - \param[out] depth Penetration depth. Always positive or null. - \param[in] geom0 The first geometry object - \param[in] pose0 Pose of the first geometry object - \param[in] geom1 The second geometry object - \param[in] pose1 Pose of the second geometry object + \param[out] direction Computed MTD unit direction + \param[out] depth Penetration depth. Always positive or null. + \param[in] geom0 The first geometry object + \param[in] pose0 Pose of the first geometry object + \param[in] geom1 The second geometry object + \param[in] pose1 Pose of the second geometry object + \param[in] queryFlags Optional flags controlling the query. \return True if the MTD has successfully been computed, i.e. if objects do overlap. @see PxGeometry PxTransform */ - PX_PHYSX_COMMON_API static bool computePenetration(PxVec3& direction, PxF32& depth, - const PxGeometry& geom0, const PxTransform& pose0, - const PxGeometry& geom1, const PxTransform& pose1); + PX_PHYSX_COMMON_API static bool computePenetration( PxVec3& direction, PxF32& depth, + const PxGeometry& geom0, const PxTransform& pose0, + const PxGeometry& geom1, const PxTransform& pose1, + PxGeometryQueryFlags queryFlags = PxGeometryQueryFlag::eDEFAULT); /** \brief Computes distance between a point and a geometry object. - Currently supported geometry objects: box, sphere, capsule, convex. + Currently supported geometry objects: box, sphere, capsule, convex, mesh. - \param[in] point The point P - \param[in] geom The geometry object - \param[in] pose Pose of the geometry object - \param[out] closestPoint Optionally returned closest point to P on the geom object. Only valid when returned distance is strictly positive. - \return Square distance between the point and the geom object, or 0.0 if the point is inside the object, or -1.0 if the geometry type is not supported. + \note For meshes, only the BVH34 midphase data-structure is supported. + + \param[in] point The point P + \param[in] geom The geometry object + \param[in] pose Pose of the geometry object + \param[out] closestPoint Optionally returned closest point to P on the geom object. Only valid when returned distance is strictly positive. + \param[out] closestIndex Optionally returned closest (triangle) index. Only valid for triangle meshes. + \param[in] queryFlags Optional flags controlling the query. + \return Square distance between the point and the geom object, or 0.0 if the point is inside the object, or -1.0 if an error occured (geometry type is not supported, or invalid pose) @see PxGeometry PxTransform */ - PX_PHYSX_COMMON_API static PxReal pointDistance(const PxVec3& point, const PxGeometry& geom, const PxTransform& pose, PxVec3* closestPoint=NULL); + PX_PHYSX_COMMON_API static PxReal pointDistance(const PxVec3& point, const PxGeometry& geom, const PxTransform& pose, + PxVec3* closestPoint=NULL, PxU32* closestIndex=NULL, + PxGeometryQueryFlags queryFlags = PxGeometryQueryFlag::eDEFAULT); + /** + \brief computes the bounds for a geometry object + + \param[out] bounds Returned computed bounds + \param[in] geom The geometry object + \param[in] pose Pose of the geometry object + \param[in] offset Offset for computed bounds. This value is added to the geom's extents. + \param[in] inflation Scale factor for computed bounds. The geom's extents are multiplied by this value. + \param[in] queryFlags Optional flags controlling the query. + + @see PxGeometry PxTransform + */ + PX_PHYSX_COMMON_API static void computeGeomBounds(PxBounds3& bounds, const PxGeometry& geom, const PxTransform& pose, float offset=0.0f, float inflation=1.0f, PxGeometryQueryFlags queryFlags = PxGeometryQueryFlag::eDEFAULT); /** \brief get the bounds for a geometry object - \param[in] geom The geometry object - \param[in] pose Pose of the geometry object - \param[in] inflation Scale factor for computed world bounds. Box extents are multiplied by this value. + \param[in] geom The geometry object + \param[in] pose Pose of the geometry object + \param[in] inflation Scale factor for computed world bounds. Box extents are multiplied by this value. \return The bounds of the object @see PxGeometry PxTransform + @deprecated */ - PX_PHYSX_COMMON_API static PxBounds3 getWorldBounds(const PxGeometry& geom, const PxTransform& pose, float inflation=1.01f); + PX_DEPRECATED PX_PHYSX_COMMON_API static PxBounds3 getWorldBounds(const PxGeometry& geom, const PxTransform& pose, float inflation=1.01f); + + /** + \brief Generate collision contacts between a convex geometry and a single triangle + + \param[in] geom The geometry object. Can be a capsule, a box or a convex mesh + \param[in] pose Pose of the geometry object + \param[in] triangleVertices Triangle vertices in local space + \param[in] triangleIndex Triangle index + \param[in] contactDistance The distance at which contacts begin to be generated between the pairs + \param[in] meshContactMargin The mesh contact margin. + \param[in] toleranceLength The toleranceLength. Used for scaling distance-based thresholds internally to produce appropriate results given simulations in different units + \param[out] contactBuffer A buffer to write contacts to. + + \return True if there was collision + */ + PX_PHYSX_COMMON_API static bool generateTriangleContacts(const PxGeometry& geom, const PxTransform& pose, const PxVec3 triangleVertices[3], PxU32 triangleIndex, PxReal contactDistance, PxReal meshContactMargin, PxReal toleranceLength, PxContactBuffer& contactBuffer); /** \brief Checks if provided geometry is valid. - \param[in] geom The geometry object. + \param[in] geom The geometry object. \return True if geometry is valid. - @see PxGeometry PxSphereGeometry, PxCapsuleGeometry, PxBoxGeometry, PxConvexGeometry + @see PxGeometry */ PX_PHYSX_COMMON_API static bool isValid(const PxGeometry& geom); }; - #if !PX_DOXYGEN } #endif diff --git a/Source/ThirdParty/PhysX/geometry/PxGeometryQueryContext.h b/Source/ThirdParty/PhysX/geometry/PxGeometryQueryContext.h new file mode 100644 index 000000000..0b64cfeaf --- /dev/null +++ b/Source/ThirdParty/PhysX/geometry/PxGeometryQueryContext.h @@ -0,0 +1,74 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_GEOMETRY_QUERY_CONTEXT_H +#define PX_GEOMETRY_QUERY_CONTEXT_H + +#include "common/PxPhysXCommonConfig.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + /** + \brief A per-thread context passed to low-level query functions. + + This is a user-defined optional parameter that gets passed down to low-level query functions (raycast / overlap / sweep). + + This is not used directly in PhysX, although the context in this case is the PxHitCallback used in the query. This allows + user-defined query functions, such as the ones from PxCustomGeometry, to get some additional data about the query. In this + case this is a 'per-query' context rather than 'per-thread', but the initial goal of this parameter is to give custom + query callbacks access to per-thread data structures (e.g. caches) that could be needed to implement the callbacks. + + In any case this is mostly for user-controlled query systems. + */ + struct PxQueryThreadContext + { + }; + + /** + \brief A per-thread context passed to low-level raycast functions. + */ + typedef PxQueryThreadContext PxRaycastThreadContext; + + /** + \brief A per-thread context passed to low-level overlap functions. + */ + typedef PxQueryThreadContext PxOverlapThreadContext; + + /** + \brief A per-thread context passed to low-level sweep functions. + */ + typedef PxQueryThreadContext PxSweepThreadContext; + +#if !PX_DOXYGEN +} +#endif + +#endif diff --git a/Source/ThirdParty/PhysX/geometry/PxGeometryQueryFlags.h b/Source/ThirdParty/PhysX/geometry/PxGeometryQueryFlags.h new file mode 100644 index 000000000..e2edb9061 --- /dev/null +++ b/Source/ThirdParty/PhysX/geometry/PxGeometryQueryFlags.h @@ -0,0 +1,68 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_GEOMETRY_QUERY_FLAGS_H +#define PX_GEOMETRY_QUERY_FLAGS_H + +#include "foundation/PxFlags.h" +#include "common/PxPhysXCommonConfig.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + /** + \brief Geometry-level query flags. + + @see PxScene::raycast PxScene::overlap PxScene::sweep PxBVH::raycast PxBVH::overlap PxBVH::sweep PxGeometryQuery::raycast PxGeometryQuery::overlap PxGeometryQuery::sweep + @see PxGeometryQuery::computePenetration PxGeometryQuery::pointDistance PxGeometryQuery::computeGeomBounds + @see PxMeshQuery::findOverlapTriangleMesh PxMeshQuery::findOverlapHeightField PxMeshQuery::sweep + */ + struct PxGeometryQueryFlag + { + enum Enum + { + eSIMD_GUARD = (1<<0), //!< Saves/restores SIMD control word for each query (safer but slower). Omit this if you took care of it yourself in your app. + + eDEFAULT = eSIMD_GUARD + }; + }; + + /** + \brief collection of set bits defined in PxGeometryQueryFlag. + + @see PxGeometryQueryFlag + */ + PX_FLAGS_TYPEDEF(PxGeometryQueryFlag, PxU32) + +#if !PX_DOXYGEN +} +#endif + +#endif diff --git a/Source/ThirdParty/PhysX/geometry/PxGjkQuery.h b/Source/ThirdParty/PhysX/geometry/PxGjkQuery.h new file mode 100644 index 000000000..c85b79171 --- /dev/null +++ b/Source/ThirdParty/PhysX/geometry/PxGjkQuery.h @@ -0,0 +1,145 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_GJK_QUERY_H +#define PX_GJK_QUERY_H + +#include "common/PxPhysXCommonConfig.h" +#include "foundation/PxVec3.h" +#include "foundation/PxQuat.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +/** +\brief Collection of GJK query functions (sweeps, raycasts, overlaps, ...). +*/ +class PxGjkQuery +{ +public: + + /** + \brief Abstract interface for a user defined shape GJK mapping support. + A user defined shape consists of a core shape and a margin. If the distance + between two shapes' cores is equal to the sum of their margins, these shapes are + considered touching. + */ + struct Support + { + /* Virtual destructor */ + virtual ~Support() {} + /** + \brief Return the user defined shape margin. Margin should be greater than or equal to 0 + + \return Margin. + */ + virtual PxReal getMargin() const = 0; + /** + \brief Return the farthest point on the user defined shape's core in given direction. + + \param[in] dir Direction + + \return Farthest point in given direction. + */ + virtual PxVec3 supportLocal(const PxVec3& dir) const = 0; + }; + + /** + \brief Computes proximity information for two shapes using GJK-EPA algorithm + + \param[in] a Shape A support mapping + \param[in] b Shape B support mapping + \param[in] poseA Shape A transformation + \param[in] poseB Shape B transformation + \param[in] contactDistance The distance at which proximity info begins to be computed between the shapes + \param[in] toleranceLength The toleranceLength. Used for scaling distance-based thresholds internally to produce appropriate results given simulations in different units + \param[out] pointA The closest/deepest point on shape A surface + \param[out] pointB The closest/deepest point on shape B surface + \param[out] separatingAxis Translating shape B along 'separatingAxis' by 'separation' makes the shapes touching + \param[out] separation Translating shape B along 'separatingAxis' by 'separation' makes the shapes touching + + \return False if the distance greater than contactDistance. + */ + PX_PHYSX_COMMON_API static bool proximityInfo(const Support& a, const Support& b, const PxTransform& poseA, const PxTransform& poseB, + PxReal contactDistance, PxReal toleranceLength, PxVec3& pointA, PxVec3& pointB, PxVec3& separatingAxis, PxReal& separation); + + /** + \brief Raycast test against the given shape. + + \param[in] shape Shape support mapping + \param[in] pose Shape transformation + \param[in] rayStart The start point of the ray to test the shape against + \param[in] unitDir Normalized direction of the ray to test the shape against + \param[in] maxDist Maximum ray length, has to be in the [0, inf) range + \param[out] t Hit distance + \param[out] n Hit normal + \param[out] p Hit point + + \return True if there is a hit. + */ + PX_PHYSX_COMMON_API static bool raycast(const Support& shape, const PxTransform& pose, const PxVec3& rayStart, + const PxVec3& unitDir, PxReal maxDist, PxReal& t, PxVec3& n, PxVec3& p); + + /** + \brief Overlap test for two shapes. + + \param[in] a Shape A support mapping + \param[in] b Shape B support mapping + \param[in] poseA Shape A transformation + \param[in] poseB Shape B transformation + + \return True if the shapes overlap. + */ + PX_PHYSX_COMMON_API static bool overlap(const Support& a, const Support& b, const PxTransform& poseA, const PxTransform& poseB); + + /** + \brief Sweep the shape B in space and test for collision with the shape A. + + \param[in] a Shape A support mapping + \param[in] b Shape B support mapping + \param[in] poseA Shape A transformation + \param[in] poseB Shape B transformation + \param[in] unitDir Normalized direction of the ray to test the shape against + \param[in] maxDist Maximum ray length, has to be in the [0, inf) range + \param[out] t Hit distance + \param[out] n Hit normal + \param[out] p Hit point + + \return True if there is a hit. + */ + PX_PHYSX_COMMON_API static bool sweep(const Support& a, const Support& b, const PxTransform& poseA, const PxTransform& poseB, + const PxVec3& unitDir, PxReal maxDist, PxReal& t, PxVec3& n, PxVec3& p); +}; + +#if !PX_DOXYGEN +} +#endif + +#endif diff --git a/Source/ThirdParty/PhysX/geometry/PxHairSystemDesc.h b/Source/ThirdParty/PhysX/geometry/PxHairSystemDesc.h new file mode 100644 index 000000000..f5ab60ed9 --- /dev/null +++ b/Source/ThirdParty/PhysX/geometry/PxHairSystemDesc.h @@ -0,0 +1,200 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. + + +#ifndef PX_HAIRSYSTEM_DESC_H +#define PX_HAIRSYSTEM_DESC_H +/** \addtogroup geomutils +@{ +*/ + +#include "foundation/PxFlags.h" +#include "common/PxCoreUtilityTypes.h" + +#if PX_ENABLE_FEATURES_UNDER_CONSTRUCTION + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + struct PxHairSystemDescFlag + { + enum Enum + { + /** + Determines whether or not to allocate memory on device (GPU) or on Host (CPU) + */ + eDEVICE_MEMORY = (1<<0) + }; + }; + + /** + \brief collection of set bits defined in PxHairSystemDescFlag + \see PxHairSystemDescFlag + */ + typedef PxFlags PxHairSystemDescFlags; + PX_FLAGS_OPERATORS(PxHairSystemDescFlag::Enum, PxU16) + + /** + \brief Descriptor class for #PxHairSystem + \note The data is *copied* when a PxHairSystem object is created from this + descriptor. The user may discard the data after the call. + + \see PxHairSystem PxHairSystemGeometry PxShape PxPhysics.createHairSystem() + PxCooking.createHairSystem() + */ + class PxHairSystemDesc + { + public: + /** + \brief The number of strands in this hair system + + Default: 0 + */ + PxU32 numStrands; + + /** + \brief The length of a hair segment + + Default: 0.1 + */ + PxReal segmentLength; + + /** + \brief The radius of a hair segment + + Default: 0.01 + */ + PxReal segmentRadius; + + /** + \brief Specifies the number of vertices each strand is composed of. + Length must be equal to numStrands, elements assumed to be of + type PxU32. Number of segments = numVerticesPerStrand - 1. + + Default: NULL + */ + PxBoundedData numVerticesPerStrand; + + /** + \brief Vertex positions and inverse mass [x,y,z,1/m] in PxBoundedData format. + If count equal to numStrands, assumed to be strand root positions, + otherwise positions of all vertices sorted by strands and increasing + from root towards tip of strand. + Type assumed to be of PxReal. + + Default: NULL + */ + PxBoundedData vertices; + + /** + \brief Vertex velocities in PxBoundedData format. + If NULL, zero velocity is assumed. + Type assumed to be of PxReal. + + Default: NULL + */ + PxBoundedData velocities; + + /** + \brief Flags bits, combined from values of the enum ::PxHairSystemDesc + + Default: 0 + */ + PxHairSystemDescFlags flags; + + /** + \brief Constructor with default initialization + */ + PX_INLINE PxHairSystemDesc(); + + /** + \brief (re)sets the structure to the default. + */ + PX_INLINE void setToDefault(); + + /** + \brief Check whether the descriptor is valid + \return True if the current settings are valid + */ + PX_INLINE bool isValid() const; + }; + + PX_INLINE PxHairSystemDesc::PxHairSystemDesc() + { + numStrands = 0; + segmentLength = 0.1f; + segmentRadius = 0.01f; + } + + PX_INLINE void PxHairSystemDesc::setToDefault() + { + *this = PxHairSystemDesc(); + } + + PX_INLINE bool PxHairSystemDesc::isValid() const + { + if (segmentLength < 0.0f || segmentRadius < 0.0f) + return false; + + if (2.0f * segmentRadius >= segmentLength) + return false; + + if (numStrands == 0) + return false; + + if (numVerticesPerStrand.count != numStrands) + return false; + + PxU32 totalNumVertices = 0; + for (PxU32 i = 0; i < numVerticesPerStrand.count; i++) + { + const PxU32 numVertices = numVerticesPerStrand.at(i); + totalNumVertices += numVertices; + if (numVertices < 2) + { + return false; + } + } + + if (vertices.count != totalNumVertices && vertices.count != numStrands) + return false; + + if (velocities.count != totalNumVertices && velocities.count != 0) + return false; + + return true; + } + +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif + +/** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/geometry/PxHairSystemGeometry.h b/Source/ThirdParty/PhysX/geometry/PxHairSystemGeometry.h new file mode 100644 index 000000000..6d35c5245 --- /dev/null +++ b/Source/ThirdParty/PhysX/geometry/PxHairSystemGeometry.h @@ -0,0 +1,73 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. + + +#ifndef PX_HAIRSYSTEM_GEOMETRY_H +#define PX_HAIRSYSTEM_GEOMETRY_H +/** \addtogroup geomutils +@{ +*/ +#include "geometry/PxGeometry.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + /** + \brief Hair system geometry class. + + */ + class PxHairSystemGeometry : public PxGeometry + { + public: + /** + \brief Default constructor. + */ + PX_INLINE PxHairSystemGeometry() : PxGeometry(PxGeometryType::eHAIRSYSTEM) {} + + /** + \brief Returns true if the geometry is valid. + + \return True if the current settings are valid for shape creation. + + @see PxRigidActor::createShape, PxPhysics::createShape + */ + PX_FORCE_INLINE bool isValid() const + { + if(mType != PxGeometryType::eHAIRSYSTEM) + return false; + + return true; + } + }; + +#if !PX_DOXYGEN +} // namespace physx +#endif + + /** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/geometry/PxHeightField.h b/Source/ThirdParty/PhysX/geometry/PxHeightField.h index 346659569..d76042228 100644 --- a/Source/ThirdParty/PhysX/geometry/PxHeightField.h +++ b/Source/ThirdParty/PhysX/geometry/PxHeightField.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_GEOMUTILS_NX_HEIGHTFIELD -#define PX_PHYSICS_GEOMUTILS_NX_HEIGHTFIELD +#ifndef PX_HEIGHTFIELD_H +#define PX_HEIGHTFIELD_H /** \addtogroup geomutils @{ */ @@ -68,7 +66,7 @@ via the PxHeightFieldGeometry and PxShape classes.

Creation

To create an instance of this class call PxPhysics::createHeightField() or -PxCooking::createHeightField(const PxHeightFieldDesc&, PxPhysicsInsertionCallback&). +PxCooking::createHeightField(const PxHeightFieldDesc&, PxInsertionCallback&). To delete it call release(). This is only possible once you have released all of its PxHeightFiedShape instances. @@ -82,7 +80,7 @@ once you have released all of its PxHeightFiedShape instances. @see PxHeightFieldDesc PxHeightFieldGeometry PxShape PxPhysics.createHeightField() PxCooking.createHeightField() */ -class PxHeightField : public PxBase +class PxHeightField : public PxRefCounted { public: /** @@ -90,7 +88,7 @@ class PxHeightField : public PxBase @see PxPhysics.createHeightField() PxHeightFieldDesc PxHeightFieldGeometry PxShape */ - PX_PHYSX_COMMON_API virtual void release() = 0; + virtual void release() = 0; /** \brief Writes out the sample data array. @@ -104,7 +102,7 @@ class PxHeightField : public PxBase @see PxHeightFieldDesc.samples */ - PX_PHYSX_COMMON_API virtual PxU32 saveCells(void* destBuffer, PxU32 destBufferSize) const = 0; + virtual PxU32 saveCells(void* destBuffer, PxU32 destBufferSize) const = 0; /** \brief Replaces a rectangular subfield in the sample data array. @@ -126,7 +124,7 @@ class PxHeightField : public PxBase @see PxHeightFieldDesc.samples PxShape.setGeometry */ - PX_PHYSX_COMMON_API virtual bool modifySamples(PxI32 startCol, PxI32 startRow, const PxHeightFieldDesc& subfieldDesc, bool shrinkBounds = false) = 0; + virtual bool modifySamples(PxI32 startCol, PxI32 startRow, const PxHeightFieldDesc& subfieldDesc, bool shrinkBounds = false) = 0; /** \brief Retrieves the number of sample rows in the samples array. @@ -135,7 +133,7 @@ class PxHeightField : public PxBase @see PxHeightFieldDesc.nbRows */ - PX_PHYSX_COMMON_API virtual PxU32 getNbRows() const = 0; + virtual PxU32 getNbRows() const = 0; /** \brief Retrieves the number of sample columns in the samples array. @@ -144,7 +142,7 @@ class PxHeightField : public PxBase @see PxHeightFieldDesc.nbColumns */ - PX_PHYSX_COMMON_API virtual PxU32 getNbColumns() const = 0; + virtual PxU32 getNbColumns() const = 0; /** \brief Retrieves the format of the sample data. @@ -153,7 +151,7 @@ class PxHeightField : public PxBase @see PxHeightFieldDesc.format PxHeightFieldFormat */ - PX_PHYSX_COMMON_API virtual PxHeightFieldFormat::Enum getFormat() const = 0; + virtual PxHeightFieldFormat::Enum getFormat() const = 0; /** \brief Retrieves the offset in bytes between consecutive samples in the array. @@ -162,7 +160,7 @@ class PxHeightField : public PxBase @see PxHeightFieldDesc.sampleStride */ - PX_PHYSX_COMMON_API virtual PxU32 getSampleStride() const = 0; + virtual PxU32 getSampleStride() const = 0; /** \brief Retrieves the convex edge threshold. @@ -171,7 +169,7 @@ class PxHeightField : public PxBase @see PxHeightFieldDesc.convexEdgeThreshold */ - PX_PHYSX_COMMON_API virtual PxReal getConvexEdgeThreshold() const = 0; + virtual PxReal getConvexEdgeThreshold() const = 0; /** \brief Retrieves the flags bits, combined from values of the enum ::PxHeightFieldFlag. @@ -180,31 +178,14 @@ class PxHeightField : public PxBase @see PxHeightFieldDesc.flags PxHeightFieldFlag */ - PX_PHYSX_COMMON_API virtual PxHeightFieldFlags getFlags() const = 0; + virtual PxHeightFieldFlags getFlags() const = 0; /** \brief Retrieves the height at the given coordinates in grid space. \return The height at the given coordinates or 0 if the coordinates are out of range. */ - PX_PHYSX_COMMON_API virtual PxReal getHeight(PxReal x, PxReal z) const = 0; - - /** - \brief Returns the reference count for shared heightfields. - - At creation, the reference count of the heightfield is 1. Every shape referencing this heightfield increments the - count by 1. When the reference count reaches 0, and only then, the heightfield gets destroyed automatically. - - \return the current reference count. - */ - PX_PHYSX_COMMON_API virtual PxU32 getReferenceCount() const = 0; - - /** - \brief Acquires a counted reference to a heightfield. - - This method increases the reference count of the heightfield by 1. Decrement the reference count by calling release() - */ - PX_PHYSX_COMMON_API virtual void acquireReference() = 0; + virtual PxReal getHeight(PxReal x, PxReal z) const = 0; /** \brief Returns material table index of given triangle @@ -214,7 +195,7 @@ class PxHeightField : public PxBase \param[in] triangleIndex (internal) index of desired triangle \return Material table index, or 0xffff if no per-triangle materials are used */ - PX_PHYSX_COMMON_API virtual PxMaterialTableIndex getTriangleMaterialIndex(PxTriangleID triangleIndex) const = 0; + virtual PxMaterialTableIndex getTriangleMaterialIndex(PxTriangleID triangleIndex) const = 0; /** \brief Returns a triangle face normal for a given triangle index @@ -224,7 +205,7 @@ class PxHeightField : public PxBase \param[in] triangleIndex (internal) index of desired triangle \return Triangle normal for a given triangle index */ - PX_PHYSX_COMMON_API virtual PxVec3 getTriangleNormal(PxTriangleID triangleIndex) const = 0; + virtual PxVec3 getTriangleNormal(PxTriangleID triangleIndex) const = 0; /** \brief Returns heightfield sample of given row and column @@ -233,7 +214,7 @@ class PxHeightField : public PxBase \param[in] column Given heightfield column \return Heightfield sample */ - PX_PHYSX_COMMON_API virtual const PxHeightFieldSample& getSample(PxU32 row, PxU32 column) const = 0; + virtual const PxHeightFieldSample& getSample(PxU32 row, PxU32 column) const = 0; /** \brief Returns the number of times the heightfield data has been modified @@ -243,15 +224,15 @@ class PxHeightField : public PxBase \return the number of times the heightfield sample data has been modified. */ - PX_PHYSX_COMMON_API virtual PxU32 getTimestamp() const = 0; + virtual PxU32 getTimestamp() const = 0; - PX_PHYSX_COMMON_API virtual const char* getConcreteTypeName() const { return "PxHeightField"; } + virtual const char* getConcreteTypeName() const { return "PxHeightField"; } protected: - PX_INLINE PxHeightField(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags) {} - PX_INLINE PxHeightField(PxBaseFlags baseFlags) : PxBase(baseFlags) {} - PX_PHYSX_COMMON_API virtual ~PxHeightField() {} - PX_PHYSX_COMMON_API virtual bool isKindOf(const char* name) const { return !::strcmp("PxHeightField", name) || PxBase::isKindOf(name); } + PX_INLINE PxHeightField(PxType concreteType, PxBaseFlags baseFlags) : PxRefCounted(concreteType, baseFlags) {} + PX_INLINE PxHeightField(PxBaseFlags baseFlags) : PxRefCounted(baseFlags) {} + virtual ~PxHeightField() {} + virtual bool isKindOf(const char* name) const { return !::strcmp("PxHeightField", name) || PxRefCounted::isKindOf(name); } }; #if !PX_DOXYGEN diff --git a/Source/ThirdParty/PhysX/geometry/PxHeightFieldDesc.h b/Source/ThirdParty/PhysX/geometry/PxHeightFieldDesc.h index 669e91559..bb9ac8228 100644 --- a/Source/ThirdParty/PhysX/geometry/PxHeightFieldDesc.h +++ b/Source/ThirdParty/PhysX/geometry/PxHeightFieldDesc.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_COLLISION_NXHEIGHTFIELDDESC -#define PX_COLLISION_NXHEIGHTFIELDDESC +#ifndef PX_HEIGHTFIELD_DESC_H +#define PX_HEIGHTFIELD_DESC_H /** \addtogroup geomutils @{ */ diff --git a/Source/ThirdParty/PhysX/geometry/PxHeightFieldFlag.h b/Source/ThirdParty/PhysX/geometry/PxHeightFieldFlag.h index 85b27a339..b09472551 100644 --- a/Source/ThirdParty/PhysX/geometry/PxHeightFieldFlag.h +++ b/Source/ThirdParty/PhysX/geometry/PxHeightFieldFlag.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_COLLISION_NXHEIGHTFIELDFLAG -#define PX_COLLISION_NXHEIGHTFIELDFLAG +#ifndef PX_HEIGHT_FIELD_FLAG_H +#define PX_HEIGHT_FIELD_FLAG_H /** \addtogroup geomutils @{ */ diff --git a/Source/ThirdParty/PhysX/geometry/PxHeightFieldGeometry.h b/Source/ThirdParty/PhysX/geometry/PxHeightFieldGeometry.h index d32c1b89d..b64c32dda 100644 --- a/Source/ThirdParty/PhysX/geometry/PxHeightFieldGeometry.h +++ b/Source/ThirdParty/PhysX/geometry/PxHeightFieldGeometry.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_NX_HEIGHTFIELD_GEOMETRY -#define PX_PHYSICS_NX_HEIGHTFIELD_GEOMETRY +#ifndef PX_HEIGHT_FIELD_GEOMETRY_H +#define PX_HEIGHT_FIELD_GEOMETRY_H /** \addtogroup geomutils @{ */ @@ -56,29 +54,51 @@ There is a minimum allowed value for Y and XZ scaling - PX_MIN_HEIGHTFIELD_XZ_SC class PxHeightFieldGeometry : public PxGeometry { public: - PX_INLINE PxHeightFieldGeometry() : - PxGeometry (PxGeometryType::eHEIGHTFIELD), - heightField (NULL), - heightScale (1.0f), - rowScale (1.0f), - columnScale (1.0f), - heightFieldFlags(0) - {} - - PX_INLINE PxHeightFieldGeometry(PxHeightField* hf, - PxMeshGeometryFlags flags, - PxReal heightScale_, - PxReal rowScale_, - PxReal columnScale_) : + /** + \brief Constructor. + */ + PX_INLINE PxHeightFieldGeometry(PxHeightField* hf = NULL, + PxMeshGeometryFlags flags = PxMeshGeometryFlag::Enum(0), + PxReal heightScale_ = 1.0f, + PxReal rowScale_ = 1.0f, + PxReal columnScale_ = 1.0f) : PxGeometry (PxGeometryType::eHEIGHTFIELD), - heightField (hf) , - heightScale (heightScale_), - rowScale (rowScale_), - columnScale (columnScale_), + heightField (hf), + heightScale (heightScale_), + rowScale (rowScale_), + columnScale (columnScale_), heightFieldFlags (flags) { } + /** + \brief Copy constructor. + + \param[in] that Other object + */ + PX_INLINE PxHeightFieldGeometry(const PxHeightFieldGeometry& that) : + PxGeometry (that), + heightField (that.heightField), + heightScale (that.heightScale), + rowScale (that.rowScale), + columnScale (that.columnScale), + heightFieldFlags (that.heightFieldFlags) + { + } + + /** + \brief Assignment operator + */ + PX_INLINE void operator=(const PxHeightFieldGeometry& that) + { + mType = that.mType; + heightField = that.heightField; + heightScale = that.heightScale; + rowScale = that.rowScale; + columnScale = that.columnScale; + heightFieldFlags = that.heightFieldFlags; + } + /** \brief Returns true if the geometry is valid. @@ -95,41 +115,41 @@ public: /** \brief The height field data. */ - PxHeightField* heightField; + PxHeightField* heightField; /** \brief The scaling factor for the height field in vertical direction (y direction in local space). */ - PxReal heightScale; + PxReal heightScale; /** \brief The scaling factor for the height field in the row direction (x direction in local space). */ - PxReal rowScale; + PxReal rowScale; /** \brief The scaling factor for the height field in the column direction (z direction in local space). */ - PxReal columnScale; + PxReal columnScale; /** \brief Flags to specify some collision properties for the height field. */ - PxMeshGeometryFlags heightFieldFlags; + PxMeshGeometryFlags heightFieldFlags; - PxPadding<3> paddingFromFlags; //!< padding for mesh flags. + PxPadding<3> paddingFromFlags; //!< padding for mesh flags. }; PX_INLINE bool PxHeightFieldGeometry::isValid() const { - if (mType != PxGeometryType::eHEIGHTFIELD) + if(mType != PxGeometryType::eHEIGHTFIELD) return false; - if (!PxIsFinite(heightScale) || !PxIsFinite(rowScale) || !PxIsFinite(columnScale)) + if(!PxIsFinite(heightScale) || !PxIsFinite(rowScale) || !PxIsFinite(columnScale)) return false; - if (rowScale < PX_MIN_HEIGHTFIELD_XZ_SCALE || columnScale < PX_MIN_HEIGHTFIELD_XZ_SCALE || heightScale < PX_MIN_HEIGHTFIELD_Y_SCALE) + if(rowScale < PX_MIN_HEIGHTFIELD_XZ_SCALE || columnScale < PX_MIN_HEIGHTFIELD_XZ_SCALE || heightScale < PX_MIN_HEIGHTFIELD_Y_SCALE) return false; - if (!heightField) + if(!heightField) return false; return true; diff --git a/Source/ThirdParty/PhysX/geometry/PxHeightFieldSample.h b/Source/ThirdParty/PhysX/geometry/PxHeightFieldSample.h index a0489974c..82df7fdf1 100644 --- a/Source/ThirdParty/PhysX/geometry/PxHeightFieldSample.h +++ b/Source/ThirdParty/PhysX/geometry/PxHeightFieldSample.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_NXHEIGHTFIELDSAMPLE -#define PX_PHYSICS_NXHEIGHTFIELDSAMPLE +#ifndef PX_HEIGHT_FIELD_SAMPLE_H +#define PX_HEIGHT_FIELD_SAMPLE_H /** \addtogroup geomutils @{ */ diff --git a/Source/ThirdParty/PhysX/geometry/PxMeshQuery.h b/Source/ThirdParty/PhysX/geometry/PxMeshQuery.h index 7a9cfb6f6..a7c657aac 100644 --- a/Source/ThirdParty/PhysX/geometry/PxMeshQuery.h +++ b/Source/ThirdParty/PhysX/geometry/PxMeshQuery.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,20 +22,21 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_GEOMUTILS_PX_MESH_QUERY -#define PX_PHYSICS_GEOMUTILS_PX_MESH_QUERY +#ifndef PX_MESH_QUERY_H +#define PX_MESH_QUERY_H /** \addtogroup geomutils @{ */ #include "common/PxPhysXCommonConfig.h" -#include "PxQueryReport.h" +#include "geometry/PxGeometryHit.h" +#include "geometry/PxGeometryQueryFlags.h" +#include "geometry/PxReportCallback.h" #if !PX_DOXYGEN namespace physx @@ -50,6 +50,17 @@ class PxHeightFieldGeometry; class PxTriangle; + struct PxMeshMeshQueryFlag + { + enum Enum + { + eDEFAULT = 0, //!< Report all overlaps + eDISCARD_COPLANAR = (1<<0) //!< Ignore coplanar triangle-triangle overlaps + }; + }; + + PX_FLAGS_TYPEDEF(PxMeshMeshQueryFlag, PxU32) + class PxMeshQuery { public: @@ -59,12 +70,12 @@ public: This function can be used together with #findOverlapTriangleMesh() to retrieve triangle properties. - \param[in] triGeom Geometry of the triangle mesh to extract the triangle from. - \param[in] transform Transform for the triangle mesh - \param[in] triangleIndex The index of the triangle to retrieve. - \param[out] triangle Triangle points in world space. - \param[out] vertexIndices Returned vertex indices for given triangle - \param[out] adjacencyIndices Returned 3 triangle adjacency internal face indices (0xFFFFFFFF if no adjacency). The mesh must be cooked with cooking param buildTriangleAdjacencies enabled. + \param[in] triGeom Geometry of the triangle mesh to extract the triangle from. + \param[in] transform Transform for the triangle mesh + \param[in] triangleIndex The index of the triangle to retrieve. + \param[out] triangle Triangle points in world space. + \param[out] vertexIndices Returned vertex indices for given triangle + \param[out] adjacencyIndices Returned 3 triangle adjacency internal face indices (0xFFFFFFFF if no adjacency). The mesh must be cooked with cooking param buildTriangleAdjacencies enabled. \note This function will flip the triangle normal whenever triGeom.scale.hasNegativeDeterminant() is true. @@ -78,12 +89,12 @@ public: This function can be used together with #findOverlapHeightField() to retrieve triangle properties. - \param[in] hfGeom Geometry of the height field to extract the triangle from. - \param[in] transform Transform for the height field. - \param[in] triangleIndex The index of the triangle to retrieve. - \param[out] triangle Triangle points in world space. - \param[out] vertexIndices Returned vertex indices for given triangle - \param[out] adjacencyIndices Returned 3 triangle adjacency triangle indices (0xFFFFFFFF if no adjacency). + \param[in] hfGeom Geometry of the height field to extract the triangle from. + \param[in] transform Transform for the height field. + \param[in] triangleIndex The index of the triangle to retrieve. + \param[out] triangle Triangle points in world space. + \param[out] vertexIndices Returned vertex indices for given triangle + \param[out] adjacencyIndices Returned 3 triangle adjacency triangle indices (0xFFFFFFFF if no adjacency). \note This function will flip the triangle normal whenever triGeom.scale.hasNegativeDeterminant() is true. \note TriangleIndex is an index used in internal format, which does have an index out of the bounds in last row. @@ -107,44 +118,78 @@ public: /** \brief Find the mesh triangles which touch the specified geometry object. + For mesh-vs-mesh overlap tests, please use the specialized function below. + Returned triangle indices can be used with #getTriangle() to retrieve the triangle properties. - \param[in] geom The geometry object to test for mesh triangle overlaps. Supported geometries are #PxSphereGeometry, #PxCapsuleGeometry and #PxBoxGeometry - \param[in] geomPose Pose of the geometry object - \param[in] meshGeom The triangle mesh geometry to check overlap against - \param[in] meshPose Pose of the triangle mesh - \param[out] results Indices of overlapping triangles - \param[in] maxResults Size of 'results' buffer - \param[in] startIndex Index of first result to be retrieved. Previous indices are skipped. - \param[out] overflow True if a buffer overflow occurred + \param[in] geom The geometry object to test for mesh triangle overlaps. Supported geometries are #PxSphereGeometry, #PxCapsuleGeometry and #PxBoxGeometry + \param[in] geomPose Pose of the geometry object + \param[in] meshGeom The triangle mesh geometry to check overlap against + \param[in] meshPose Pose of the triangle mesh + \param[out] results Indices of overlapping triangles + \param[in] maxResults Size of 'results' buffer + \param[in] startIndex Index of first result to be retrieved. Previous indices are skipped. + \param[out] overflow True if a buffer overflow occurred + \param[in] queryFlags Optional flags controlling the query. \return Number of overlaps found, i.e. number of elements written to the results buffer - @see PxTriangleMeshGeometry getTriangle() + @see PxTriangleMeshGeometry getTriangle() PxGeometryQueryFlags */ PX_PHYSX_COMMON_API static PxU32 findOverlapTriangleMesh( const PxGeometry& geom, const PxTransform& geomPose, const PxTriangleMeshGeometry& meshGeom, const PxTransform& meshPose, - PxU32* results, PxU32 maxResults, PxU32 startIndex, bool& overflow); + PxU32* results, PxU32 maxResults, PxU32 startIndex, bool& overflow, + PxGeometryQueryFlags queryFlags = PxGeometryQueryFlag::eDEFAULT); + + /** + \brief Mesh-vs-mesh overlap test + + A specialized findOverlapTriangleMesh function for mesh-vs-mesh. The other findOverlapTriangleMesh() function above cannot be used + directly since it only returns a single set of triangle indices that belongs to one of the meshes only. This function returns pairs + of triangle indices that belong to both the first & second input meshes. + + Returned triangle indices can be used with #getTriangle() to retrieve the triangle properties. + + \note This is only implemented for the PxMeshMidPhase::eBVH34 data structure. + + \param[in] callback The callback object used to report results + \param[in] meshGeom0 First triangle mesh geometry + \param[in] meshPose0 Pose of first triangle mesh geometry + \param[in] meshGeom1 Second triangle mesh geometry + \param[in] meshPose1 Pose of second triangle mesh geometry + \param[in] queryFlags Optional flags controlling the query. + \param[in] meshMeshFlags Optional flags controlling the query. + \return true if an overlap has been detected, false if the meshes are disjoint + + @see PxTriangleMeshGeometry getTriangle() PxReportCallback PxGeometryQueryFlags PxMeshMeshQueryFlags + */ + PX_PHYSX_COMMON_API static bool findOverlapTriangleMesh(PxReportCallback& callback, + const PxTriangleMeshGeometry& meshGeom0, const PxTransform& meshPose0, + const PxTriangleMeshGeometry& meshGeom1, const PxTransform& meshPose1, + PxGeometryQueryFlags queryFlags = PxGeometryQueryFlag::eDEFAULT, + PxMeshMeshQueryFlags meshMeshFlags = PxMeshMeshQueryFlag::eDEFAULT); /** \brief Find the height field triangles which touch the specified geometry object. Returned triangle indices can be used with #getTriangle() to retrieve the triangle properties. - \param[in] geom The geometry object to test for height field overlaps. Supported geometries are #PxSphereGeometry, #PxCapsuleGeometry and #PxBoxGeometry. The sphere and capsule queries are currently conservative estimates. - \param[in] geomPose Pose of the geometry object - \param[in] hfGeom The height field geometry to check overlap against - \param[in] hfPose Pose of the height field - \param[out] results Indices of overlapping triangles - \param[in] maxResults Size of 'results' buffer - \param[in] startIndex Index of first result to be retrieved. Previous indices are skipped. - \param[out] overflow True if a buffer overflow occurred + \param[in] geom The geometry object to test for height field overlaps. Supported geometries are #PxSphereGeometry, #PxCapsuleGeometry and #PxBoxGeometry. The sphere and capsule queries are currently conservative estimates. + \param[in] geomPose Pose of the geometry object + \param[in] hfGeom The height field geometry to check overlap against + \param[in] hfPose Pose of the height field + \param[out] results Indices of overlapping triangles + \param[in] maxResults Size of 'results' buffer + \param[in] startIndex Index of first result to be retrieved. Previous indices are skipped. + \param[out] overflow True if a buffer overflow occurred + \param[in] queryFlags Optional flags controlling the query. \return Number of overlaps found, i.e. number of elements written to the results buffer - @see PxHeightFieldGeometry getTriangle() + @see PxHeightFieldGeometry getTriangle() PxGeometryQueryFlags */ PX_PHYSX_COMMON_API static PxU32 findOverlapHeightField(const PxGeometry& geom, const PxTransform& geomPose, const PxHeightFieldGeometry& hfGeom, const PxTransform& hfPose, - PxU32* results, PxU32 maxResults, PxU32 startIndex, bool& overflow); + PxU32* results, PxU32 maxResults, PxU32 startIndex, bool& overflow, + PxGeometryQueryFlags queryFlags = PxGeometryQueryFlag::eDEFAULT); /** @@ -153,17 +198,18 @@ public: This function simply sweeps input geometry against each input triangle, in the order they are given. This is an O(N) operation with N = number of input triangles. It does not use any particular acceleration structure. - \param[in] unitDir Normalized direction of the sweep. - \param[in] distance Sweep distance. Needs to be larger than 0. Clamped to PX_MAX_SWEEP_DISTANCE. - \param[in] geom The geometry object to sweep. Supported geometries are #PxSphereGeometry, #PxCapsuleGeometry and #PxBoxGeometry - \param[in] pose Pose of the geometry object to sweep. - \param[in] triangleCount Number of specified triangles - \param[in] triangles Array of triangles to sweep against - \param[out] sweepHit The sweep hit information. See the notes below for limitations about returned results. - \param[in] hitFlags Specification of the kind of information to retrieve on hit. Combination of #PxHitFlag flags. See the notes below for limitations about supported flags. - \param[in] cachedIndex Cached triangle index for subsequent calls. Cached triangle is tested first. Optional parameter. - \param[in] inflation This parameter creates a skin around the swept geometry which increases its extents for sweeping. The sweep will register a hit as soon as the skin touches a shape, and will return the corresponding distance and normal. - \param[in] doubleSided Counterpart of PxMeshGeometryFlag::eDOUBLE_SIDED for input triangles. + \param[in] unitDir Normalized direction of the sweep. + \param[in] distance Sweep distance. Needs to be larger than 0. Clamped to PX_MAX_SWEEP_DISTANCE. + \param[in] geom The geometry object to sweep. Supported geometries are #PxSphereGeometry, #PxCapsuleGeometry and #PxBoxGeometry + \param[in] pose Pose of the geometry object to sweep. + \param[in] triangleCount Number of specified triangles + \param[in] triangles Array of triangles to sweep against + \param[out] sweepHit The sweep hit information. See the notes below for limitations about returned results. + \param[in] hitFlags Specification of the kind of information to retrieve on hit. Combination of #PxHitFlag flags. See the notes below for limitations about supported flags. + \param[in] cachedIndex Cached triangle index for subsequent calls. Cached triangle is tested first. Optional parameter. + \param[in] inflation This parameter creates a skin around the swept geometry which increases its extents for sweeping. The sweep will register a hit as soon as the skin touches a shape, and will return the corresponding distance and normal. + \param[in] doubleSided Counterpart of PxMeshGeometryFlag::eDOUBLE_SIDED for input triangles. + \param[in] queryFlags Optional flags controlling the query. \return True if the swept geometry object hits the specified triangles \note Only the following geometry types are currently supported: PxSphereGeometry, PxCapsuleGeometry, PxBoxGeometry @@ -173,11 +219,10 @@ public: \note ePOSITION is only defined when there is no initial overlap (sweepHit.hadInitialOverlap() == false) \note The returned normal for initially overlapping sweeps is set to -unitDir. \note Otherwise the returned normal is the front normal of the triangle even if PxHitFlag::eMESH_BOTH_SIDES is set. - \note The returned PxSweepHit::faceIndex parameter will hold the index of the hit triangle in input array, i.e. the range is [0; triangleCount). For initially overlapping sweeps, this is the index of overlapping triangle. - \note The returned PxSweepHit::actor and PxSweepHit::shape pointers are not filled. + \note The returned PxGeomSweepHit::faceIndex parameter will hold the index of the hit triangle in input array, i.e. the range is [0; triangleCount). For initially overlapping sweeps, this is the index of overlapping triangle. \note The inflation parameter is not compatible with PxHitFlag::ePRECISE_SWEEP. - @see PxTriangle PxSweepHit PxGeometry PxTransform + @see PxTriangle PxSweepHit PxGeometry PxTransform PxGeometryQueryFlags */ PX_PHYSX_COMMON_API static bool sweep(const PxVec3& unitDir, const PxReal distance, @@ -185,11 +230,12 @@ public: const PxTransform& pose, PxU32 triangleCount, const PxTriangle* triangles, - PxSweepHit& sweepHit, + PxGeomSweepHit& sweepHit, PxHitFlags hitFlags = PxHitFlag::eDEFAULT, const PxU32* cachedIndex = NULL, const PxReal inflation = 0.0f, - bool doubleSided = false); + bool doubleSided = false, + PxGeometryQueryFlags queryFlags = PxGeometryQueryFlag::eDEFAULT); }; diff --git a/Source/ThirdParty/PhysX/geometry/PxMeshScale.h b/Source/ThirdParty/PhysX/geometry/PxMeshScale.h index 02bf3659a..813435664 100644 --- a/Source/ThirdParty/PhysX/geometry/PxMeshScale.h +++ b/Source/ThirdParty/PhysX/geometry/PxMeshScale.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_NX_MESHSCALE -#define PX_PHYSICS_NX_MESHSCALE +#ifndef PX_MESH_SCALE_H +#define PX_MESH_SCALE_H /** \addtogroup geomutils @{ */ @@ -54,7 +52,9 @@ namespace physx /** \brief A class expressing a nonuniform scaling transformation. -The scaling is along arbitrary axes that are specified by PxMeshScale::rotation. +The scaling is along arbitrary axes that are specified by PxMeshScale::rotation. Specifically, PxMeshScale::rotation +describes the rotation from the scaling-axes frame to the mesh-local frame, i.e. PxMeshScale::rotation.rotate(v) transforms +the coordinates of vertex v from the mesh-local frame to the scaling-axes frame. \note Negative scale values are supported for PxTriangleMeshGeometry with absolute values for each component within [PX_MIN_ABS_MESH_SCALE, PX_MAX_ABS_MESH_SCALE] range. @@ -107,7 +107,6 @@ public: rotation = r; } - /** \brief Returns true if the scaling is an identity transformation. */ @@ -161,10 +160,8 @@ public: return (scale.maxElement() <= PX_MESH_SCALE_MAX) && (scale.minElement() >= PX_MESH_SCALE_MIN); } - PxVec3 scale; //!< A nonuniform scaling - PxQuat rotation; //!< The orientation of the scaling axes - - + PxVec3 scale; //!< A nonuniform scaling + PxQuat rotation; //!< The orientation of the scaling axes }; #if !PX_DOXYGEN diff --git a/Source/ThirdParty/PhysX/geometry/PxParticleSystemGeometry.h b/Source/ThirdParty/PhysX/geometry/PxParticleSystemGeometry.h new file mode 100644 index 000000000..f4578d120 --- /dev/null +++ b/Source/ThirdParty/PhysX/geometry/PxParticleSystemGeometry.h @@ -0,0 +1,99 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_PARTICLESYSTEM_GEOMETRY_H +#define PX_PARTICLESYSTEM_GEOMETRY_H +/** \addtogroup geomutils +@{ +*/ +#include "geometry/PxGeometry.h" +#include "common/PxCoreUtilityTypes.h" +#include "foundation/PxBounds3.h" +#include "foundation/PxVec4.h" +#include "PxParticleSystem.h" +#include "PxParticleSolverType.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + /** + \brief Particle system geometry class. + + */ + class PxParticleSystemGeometry : public PxGeometry + { + public: + /** + \brief Default constructor. + + Creates an empty object with no particles. + */ + PX_INLINE PxParticleSystemGeometry() : PxGeometry(PxGeometryType::ePARTICLESYSTEM){} + + /** + \brief Copy constructor. + + \param[in] that Other object + */ + PX_INLINE PxParticleSystemGeometry(const PxParticleSystemGeometry& that) : PxGeometry(that) {} + + /** + \brief Assignment operator + */ + PX_INLINE void operator=(const PxParticleSystemGeometry& that) + { + mType = that.mType; + mSolverType = that.mSolverType; + } + + /** + \brief Returns true if the geometry is valid. + + \return True if the current settings are valid for shape creation. + + @see PxRigidActor::createShape, PxPhysics::createShape + */ + PX_FORCE_INLINE bool isValid() const + { + if(mType != PxGeometryType::ePARTICLESYSTEM) + return false; + + return true; + } + + PxParticleSolverType::Enum mSolverType; + }; + +#if !PX_DOXYGEN +} // namespace physx +#endif + + /** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/geometry/PxPlaneGeometry.h b/Source/ThirdParty/PhysX/geometry/PxPlaneGeometry.h index cbc80e8d5..72c6d1424 100644 --- a/Source/ThirdParty/PhysX/geometry/PxPlaneGeometry.h +++ b/Source/ThirdParty/PhysX/geometry/PxPlaneGeometry.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,18 +22,15 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_NX_PLANE_GEOMETRY -#define PX_PHYSICS_NX_PLANE_GEOMETRY +#ifndef PX_PLANE_GEOMETRY_H +#define PX_PLANE_GEOMETRY_H /** \addtogroup geomutils @{ */ -#include "foundation/PxPlane.h" -#include "foundation/PxTransform.h" #include "geometry/PxGeometry.h" #include "foundation/PxFoundationConfig.h" @@ -59,7 +55,25 @@ To generate a PxTransform from a PxPlane, use PxTransformFromPlaneEquation. class PxPlaneGeometry : public PxGeometry { public: - PX_INLINE PxPlaneGeometry() : PxGeometry(PxGeometryType::ePLANE) {} + /** + \brief Constructor. + */ + PX_INLINE PxPlaneGeometry() : PxGeometry(PxGeometryType::ePLANE) {} + + /** + \brief Copy constructor. + + \param[in] that Other object + */ + PX_INLINE PxPlaneGeometry(const PxPlaneGeometry& that) : PxGeometry(that) {} + + /** + \brief Assignment operator + */ + PX_INLINE void operator=(const PxPlaneGeometry& that) + { + mType = that.mType; + } /** \brief Returns true if the geometry is valid. @@ -69,37 +83,14 @@ public: PX_INLINE bool isValid() const; }; - PX_INLINE bool PxPlaneGeometry::isValid() const { - if (mType != PxGeometryType::ePLANE) + if(mType != PxGeometryType::ePLANE) return false; return true; } - -/** \brief creates a transform from a plane equation, suitable for an actor transform for a PxPlaneGeometry - -\param[in] plane the desired plane equation -\return a PxTransform which will transform the plane PxPlane(1,0,0,0) to the specified plane -*/ - -PX_FOUNDATION_API PxTransform PxTransformFromPlaneEquation(const PxPlane& plane); - -/** \brief creates a plane equation from a transform, such as the actor transform for a PxPlaneGeometry - -\param[in] transform the transform -\return the plane -*/ - - -PX_INLINE PxPlane PxPlaneEquationFromTransform(const PxTransform& transform) -{ - return transform.transform(PxPlane(1.f,0.f,0.f,0.f)); -} - - #if !PX_DOXYGEN } // namespace physx #endif diff --git a/Source/ThirdParty/PhysX/geometry/PxReportCallback.h b/Source/ThirdParty/PhysX/geometry/PxReportCallback.h new file mode 100644 index 000000000..36f2a8fd0 --- /dev/null +++ b/Source/ThirdParty/PhysX/geometry/PxReportCallback.h @@ -0,0 +1,259 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_REPORT_CALLBACK_H +#define PX_REPORT_CALLBACK_H + +/** \addtogroup geomutils + @{ +*/ + +#include "common/PxPhysXCommonConfig.h" +#include "foundation/PxArray.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + /** + \brief Base class for callback reporting an unknown number of items to users. + + This can be used as-is and customized by users, or several pre-designed callbacks can be used instead (see below). + + This design lets users decide how to retrieve the results of a query: + - either one by one via a regular callback + - or one batch at a time via a callback + - or written out directly to their own C-style buffer + - or pushed back to their own PxArray + - etc + + @see PxRegularReportCallback PxLocalStorageReportCallback PxExternalStorageReportCallback PxDynamicArrayReportCallback + */ + template + class PxReportCallback + { + public: + PxReportCallback(T* buffer=NULL, PxU32 capacity=0) : mBuffer(buffer), mCapacity(capacity), mSize(0) {} + virtual ~PxReportCallback() {} + + T* mBuffer; // Destination buffer for writing results. if NULL, the system will use its internal buffer and set that pointer as it sees fit. + // Otherwise users can set it to where they want the results to be written. + PxU32 mCapacity; // Capacity of mBuffer. If mBuffer is NULL, this controls how many items are reported to users at the same time (with a limit of 256). + PxU32 mSize; //!< Current number of items in the buffer. This is entirely managed by the system. + + /** + \brief Reports query results to users. + + This will be called by the system as many times as necessary to report all results. + + \param[in] nbItems Number of reported items + \param[in] items array of reported items + + \return true to continue the query, false to abort the query + */ + virtual bool flushResults(PxU32 nbItems, const T* items) = 0; + }; + + /** + \brief Regular report callback + + This reports results like a regular callback would: + - without explicit buffer management from users + - by default, one item at a time + + This customized callback sends results to users via the processResults() function. + + The capacity parameter dictates how many items can be reported at a time, + i.e. how many times the flushResults/processResults function will be called by the system. + + @see PxReportCallback + */ + template + class PxRegularReportCallback : public PxReportCallback + { + public: + PxRegularReportCallback(const PxU32 capacity=1) + { + PX_ASSERT(capacity<=256); + this->mCapacity = capacity; + } + + virtual bool flushResults(PxU32 nbItems, const T* items) + { + PX_ASSERT(nbItems<=this->mCapacity); + PX_ASSERT(items==this->mBuffer); + return processResults(nbItems, items); + } + + /** + \brief Reports query results to users. + + \param[in] nbItems Number of reported items + \param[in] items array of reported items + + \return true to continue the query, false to abort the query + */ + virtual bool processResults(PxU32 nbItems, const T* items) = 0; + }; + + /** + \brief Local storage report callback + + This is the same as a regular callback, except the destination buffer is a local buffer within the class. + + This customized callback sends results to users via the processResults() function. + + The capacity of the embedded buffer (determined by a template parameter) dictates how many items can be reported at a time, + i.e. how many times the flushResults/processResults function will be called by the system. + + @see PxReportCallback + */ + template + class PxLocalStorageReportCallback : public PxReportCallback + { + T mLocalStorage[capacityT]; + + public: + PxLocalStorageReportCallback() + { + this->mBuffer = mLocalStorage; + this->mCapacity = capacityT; + } + + virtual bool flushResults(PxU32 nbItems, const T* items) + { + PX_ASSERT(items==mLocalStorage); + PX_ASSERT(nbItems<=this->mCapacity); + return processResults(nbItems, items); + } + + /** + \brief Reports query results to users. + + \param[in] nbItems Number of reported items + \param[in] items array of reported items + + \return true to continue the query, false to abort the query + */ + virtual bool processResults(PxU32 nbItems, const T* items) = 0; + }; + + /** + \brief External storage report callback + + This is the same as a regular callback, except the destination buffer is a user-provided external buffer. + + Typically the provided buffer can be larger here than for PxLocalStorageReportCallback, and it could + even be a scratchpad-kind of memory shared by multiple sub-systems. + + This would be the same as having a C-style buffer to write out results in the query interface. + + This customized callback sends results to users via the processResults() function. + + The capacity parameter dictates how many items can be reported at a time, + i.e. how many times the flushResults/processResults function will be called by the system. + + @see PxReportCallback + */ + template + class PxExternalStorageReportCallback : public PxReportCallback + { + public: + PxExternalStorageReportCallback(T* buffer, PxU32 capacity) + { + this->mBuffer = buffer; + this->mCapacity = capacity; + } + + virtual bool flushResults(PxU32 nbItems, const T* items) + { + PX_ASSERT(items==this->mBuffer); + PX_ASSERT(nbItems<=this->mCapacity); + return processResults(nbItems, items); + } + + /** + \brief Reports query results to users. + + \param[in] nbItems Number of reported items + \param[in] items array of reported items + + \return true to continue the query, false to abort the query + */ + virtual bool processResults(PxU32 nbItems, const T* items) = 0; + }; + + /** + \brief Dynamic array report callback + + This callback emulates the behavior of pushing results to a (user-provided) dynamic array. + + This customized callback does not actually call users back during the query, results are + available afterwards in the provided dynamic array. This would be the same as having a PxArray + directly in the query interface. + + @see PxReportCallback + */ + template + class PxDynamicArrayReportCallback : public PxReportCallback + { + public: + PxDynamicArrayReportCallback(PxArray& results) : mResults(results) + { + mResults.reserve(32); + this->mBuffer = mResults.begin(); + this->mCapacity = mResults.capacity(); + } + + virtual bool flushResults(PxU32 nbItems, const T* /*items*/) + { + const PxU32 size = mResults.size(); + const PxU32 capa = mResults.capacity(); + const PxU32 newSize = size+nbItems; + PX_ASSERT(newSize<=capa); + mResults.forceSize_Unsafe(newSize); + if(newSize==capa) + { + const PxU32 newCapa = capa*2; + mResults.reserve(newCapa); + this->mBuffer = mResults.begin() + newSize; + this->mCapacity = mResults.capacity() - newSize; + } + return true; + } + + PxArray& mResults; + }; + +#if !PX_DOXYGEN +} +#endif + +/** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/geometry/PxSimpleTriangleMesh.h b/Source/ThirdParty/PhysX/geometry/PxSimpleTriangleMesh.h index 643905dd4..76b448719 100644 --- a/Source/ThirdParty/PhysX/geometry/PxSimpleTriangleMesh.h +++ b/Source/ThirdParty/PhysX/geometry/PxSimpleTriangleMesh.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_GEOMUTILS_NX_SIMPLETRIANGLEMESH -#define PX_PHYSICS_GEOMUTILS_NX_SIMPLETRIANGLEMESH +#ifndef PX_SIMPLE_TRIANGLE_MESH_H +#define PX_SIMPLE_TRIANGLE_MESH_H /** \addtogroup geomutils @{ */ diff --git a/Source/ThirdParty/PhysX/geometry/PxSphereGeometry.h b/Source/ThirdParty/PhysX/geometry/PxSphereGeometry.h index b89191d46..d93985153 100644 --- a/Source/ThirdParty/PhysX/geometry/PxSphereGeometry.h +++ b/Source/ThirdParty/PhysX/geometry/PxSphereGeometry.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_NX_SPHERE_GEOMETRY -#define PX_PHYSICS_NX_SPHERE_GEOMETRY +#ifndef PX_SPHERE_GEOMETRY_H +#define PX_SPHERE_GEOMETRY_H /** \addtogroup geomutils @{ */ @@ -49,8 +47,26 @@ Spheres are defined by their radius. class PxSphereGeometry : public PxGeometry { public: - PX_INLINE PxSphereGeometry() : PxGeometry(PxGeometryType::eSPHERE), radius(0) {} - PX_INLINE PxSphereGeometry(PxReal ir) : PxGeometry(PxGeometryType::eSPHERE), radius(ir) {} + /** + \brief Constructor. + */ + PX_INLINE PxSphereGeometry(PxReal ir=0.0f) : PxGeometry(PxGeometryType::eSPHERE), radius(ir) {} + + /** + \brief Copy constructor. + + \param[in] that Other object + */ + PX_INLINE PxSphereGeometry(const PxSphereGeometry& that) : PxGeometry(that), radius(that.radius) {} + + /** + \brief Assignment operator + */ + PX_INLINE void operator=(const PxSphereGeometry& that) + { + mType = that.mType; + radius = that.radius; + } /** \brief Returns true if the geometry is valid. @@ -72,14 +88,13 @@ public: PxReal radius; }; - PX_INLINE bool PxSphereGeometry::isValid() const { - if (mType != PxGeometryType::eSPHERE) + if(mType != PxGeometryType::eSPHERE) return false; - if (!PxIsFinite(radius)) + if(!PxIsFinite(radius)) return false; - if (radius <= 0.0f) + if(radius <= 0.0f) return false; return true; diff --git a/Source/ThirdParty/PhysX/geometry/PxTetrahedron.h b/Source/ThirdParty/PhysX/geometry/PxTetrahedron.h new file mode 100644 index 000000000..2e0233737 --- /dev/null +++ b/Source/ThirdParty/PhysX/geometry/PxTetrahedron.h @@ -0,0 +1,111 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_TETRAHEDRON_H +#define PX_TETRAHEDRON_H +/** \addtogroup geomutils +@{ +*/ + +#include "common/PxPhysXCommonConfig.h" +#include "foundation/PxVec3.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + /** + \brief Tetrahedron class. + */ + class PxTetrahedron + { + public: + /** + \brief Constructor + */ + PX_FORCE_INLINE PxTetrahedron() {} + + /** + \brief Constructor + + \param[in] p0 Point 0 + \param[in] p1 Point 1 + \param[in] p2 Point 2 + \param[in] p3 Point 3 + */ + PX_FORCE_INLINE PxTetrahedron(const PxVec3& p0, const PxVec3& p1, const PxVec3& p2, const PxVec3& p3) + { + verts[0] = p0; + verts[1] = p1; + verts[2] = p2; + verts[3] = p3; + } + + /** + \brief Copy constructor + + \param[in] tetrahedron copy + */ + PX_FORCE_INLINE PxTetrahedron(const PxTetrahedron& tetrahedron) + { + verts[0] = tetrahedron.verts[0]; + verts[1] = tetrahedron.verts[1]; + verts[2] = tetrahedron.verts[2]; + verts[3] = tetrahedron.verts[3]; + } + + /** + \brief Destructor + */ + PX_FORCE_INLINE ~PxTetrahedron() {} + + /** + \brief Assignment operator + */ + PX_FORCE_INLINE void operator=(const PxTetrahedron& tetrahedron) + { + verts[0] = tetrahedron.verts[0]; + verts[1] = tetrahedron.verts[1]; + verts[2] = tetrahedron.verts[2]; + verts[3] = tetrahedron.verts[3]; + } + /** + \brief Array of Vertices. + */ + PxVec3 verts[4]; + + }; + + +#if !PX_DOXYGEN +} +#endif + +/** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/geometry/PxTetrahedronMesh.h b/Source/ThirdParty/PhysX/geometry/PxTetrahedronMesh.h new file mode 100644 index 000000000..147a64390 --- /dev/null +++ b/Source/ThirdParty/PhysX/geometry/PxTetrahedronMesh.h @@ -0,0 +1,362 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_TETRAHEDRON_MESH_H +#define PX_TETRAHEDRON_MESH_H +/** \addtogroup geomutils +@{ */ + +#include "foundation/PxVec3.h" +#include "foundation/PxBounds3.h" +#include "foundation/PxUserAllocated.h" +#include "common/PxPhysXCommonConfig.h" +#include "common/PxBase.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + struct PxTetrahedronMeshFlag + { + enum Enum + { + e16_BIT_INDICES = (1 << 1) //!< The tetrahedron mesh has 16bits vertex indices + }; + }; + + /** + \brief collection of set bits defined in PxTetrahedronMeshFlag. + + @see PxTetrahedronMeshFlag + */ + typedef PxFlags PxTetrahedronMeshFlags; + PX_FLAGS_OPERATORS(PxTetrahedronMeshFlag::Enum, PxU8) + + + /** + \brief A data container providing mass, rest pose and other information required for softbody simulation + + Stores properties of softbody like inverse mass per node, rest pose matrix per tetrahedral element etc. + Mainly used internally to store runtime data. + + */ + class PxSoftBodyAuxData : public PxRefCounted + { + public: + /** + \brief Decrements the reference count of a tetrahedron mesh and releases it if the new reference count is zero. + + @see PxPhysics.createTetrahedronMesh() + */ + virtual void release() = 0; + + protected: + PX_INLINE PxSoftBodyAuxData(PxType concreteType, PxBaseFlags baseFlags) : PxRefCounted(concreteType, baseFlags) {} + PX_INLINE PxSoftBodyAuxData(PxBaseFlags baseFlags) : PxRefCounted(baseFlags) {} + virtual ~PxSoftBodyAuxData() {} + + virtual bool isKindOf(const char* name) const { return !::strcmp("PxSoftBodyAuxData", name) || PxRefCounted::isKindOf(name); } + }; + + /** + \brief A tetramedron mesh, also called a 'tetrahedron soup'. + + It is represented as an indexed tetrahedron list. There are no restrictions on the + tetrahedron data. + + To avoid duplicating data when you have several instances of a particular + mesh positioned differently, you do not use this class to represent a + mesh object directly. Instead, you create an instance of this mesh via + the PxTetrahedronMeshGeometry and PxShape classes. + +

Creation

+ + To create an instance of this class call PxPhysics::createTetrahedronMesh(), + and release() to delete it. This is only possible + once you have released all of its PxShape instances. + + +

Visualizations:

+ \li #PxVisualizationParameter::eCOLLISION_AABBS + \li #PxVisualizationParameter::eCOLLISION_SHAPES + \li #PxVisualizationParameter::eCOLLISION_AXES + \li #PxVisualizationParameter::eCOLLISION_FNORMALS + \li #PxVisualizationParameter::eCOLLISION_EDGES + + @see PxTetrahedronMeshDesc PxTetrahedronMeshGeometry PxShape PxPhysics.createTetrahedronMesh() + */ + class PxTetrahedronMesh : public PxRefCounted + { + public: + /** + \brief Returns the number of vertices. + \return number of vertices + @see getVertices() + */ + virtual PxU32 getNbVertices() const = 0; + + /** + \brief Returns the vertices + \return array of vertices + @see getNbVertices() + */ + virtual const PxVec3* getVertices() const = 0; + + + /** + \brief Returns the number of tetrahedrons. + \return number of tetrahedrons + @see getTetrahedrons() + */ + virtual PxU32 getNbTetrahedrons() const = 0; + + /** + \brief Returns the tetrahedron indices. + + The indices can be 16 or 32bit depending on the number of tetrahedrons in the mesh. + Call getTetrahedronMeshFlags() to know if the indices are 16 or 32 bits. + + The number of indices is the number of tetrahedrons * 4. + + \return array of tetrahedrons + @see getNbTetrahedron() getTetrahedronMeshFlags() getTetrahedraRemap() + */ + virtual const void* getTetrahedrons() const = 0; + + /** + \brief Reads the PxTetrahedronMesh flags. + + See the list of flags #PxTetrahedronMeshFlags + + \return The values of the PxTetrahedronMesh flags. + */ + virtual PxTetrahedronMeshFlags getTetrahedronMeshFlags() const = 0; + + + /** + \brief Returns the tetrahedra remapping table. + + The tetrahedra are internally sorted according to various criteria. Hence the internal tetrahedron order + does not always match the original (user-defined) order. The remapping table helps finding the old + indices knowing the new ones: + + remapTable[ internalTetrahedronIndex ] = originalTetrahedronIndex + + \return the remapping table (or NULL if 'PxCookingParams::suppressTriangleMeshRemapTable' has been used) + @see getNbTetrahedron() getTetrahedrons() PxCookingParams::suppressTriangleMeshRemapTable + */ + virtual const PxU32* getTetrahedraRemap() const = 0; + + /** + \brief Returns the local-space (vertex space) AABB from the tetrahedron mesh. + + \return local-space bounds + */ + virtual PxBounds3 getLocalBounds() const = 0; + + /** + \brief Decrements the reference count of a tetrahedron mesh and releases it if the new reference count is zero. + + @see PxPhysics.createTetrahedronMesh() + */ + virtual void release() = 0; + + protected: + PX_INLINE PxTetrahedronMesh(PxType concreteType, PxBaseFlags baseFlags) : PxRefCounted(concreteType, baseFlags) {} + PX_INLINE PxTetrahedronMesh(PxBaseFlags baseFlags) : PxRefCounted(baseFlags) {} + virtual ~PxTetrahedronMesh() {} + + virtual bool isKindOf(const char* name) const { return !::strcmp("PxTetrahedronMesh", name) || PxRefCounted::isKindOf(name); } + }; + + /** + \brief A softbody mesh, containing structures to store collision shape, simulation shape and deformation state + + The class bundles shapes and deformation state of a softbody that is simulated using FEM. The meshes used for + collision detection and for the FEM calculations are both tetrahedral meshes. While collision detection requires + a mesh that matches the surface of the simulated body as exactly as possible, the simulation mesh has more freedom + such that it can be optimized for tetrahedra without small angles and nodes that aren't shared by too many elements. + +

Creation

+ + To create an instance of this class call PxPhysics::createSoftBodyMesh(), + and release() to delete it. This is only possible + once you have released all of its PxShape instances. + + */ + class PxSoftBodyMesh : public PxRefCounted + { + public: + /** + \brief Const accecssor to the softbody's collision mesh. + + @see PxTetrahedronMesh + */ + virtual const PxTetrahedronMesh* getCollisionMesh() const = 0; + + /** + \brief Accecssor to the softbody's collision mesh. + + @see PxTetrahedronMesh + */ + virtual PxTetrahedronMesh* getCollisionMesh() = 0; + + /** + \brief Const accessor to the softbody's simulation mesh. + + @see PxTetrahedronMesh + */ + virtual const PxTetrahedronMesh* getSimulationMesh() const = 0; + + /** + \brief Accecssor to the softbody's simulation mesh. + + @see PxTetrahedronMesh + */ + virtual PxTetrahedronMesh* getSimulationMesh() = 0; + + + /** + \brief Const accessor to the softbodies simulation state. + + @see PxSoftBodyAuxData + */ + virtual const PxSoftBodyAuxData* getSoftBodyAuxData() const = 0; + + /** + \brief Accessor to the softbody's auxilary data like mass and rest pose information + + @see PxSoftBodyAuxData + */ + virtual PxSoftBodyAuxData* getSoftBodyAuxData() = 0; + + /** + \brief Decrements the reference count of a tetrahedron mesh and releases it if the new reference count is zero. + + @see PxPhysics.createTetrahedronMesh() + */ + virtual void release() = 0; + + + protected: + PX_INLINE PxSoftBodyMesh(PxType concreteType, PxBaseFlags baseFlags) : PxRefCounted(concreteType, baseFlags) {} + PX_INLINE PxSoftBodyMesh(PxBaseFlags baseFlags) : PxRefCounted(baseFlags) {} + virtual ~PxSoftBodyMesh() {} + + virtual bool isKindOf(const char* name) const { return !::strcmp("PxSoftBodyMesh", name) || PxRefCounted::isKindOf(name); } + }; + + + /** + + \brief Contains information about how to update the collision mesh's vertices given a deformed simulation tetmesh. + + @see PxTetrahedronMeshData + */ + class PxCollisionMeshMappingData : public PxUserAllocated + { + public: + virtual void release() = 0; + + virtual ~PxCollisionMeshMappingData() {} + }; + + /** + + \brief Stores data to accelerate collision detection of a tetrahedral mesh + + @see PxTetrahedronMeshData + */ + class PxSoftBodyCollisionData : public PxUserAllocated + { + + }; + + /** + + \brief Contains raw geometry information describing the tetmesh's vertices and its elements (tetrahedra) + + @see PxTetrahedronMeshData + */ + class PxTetrahedronMeshData : public PxUserAllocated + { + + }; + + /** + + \brief Stores data to compute and store the state of a deformed tetrahedral mesh + + @see PxTetrahedronMeshData + */ + class PxSoftBodySimulationData : public PxUserAllocated + { + + }; + + /** + + \brief Conbines PxTetrahedronMeshData and PxSoftBodyCollisionData + + @see PxTetrahedronMeshData PxSoftBodyCollisionData + */ + class PxCollisionTetrahedronMeshData : public PxUserAllocated + { + public: + virtual const PxTetrahedronMeshData* getMesh() const = 0; + virtual PxTetrahedronMeshData* getMesh() = 0; + virtual const PxSoftBodyCollisionData* getData() const = 0; + virtual PxSoftBodyCollisionData* getData() = 0; + virtual void release() = 0; + + virtual ~PxCollisionTetrahedronMeshData() {} + }; + + /** + + \brief Conbines PxTetrahedronMeshData and PxSoftBodyCollisionData + + @see PxTetrahedronMeshData PxSoftBodySimulationData + */ + class PxSimulationTetrahedronMeshData : public PxUserAllocated + { + public: + virtual PxTetrahedronMeshData* getMesh() = 0; + virtual PxSoftBodySimulationData* getData() = 0; + virtual void release() = 0; + + virtual ~PxSimulationTetrahedronMeshData() {} + }; + +#if !PX_DOXYGEN +} // namespace physx +#endif + + /** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/geometry/PxTetrahedronMeshGeometry.h b/Source/ThirdParty/PhysX/geometry/PxTetrahedronMeshGeometry.h new file mode 100644 index 000000000..2c32cdf79 --- /dev/null +++ b/Source/ThirdParty/PhysX/geometry/PxTetrahedronMeshGeometry.h @@ -0,0 +1,111 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_TETRAHEDRON_GEOMETRY_H +#define PX_TETRAHEDRON_GEOMETRY_H +/** \addtogroup geomutils +@{ +*/ +#include "geometry/PxGeometry.h" +#include "geometry/PxMeshScale.h" +#include "common/PxCoreUtilityTypes.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + class PxTetrahedronMesh; + + /** + \brief Tetrahedron mesh geometry class. + + This class wraps a tetrahedron mesh such that it can be used in contexts where a PxGeometry type is needed. + */ + class PxTetrahedronMeshGeometry : public PxGeometry + { + public: + /** + \brief Constructor. By default creates an empty object with a NULL mesh and identity scale. + */ + PX_INLINE PxTetrahedronMeshGeometry(PxTetrahedronMesh* mesh = NULL) : + PxGeometry(PxGeometryType::eTETRAHEDRONMESH), + tetrahedronMesh(mesh) + {} + + /** + \brief Copy constructor. + + \param[in] that Other object + */ + PX_INLINE PxTetrahedronMeshGeometry(const PxTetrahedronMeshGeometry& that) : + PxGeometry(that), + tetrahedronMesh(that.tetrahedronMesh) + {} + + /** + \brief Assignment operator + */ + PX_INLINE void operator=(const PxTetrahedronMeshGeometry& that) + { + mType = that.mType; + tetrahedronMesh = that.tetrahedronMesh; + } + + /** + \brief Returns true if the geometry is valid. + + \return True if the current settings are valid for shape creation. + + \note A valid tetrahedron mesh has a positive scale value in each direction (scale.scale.x > 0, scale.scale.y > 0, scale.scale.z > 0). + It is illegal to call PxRigidActor::createShape and PxPhysics::createShape with a tetrahedron mesh that has zero extents in any direction. + + @see PxRigidActor::createShape, PxPhysics::createShape + */ + PX_INLINE bool isValid() const; + + public: + PxTetrahedronMesh* tetrahedronMesh; //!< A reference to the mesh object. + }; + + PX_INLINE bool PxTetrahedronMeshGeometry::isValid() const + { + if(mType != PxGeometryType::eTETRAHEDRONMESH) + return false; + + if(!tetrahedronMesh) + return false; + + return true; + } + +#if !PX_DOXYGEN +} // namespace physx +#endif + + /** @} */ +#endif diff --git a/Source/ThirdParty/PhysX/geometry/PxTriangle.h b/Source/ThirdParty/PhysX/geometry/PxTriangle.h index 8ccc6d646..5fe2dd156 100644 --- a/Source/ThirdParty/PhysX/geometry/PxTriangle.h +++ b/Source/ThirdParty/PhysX/geometry/PxTriangle.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_GEOMUTILS_PX_TRIANGLE -#define PX_PHYSICS_GEOMUTILS_PX_TRIANGLE +#ifndef PX_TRIANGLE_H +#define PX_TRIANGLE_H /** \addtogroup geomutils @{ */ @@ -131,15 +129,25 @@ class PxTriangle /** \return Computes a point on the triangle from u and v barycentric coordinates. */ - PxVec3 pointFromUV(PxReal u, PxReal v) const { return (1.0f-u-v)*verts[0] + u*verts[1] + v*verts[2]; } + PX_FORCE_INLINE PxVec3 pointFromUV(PxReal u, PxReal v) const + { + return (1.0f-u-v)*verts[0] + u*verts[1] + v*verts[2]; + } /** \brief Array of Vertices. */ PxVec3 verts[3]; - }; +//! A padded version of PxTriangle, to safely load its data using SIMD +class PxTrianglePadded : public PxTriangle +{ +public: + PX_FORCE_INLINE PxTrianglePadded() {} + PX_FORCE_INLINE ~PxTrianglePadded() {} + PxU32 padding; +}; #if !PX_DOXYGEN } diff --git a/Source/ThirdParty/PhysX/geometry/PxTriangleMesh.h b/Source/ThirdParty/PhysX/geometry/PxTriangleMesh.h index 6b0eb2efc..1a9f4892a 100644 --- a/Source/ThirdParty/PhysX/geometry/PxTriangleMesh.h +++ b/Source/ThirdParty/PhysX/geometry/PxTriangleMesh.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_GEOMUTILS_NX_TRIANGLEMESH -#define PX_PHYSICS_GEOMUTILS_NX_TRIANGLEMESH +#ifndef PX_TRIANGLE_MESH_H +#define PX_TRIANGLE_MESH_H /** \addtogroup geomutils @{ */ @@ -37,35 +35,28 @@ #include "foundation/PxBounds3.h" #include "common/PxPhysXCommonConfig.h" #include "common/PxBase.h" +#include "foundation/PxUserAllocated.h" #if !PX_DOXYGEN namespace physx { #endif -/** -\brief Enables the dynamic rtree mesh feature. It is recommended to use this feature for scene queries only. -@see PxTriangleMesh::getVerticesForModification -@see PxTriangleMesh::refitBVH -*/ -#define PX_ENABLE_DYNAMIC_MESH_RTREE 1 - /** \brief Mesh midphase structure. This enum is used to select the desired acceleration structure for midphase queries (i.e. raycasts, overlaps, sweeps vs triangle meshes). The PxMeshMidPhase::eBVH33 structure is the one used in recent PhysX versions (up to PhysX 3.3). It has great performance and is - supported on all platforms. + supported on all platforms. It is deprecated since PhysX 5.x. The PxMeshMidPhase::eBVH34 structure is a revisited implementation introduced in PhysX 3.4. It can be significantly faster both - in terms of cooking performance and runtime performance, but it is currently only available on platforms supporting the - SSE2 instuction set. + in terms of cooking performance and runtime performance. */ struct PxMeshMidPhase { enum Enum { - eBVH33 = 0, //!< Default midphase mesh structure, as used up to PhysX 3.3 + eBVH33 = 0, //!< Default midphase mesh structure, as used up to PhysX 3.3 (deprecated) eBVH34 = 1, //!< New midphase mesh structure, introduced in PhysX 3.4 eLAST @@ -82,7 +73,8 @@ struct PxTriangleMeshFlag enum Enum { e16_BIT_INDICES = (1<<1), //!< The triangle mesh has 16bits vertex indices. - eADJACENCY_INFO = (1<<2) //!< The triangle mesh has adjacency information build. + eADJACENCY_INFO = (1<<2), //!< The triangle mesh has adjacency information build. + ePREFER_NO_SDF_PROJ = (1<<3)//!< Indicates that this mesh would preferably not be the mesh projected for mesh-mesh collision. This can indicate that the mesh is not well tessellated. }; }; @@ -122,8 +114,7 @@ once you have released all of its PxShape instances. @see PxTriangleMeshDesc PxTriangleMeshGeometry PxShape PxPhysics.createTriangleMesh() */ - -class PxTriangleMesh : public PxBase +class PxTriangleMesh : public PxRefCounted { public: /** @@ -131,16 +122,15 @@ class PxTriangleMesh : public PxBase \return number of vertices @see getVertices() */ - virtual PxU32 getNbVertices() const = 0; + virtual PxU32 getNbVertices() const = 0; /** \brief Returns the vertices. \return array of vertices @see getNbVertices() */ - virtual const PxVec3* getVertices() const = 0; + virtual const PxVec3* getVertices() const = 0; -#if PX_ENABLE_DYNAMIC_MESH_RTREE /** \brief Returns all mesh vertices for modification. @@ -150,7 +140,7 @@ class PxTriangleMesh : public PxBase \return inplace vertex coordinates for each existing mesh vertex. - \note works only for PxMeshMidPhase::eBVH33 + \note It is recommended to use this feature for scene queries only. \note Size of array returned is equal to the number returned by getNbVertices(). \note This function operates on cooked vertex indices. \note This means the index mapping and vertex count can be different from what was provided as an input to the cooking routine. @@ -160,7 +150,7 @@ class PxTriangleMesh : public PxBase @see getNbVertices() @see refitBVH() */ - virtual PxVec3* getVerticesForModification() = 0; + virtual PxVec3* getVerticesForModification() = 0; /** \brief Refits BVH for mesh vertices. @@ -170,24 +160,24 @@ class PxTriangleMesh : public PxBase \return New bounds for the entire mesh. - \note works only for PxMeshMidPhase::eBVH33 + \note For PxMeshMidPhase::eBVH34 trees the refit operation is only available on non-quantized trees (see PxBVH34MidphaseDesc::quantized) \note PhysX does not keep a mapping from the mesh to mesh shapes that reference it. \note Call PxShape::setGeometry on each shape which references the mesh, to ensure that internal data structures are updated to reflect the new geometry. \note PxShape::setGeometry does not guarantee correct/continuous behavior when objects are resting on top of old or new geometry. \note It is also recommended to make sure that a call to validateTriangleMesh returns true if mesh cleaning is disabled. \note Active edges information will be lost during refit, the rigid body mesh contact generation might not perform as expected. @see getNbVertices() - @see getVerticesForModification() + @see getVerticesForModification() + @see PxBVH34MidphaseDesc::quantized */ - virtual PxBounds3 refitBVH() = 0; -#endif // PX_ENABLE_DYNAMIC_MESH_RTREE + virtual PxBounds3 refitBVH() = 0; /** \brief Returns the number of triangles. \return number of triangles @see getTriangles() getTrianglesRemap() */ - virtual PxU32 getNbTriangles() const = 0; + virtual PxU32 getNbTriangles() const = 0; /** \brief Returns the triangle indices. @@ -200,7 +190,7 @@ class PxTriangleMesh : public PxBase \return array of triangles @see getNbTriangles() getTriangleMeshFlags() getTrianglesRemap() */ - virtual const void* getTriangles() const = 0; + virtual const void* getTriangles() const = 0; /** \brief Reads the PxTriangleMesh flags. @@ -211,7 +201,7 @@ class PxTriangleMesh : public PxBase @see PxTriangleMesh */ - virtual PxTriangleMeshFlags getTriangleMeshFlags() const = 0; + virtual PxTriangleMeshFlags getTriangleMeshFlags() const = 0; /** \brief Returns the triangle remapping table. @@ -225,15 +215,14 @@ class PxTriangleMesh : public PxBase \return the remapping table (or NULL if 'PxCookingParams::suppressTriangleMeshRemapTable' has been used) @see getNbTriangles() getTriangles() PxCookingParams::suppressTriangleMeshRemapTable */ - virtual const PxU32* getTrianglesRemap() const = 0; - + virtual const PxU32* getTrianglesRemap() const = 0; /** \brief Decrements the reference count of a triangle mesh and releases it if the new reference count is zero. @see PxPhysics.createTriangleMesh() */ - virtual void release() = 0; + virtual void release() = 0; /** \brief Returns material table index of given triangle @@ -250,31 +239,62 @@ class PxTriangleMesh : public PxBase \return local-space bounds */ - virtual PxBounds3 getLocalBounds() const = 0; + virtual PxBounds3 getLocalBounds() const = 0; /** - \brief Returns the reference count for shared meshes. - - At creation, the reference count of the mesh is 1. Every shape referencing this mesh increments the - count by 1. When the reference count reaches 0, and only then, the mesh gets destroyed automatically. - - \return the current reference count. + \brief Returns the local-space Signed Distance Field for this mesh if it has one. + \return local-space SDF. */ - virtual PxU32 getReferenceCount() const = 0; + virtual const PxReal* getSDF() const = 0; /** - \brief Acquires a counted reference to a triangle mesh. - - This method increases the reference count of the triangle mesh by 1. Decrement the reference count by calling release() + \brief Returns the resolution of the local-space dense SDF. */ - virtual void acquireReference() = 0; + virtual void getSDFDimensions(PxU32& numX, PxU32& numY, PxU32& numZ) const = 0; + + /** + \brief Sets whether this mesh should be preferred for SDF projection. + + By default, meshes are flagged as preferring projection and the decisions on which mesh to project is based on the triangle and vertex + count. The model with the fewer triangles is projected onto the SDF of the more detailed mesh. + If one of the meshes is set to prefer SDF projection (default) and the other is set to not prefer SDF projection, model flagged as + preferring SDF projection will be projected onto the model flagged as not preferring, regardless of the detail of the respective meshes. + Where both models are flagged as preferring no projection, the less detailed model will be projected as before. + + \param[in] preferProjection Indicates if projection is preferred + */ + virtual void setPreferSDFProjection(bool preferProjection) = 0; + + /** + \brief Returns whether this mesh prefers SDF projection. + \return whether this mesh prefers SDF projection. + */ + virtual bool getPreferSDFProjection() const = 0; + + /** + \brief Returns the mass properties of the mesh assuming unit density. + + The following relationship holds between mass and volume: + + mass = volume * density + + The mass of a unit density mesh is equal to its volume, so this function returns the volume of the mesh. + + Similarly, to obtain the localInertia of an identically shaped object with a uniform density of d, simply multiply the + localInertia of the unit density mesh by d. + + \param[out] mass The mass of the mesh assuming unit density. + \param[out] localInertia The inertia tensor in mesh local space assuming unit density. + \param[out] localCenterOfMass Position of center of mass (or centroid) in mesh local space. + */ + virtual void getMassInformation(PxReal& mass, PxMat33& localInertia, PxVec3& localCenterOfMass) const = 0; protected: - PX_INLINE PxTriangleMesh(PxType concreteType, PxBaseFlags baseFlags) : PxBase(concreteType, baseFlags) {} - PX_INLINE PxTriangleMesh(PxBaseFlags baseFlags) : PxBase(baseFlags) {} - virtual ~PxTriangleMesh() {} + PX_INLINE PxTriangleMesh(PxType concreteType, PxBaseFlags baseFlags) : PxRefCounted(concreteType, baseFlags) {} + PX_INLINE PxTriangleMesh(PxBaseFlags baseFlags) : PxRefCounted(baseFlags) {} + virtual ~PxTriangleMesh() {} - virtual bool isKindOf(const char* name) const { return !::strcmp("PxTriangleMesh", name) || PxBase::isKindOf(name); } + virtual bool isKindOf(const char* name) const { return !::strcmp("PxTriangleMesh", name) || PxRefCounted::isKindOf(name); } }; /** @@ -282,15 +302,16 @@ protected: \brief A triangle mesh containing the PxMeshMidPhase::eBVH33 structure. @see PxMeshMidPhase +@deprecated */ -class PxBVH33TriangleMesh : public PxTriangleMesh +class PX_DEPRECATED PxBVH33TriangleMesh : public PxTriangleMesh { public: protected: - PX_INLINE PxBVH33TriangleMesh(PxType concreteType, PxBaseFlags baseFlags) : PxTriangleMesh(concreteType, baseFlags) {} - PX_INLINE PxBVH33TriangleMesh(PxBaseFlags baseFlags) : PxTriangleMesh(baseFlags) {} - virtual ~PxBVH33TriangleMesh() {} - virtual bool isKindOf(const char* name) const { return !::strcmp("PxBVH33TriangleMesh", name) || PxTriangleMesh::isKindOf(name); } + PX_INLINE PxBVH33TriangleMesh(PxType concreteType, PxBaseFlags baseFlags) : PxTriangleMesh(concreteType, baseFlags) {} + PX_INLINE PxBVH33TriangleMesh(PxBaseFlags baseFlags) : PxTriangleMesh(baseFlags) {} + virtual ~PxBVH33TriangleMesh() {} + virtual bool isKindOf(const char* name) const { return !::strcmp("PxBVH33TriangleMesh", name) || PxTriangleMesh::isKindOf(name); } }; /** @@ -303,10 +324,10 @@ class PxBVH34TriangleMesh : public PxTriangleMesh { public: protected: - PX_INLINE PxBVH34TriangleMesh(PxType concreteType, PxBaseFlags baseFlags) : PxTriangleMesh(concreteType, baseFlags) {} - PX_INLINE PxBVH34TriangleMesh(PxBaseFlags baseFlags) : PxTriangleMesh(baseFlags) {} - virtual ~PxBVH34TriangleMesh() {} - virtual bool isKindOf(const char* name) const { return !::strcmp("PxBVH34TriangleMesh", name) || PxTriangleMesh::isKindOf(name); } + PX_INLINE PxBVH34TriangleMesh(PxType concreteType, PxBaseFlags baseFlags) : PxTriangleMesh(concreteType, baseFlags) {} + PX_INLINE PxBVH34TriangleMesh(PxBaseFlags baseFlags) : PxTriangleMesh(baseFlags) {} + virtual ~PxBVH34TriangleMesh() {} + virtual bool isKindOf(const char* name) const { return !::strcmp("PxBVH34TriangleMesh", name) || PxTriangleMesh::isKindOf(name); } }; #if !PX_DOXYGEN diff --git a/Source/ThirdParty/PhysX/geometry/PxTriangleMeshGeometry.h b/Source/ThirdParty/PhysX/geometry/PxTriangleMeshGeometry.h index 56f58f79a..3f347a156 100644 --- a/Source/ThirdParty/PhysX/geometry/PxTriangleMeshGeometry.h +++ b/Source/ThirdParty/PhysX/geometry/PxTriangleMeshGeometry.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,13 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef PX_PHYSICS_NX_TRIANGLEMESH_GEOMETRY -#define PX_PHYSICS_NX_TRIANGLEMESH_GEOMETRY +#ifndef PX_TRIANGLE_MESH_GEOMETRY_H +#define PX_TRIANGLE_MESH_GEOMETRY_H /** \addtogroup geomutils @{ */ @@ -44,7 +42,6 @@ namespace physx class PxTriangleMesh; - /** \brief Flags controlling the simulated behavior of the triangle mesh geometry. @@ -54,6 +51,7 @@ struct PxMeshGeometryFlag { enum Enum { + eTIGHT_BOUNDS = (1<<0), //!< Use tighter (but more expensive to compute) bounds around the triangle mesh geometry. eDOUBLE_SIDED = (1<<1) //!< Meshes with this flag set are treated as double-sided. //!< This flag is currently only used for raycasts and sweeps (it is ignored for overlap queries). //!< For detailed specifications of this flag for meshes and heightfields please refer to the Geometry Query section of the user guide. @@ -77,37 +75,50 @@ lets the combined object be used anywhere a PxGeometry is needed. The scaling is a transform along arbitrary axes contained in the scale object. The vertices of the mesh in geometry (or shape) space is the PxMeshScale::toMat33() transform, multiplied by the vertex space vertices -in the PxConvexMesh object. +in the PxTriangleMeshGeometry object. */ class PxTriangleMeshGeometry : public PxGeometry { public: /** - \brief Default constructor. + \brief Constructor. By default creates an empty object with a NULL mesh and identity scale. - Creates an empty object with a NULL mesh and identity scale. - */ - PX_INLINE PxTriangleMeshGeometry() : - PxGeometry (PxGeometryType::eTRIANGLEMESH), - triangleMesh(NULL) - {} - - /** - \brief Constructor. \param[in] mesh Mesh pointer. May be NULL, though this will not make the object valid for shape construction. \param[in] scaling Scale factor. \param[in] flags Mesh flags. - \ */ - PX_INLINE PxTriangleMeshGeometry( PxTriangleMesh* mesh, - const PxMeshScale& scaling = PxMeshScale(), + PX_INLINE PxTriangleMeshGeometry( PxTriangleMesh* mesh = NULL, + const PxMeshScale& scaling = PxMeshScale(), PxMeshGeometryFlags flags = PxMeshGeometryFlags()) : - PxGeometry (PxGeometryType::eTRIANGLEMESH), - scale (scaling), - meshFlags (flags), - triangleMesh(mesh) + PxGeometry (PxGeometryType::eTRIANGLEMESH), + scale (scaling), + meshFlags (flags), + triangleMesh(mesh) {} + /** + \brief Copy constructor. + + \param[in] that Other object + */ + PX_INLINE PxTriangleMeshGeometry(const PxTriangleMeshGeometry& that) : + PxGeometry (that), + scale (that.scale), + meshFlags (that.meshFlags), + triangleMesh(that.triangleMesh) + {} + + /** + \brief Assignment operator + */ + PX_INLINE void operator=(const PxTriangleMeshGeometry& that) + { + mType = that.mType; + scale = that.scale; + meshFlags = that.meshFlags; + triangleMesh = that.triangleMesh; + } + /** \brief Returns true if the geometry is valid. @@ -127,7 +138,6 @@ public: PxTriangleMesh* triangleMesh; //!< A reference to the mesh object. }; - PX_INLINE bool PxTriangleMeshGeometry::isValid() const { if(mType != PxGeometryType::eTRIANGLEMESH) diff --git a/Source/ThirdParty/PhysX/geomutils/GuContactBuffer.h b/Source/ThirdParty/PhysX/geomutils/GuContactBuffer.h deleted file mode 100644 index 786735792..000000000 --- a/Source/ThirdParty/PhysX/geomutils/GuContactBuffer.h +++ /dev/null @@ -1,131 +0,0 @@ -// -// Redistribution and use in source and binary forms, with or without -// modification, are permitted provided that the following conditions -// are met: -// * Redistributions of source code must retain the above copyright -// notice, this list of conditions and the following disclaimer. -// * Redistributions in binary form must reproduce the above copyright -// notice, this list of conditions and the following disclaimer in the -// documentation and/or other materials provided with the distribution. -// * Neither the name of NVIDIA CORPORATION nor the names of its -// contributors may be used to endorse or promote products derived -// from this software without specific prior written permission. -// -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY -// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR -// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, -// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, -// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR -// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY -// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -// -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. -// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. -// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - -#ifndef GU_CONTACTBUFFER_H -#define GU_CONTACTBUFFER_H - -#include "geomutils/GuContactPoint.h" -#include "PxPhysXConfig.h" -#include "PxContact.h" - -namespace physx -{ -namespace Gu -{ - - struct NarrowPhaseParams - { - PX_FORCE_INLINE NarrowPhaseParams(PxReal contactDistance, PxReal meshContactMargin, PxReal toleranceLength) : - mContactDistance(contactDistance), - mMeshContactMargin(meshContactMargin), - mToleranceLength(toleranceLength) {} - - PxReal mContactDistance; - PxReal mMeshContactMargin; // PT: Margin used to generate mesh contacts. Temp & unclear, should be removed once GJK is default path. - PxReal mToleranceLength; // PT: copy of PxTolerancesScale::length - }; - -//sizeof(SavedContactData)/sizeof(PxU32) = 17, 1088/17 = 64 triangles in the local array -#define LOCAL_CONTACTS_SIZE 1088 - -class ContactBuffer -{ -public: - - static const PxU32 MAX_CONTACTS = 64; - - Gu::ContactPoint contacts[MAX_CONTACTS]; - PxU32 count; - PxU32 pad; - - PX_FORCE_INLINE void reset() - { - count = 0; - } - - PX_FORCE_INLINE bool contact(const PxVec3& worldPoint, - const PxVec3& worldNormalIn, - PxReal separation, - PxU32 faceIndex1 = PXC_CONTACT_NO_FACE_INDEX - ) - { - PX_ASSERT(PxAbs(worldNormalIn.magnitude()-1)<1e-3f); - - if(count>=MAX_CONTACTS) - return false; - - Gu::ContactPoint& p = contacts[count++]; - p.normal = worldNormalIn; - p.point = worldPoint; - p.separation = separation; - p.internalFaceIndex1= faceIndex1; - return true; - } - - PX_FORCE_INLINE bool contact(const PxVec3& worldPoint, - const PxVec3& worldNormalIn, - PxReal separation, - PxU16 internalUsage, - PxU32 faceIndex1 = PXC_CONTACT_NO_FACE_INDEX - ) - { - PX_ASSERT(PxAbs(worldNormalIn.magnitude() - 1)<1e-3f); - - if (count >= MAX_CONTACTS) - return false; - - Gu::ContactPoint& p = contacts[count++]; - p.normal = worldNormalIn; - p.point = worldPoint; - p.separation = separation; - p.internalFaceIndex1 = faceIndex1; - p.forInternalUse = internalUsage; - return true; - } - - PX_FORCE_INLINE bool contact(const Gu::ContactPoint & pt) - { - if(count>=MAX_CONTACTS) - return false; - contacts[count++] = pt; - return true; - } - - PX_FORCE_INLINE Gu::ContactPoint* contact() - { - if(count>=MAX_CONTACTS) - return NULL; - return &contacts[count++]; - } -}; - -} -} - -#endif diff --git a/Source/ThirdParty/PhysX/geomutils/PxContactBuffer.h b/Source/ThirdParty/PhysX/geomutils/PxContactBuffer.h new file mode 100644 index 000000000..92a47f271 --- /dev/null +++ b/Source/ThirdParty/PhysX/geomutils/PxContactBuffer.h @@ -0,0 +1,95 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_CONTACTBUFFER_H +#define PX_CONTACTBUFFER_H + +#include "PxPhysXConfig.h" +#include "geomutils/PxContactPoint.h" +#include "PxContact.h" + +#if !PX_DOXYGEN +namespace physx +{ +#endif + + class PxContactBuffer + { + public: + + static const PxU32 MAX_CONTACTS = 64; + + PxContactPoint contacts[MAX_CONTACTS]; + PxU32 count; + PxU32 pad; + + PX_FORCE_INLINE void reset() + { + count = 0; + } + + PX_FORCE_INLINE bool contact(const PxVec3& worldPoint, + const PxVec3& worldNormalIn, + PxReal separation, + PxU32 faceIndex1 = PXC_CONTACT_NO_FACE_INDEX + ) + { + PX_ASSERT(PxAbs(worldNormalIn.magnitude()-1)<1e-3f); + + if(count>=MAX_CONTACTS) + return false; + + PxContactPoint& p = contacts[count++]; + p.normal = worldNormalIn; + p.point = worldPoint; + p.separation = separation; + p.internalFaceIndex1= faceIndex1; + return true; + } + + PX_FORCE_INLINE bool contact(const PxContactPoint& pt) + { + if(count>=MAX_CONTACTS) + return false; + contacts[count++] = pt; + return true; + } + + PX_FORCE_INLINE PxContactPoint* contact() + { + if(count>=MAX_CONTACTS) + return NULL; + return &contacts[count++]; + } + }; + +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif diff --git a/Source/ThirdParty/PhysX/geomutils/GuContactPoint.h b/Source/ThirdParty/PhysX/geomutils/PxContactPoint.h similarity index 52% rename from Source/ThirdParty/PhysX/geomutils/GuContactPoint.h rename to Source/ThirdParty/PhysX/geomutils/PxContactPoint.h index 33f851d60..9630bf255 100644 --- a/Source/ThirdParty/PhysX/geomutils/GuContactPoint.h +++ b/Source/ThirdParty/PhysX/geomutils/PxContactPoint.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,87 +22,79 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef GU_CONTACT_POINT_H -#define GU_CONTACT_POINT_H - -/** \addtogroup geomutils -@{ -*/ +#ifndef PX_CONTACT_POINT_H +#define PX_CONTACT_POINT_H #include "foundation/PxVec3.h" +#if !PX_DOXYGEN namespace physx { -namespace Gu -{ - -struct ContactPoint -{ - /** - \brief The normal of the contacting surfaces at the contact point. - - For two shapes s0 and s1, the normal points in the direction that s0 needs to move in to resolve the contact with s1. - */ - PX_ALIGN(16, PxVec3 normal); - /** - \brief The separation of the shapes at the contact point. A negative separation denotes a penetration. - */ - PxReal separation; - - /** - \brief The point of contact between the shapes, in world space. - */ - PX_ALIGN(16, PxVec3 point); - - /** - \brief The max impulse permitted at this point - */ - PxReal maxImpulse; - - PX_ALIGN(16, PxVec3 targetVel); - - /** - \brief The static friction coefficient - */ - PxReal staticFriction; - - /** - \brief Material flags for this contact (eDISABLE_FRICTION, eDISABLE_STRONG_FRICTION). @see PxMaterialFlag - */ - PxU8 materialFlags; - - /** - \brief internal structure used for internal use only - */ - PxU16 forInternalUse; - - /** - \brief The surface index of shape 1 at the contact point. This is used to identify the surface material. - - \note This field is only supported by triangle meshes and heightfields, else it will be set to PXC_CONTACT_NO_FACE_INDEX. - \note This value must be directly after internalFaceIndex0 in memory - */ - - PxU32 internalFaceIndex1; - - /** - \brief The dynamic friction coefficient - */ - PxReal dynamicFriction; - /** - \brief The restitution coefficient - */ - PxReal restitution; - -}; - -} - -} - -/** @} */ +#endif + + struct PxContactPoint + { + /** + \brief The normal of the contacting surfaces at the contact point. + + For two shapes s0 and s1, the normal points in the direction that s0 needs to move in to resolve the contact with s1. + */ + PX_ALIGN(16, PxVec3 normal); + + /** + \brief The separation of the shapes at the contact point. A negative separation denotes a penetration. + */ + PxReal separation; + + /** + \brief The point of contact between the shapes, in world space. + */ + PX_ALIGN(16, PxVec3 point); + + /** + \brief The max impulse permitted at this point + */ + PxReal maxImpulse; + + PX_ALIGN(16, PxVec3 targetVel); + + /** + \brief The static friction coefficient + */ + PxReal staticFriction; + + /** + \brief Material flags for this contact (eDISABLE_FRICTION, eDISABLE_STRONG_FRICTION). @see PxMaterialFlag + */ + PxU8 materialFlags; + + /** + \brief The surface index of shape 1 at the contact point. This is used to identify the surface material. + + \note This field is only supported by triangle meshes and heightfields, else it will be set to PXC_CONTACT_NO_FACE_INDEX. + \note This value must be directly after internalFaceIndex0 in memory + */ + PxU32 internalFaceIndex1; + + /** + \brief The dynamic friction coefficient + */ + PxReal dynamicFriction; + + /** + \brief The restitution coefficient + */ + PxReal restitution; + + PxReal damping; + }; + +#if !PX_DOXYGEN +} // namespace physx +#endif + #endif diff --git a/Source/ThirdParty/PhysX/gpu/PxGpu.h b/Source/ThirdParty/PhysX/gpu/PxGpu.h index 60210a6bb..4b0f34b38 100644 --- a/Source/ThirdParty/PhysX/gpu/PxGpu.h +++ b/Source/ThirdParty/PhysX/gpu/PxGpu.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,7 +22,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. #ifndef PX_GPU_H #define PX_GPU_H @@ -34,11 +33,10 @@ #if PX_SUPPORT_GPU_PHYSX #include "cudamanager/PxCudaContextManager.h" -#include "cudamanager/PxCudaMemoryManager.h" #include "foundation/Px.h" #include "foundation/PxPreprocessor.h" +#include "foundation/PxFoundation.h" #include "common/PxPhysXCommonConfig.h" -#include "PxFoundation.h" /** \brief PxGpuLoadHook @@ -91,6 +89,46 @@ PX_C_EXPORT PX_PHYSX_CORE_API int PX_CALL_CONV PxGetSuggestedCudaDeviceOrdinal(p */ PX_C_EXPORT PX_PHYSX_CORE_API physx::PxCudaContextManager* PX_CALL_CONV PxCreateCudaContextManager(physx::PxFoundation& foundation, const physx::PxCudaContextManagerDesc& desc, physx::PxProfilerCallback* profilerCallback = NULL); +/** + * \brief Sets profiler callback to PhysX GPU + \param[in] profilerCallback PhysX profiler callback instance. + + @see PxGetProfilerCallback() + */ +PX_C_EXPORT PX_PHYSX_CORE_API void PX_CALL_CONV PxSetPhysXGpuProfilerCallback(physx::PxProfilerCallback* profilerCallback); + + +/** +\brief Internally used callback to register function names of cuda kernels +*/ +PX_C_EXPORT PX_PHYSX_CORE_API void PX_CALL_CONV PxCudaRegisterFunction(int moduleIndex, const char* functionName); + +/** +\brief Internally used callback to register cuda modules at load time +*/ +PX_C_EXPORT PX_PHYSX_CORE_API void** PX_CALL_CONV PxCudaRegisterFatBinary(void*); + +/** +\brief Access to the registered cuda modules +*/ +PX_C_EXPORT PX_PHYSX_CORE_API void** PX_CALL_CONV PxGetCudaModuleTable(); + +/** +\brief Number of registered cuda modules +*/ +PX_C_EXPORT PX_PHYSX_CORE_API physx::PxU32 PX_CALL_CONV PxGetCudaModuleTableSize(); + +/** +\brief Access to the loaded cuda functions (kernels) +*/ +PX_C_EXPORT PX_PHYSX_CORE_API physx::PxKernelIndex* PX_CALL_CONV PxGetCudaFunctionTable(); + +/** +\brief Number of loaded cuda functions (kernels) +*/ +PX_C_EXPORT PX_PHYSX_CORE_API physx::PxU32 PX_CALL_CONV PxGetCudaFunctionTableSize(); + + #endif // PX_SUPPORT_GPU_PHYSX -#endif // PX_GPU_H +#endif diff --git a/Source/ThirdParty/PhysX/omnipvd/PxOmniPvd.h b/Source/ThirdParty/PhysX/omnipvd/PxOmniPvd.h new file mode 100644 index 000000000..cc7b8420b --- /dev/null +++ b/Source/ThirdParty/PhysX/omnipvd/PxOmniPvd.h @@ -0,0 +1,94 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#ifndef PX_OMNI_PVD_H +#define PX_OMNI_PVD_H + +#include "PxPhysXConfig.h" + +class OmniPvdWriter; +class OmniPvdFileWriteStream; + +#if !PX_DOXYGEN +namespace physx +{ +#endif + +class PxFoundation; + +class PxOmniPvd +{ +public: + virtual ~PxOmniPvd() + { + } + /** + \brief Gets an instance of the OmniPvd writer + + \return OmniPvdWriter instance on succes, NULL otherwise. + */ + virtual OmniPvdWriter* getWriter() = 0; + + /** + \brief Gets an instance to the OmniPvd file write stream + + \return OmniPvdFileWriteStream instance on succes, NULL otherwise. + */ + virtual OmniPvdFileWriteStream* getFileWriteStream() = 0; + + /** + \brief Starts the OmniPvd sampling + + \return True if sampling started correctly, false if not. + */ + virtual bool startSampling() = 0; + + /** + \brief Releases the PxOmniPvd object + + */ + virtual void release() = 0; +}; +#if !PX_DOXYGEN +} // namespace physx +#endif +/** +\brief Creates an instance of the OmniPvd object + +Creates an instance of the OmniPvd class. There may be only one instance of this class per process. Calling this method after an instance +has been created already will return the same instance over and over. + +\param foundation Foundation instance (see PxFoundation) + +\return PxOmniPvd instance on succes, NULL otherwise. + +*/ +PX_C_EXPORT PX_PHYSX_CORE_API physx::PxOmniPvd* PX_CALL_CONV PxCreateOmniPvd(physx::PxFoundation& foundation); + + +#endif diff --git a/Source/ThirdParty/PhysX/pvd/PxPvd.h b/Source/ThirdParty/PhysX/pvd/PxPvd.h index 08b4aabad..1597e3ab1 100644 --- a/Source/ThirdParty/PhysX/pvd/PxPvd.h +++ b/Source/ThirdParty/PhysX/pvd/PxPvd.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PXPVDSDK_PXPVD_H -#define PXPVDSDK_PXPVD_H +#ifndef PX_PVD_H +#define PX_PVD_H /** \addtogroup pvd @{ @@ -175,4 +174,5 @@ PX_C_EXPORT PxPvd* PX_CALL_CONV PxCreatePvd(PxFoundation& foundation); #endif /** @} */ -#endif // PXPVDSDK_PXPVD_H +#endif + diff --git a/Source/ThirdParty/PhysX/pvd/PxPvdSceneClient.h b/Source/ThirdParty/PhysX/pvd/PxPvdSceneClient.h index 2db2e073b..0c9140089 100644 --- a/Source/ThirdParty/PhysX/pvd/PxPvdSceneClient.h +++ b/Source/ThirdParty/PhysX/pvd/PxPvdSceneClient.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,7 +22,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. @@ -36,17 +35,21 @@ #include "foundation/PxFlags.h" +#if !PX_DOXYGEN namespace physx { +#endif namespace pvdsdk { class PvdClient; - struct PvdDebugPoint; - struct PvdDebugLine; - struct PvdDebugTriangle; - struct PvdDebugText; } -} + struct PxDebugPoint; + struct PxDebugLine; + struct PxDebugTriangle; + struct PxDebugText; +#if !PX_DOXYGEN +} // namespace physx +#endif #if !PX_DOXYGEN namespace physx @@ -108,22 +111,22 @@ class PxPvdSceneClient /** draw points on PVD application's render window */ - virtual void drawPoints(const physx::pvdsdk::PvdDebugPoint* points, PxU32 count) = 0; + virtual void drawPoints(const physx::PxDebugPoint* points, PxU32 count) = 0; /** draw lines on PVD application's render window */ - virtual void drawLines(const physx::pvdsdk::PvdDebugLine* lines, PxU32 count) = 0; + virtual void drawLines(const physx::PxDebugLine* lines, PxU32 count) = 0; /** draw triangles on PVD application's render window */ - virtual void drawTriangles(const physx::pvdsdk::PvdDebugTriangle* triangles, PxU32 count) = 0; + virtual void drawTriangles(const physx::PxDebugTriangle* triangles, PxU32 count) = 0; /** draw text on PVD application's render window */ - virtual void drawText(const physx::pvdsdk::PvdDebugText& text) = 0; + virtual void drawText(const physx::PxDebugText& text) = 0; /** get the underlying client, for advanced users @@ -139,4 +142,4 @@ protected: #endif /** @} */ -#endif // PX_PVD_SCENE_CLIENT_H +#endif diff --git a/Source/ThirdParty/PhysX/pvd/PxPvdTransport.h b/Source/ThirdParty/PhysX/pvd/PxPvdTransport.h index 169ec23df..d9da9dfad 100644 --- a/Source/ThirdParty/PhysX/pvd/PxPvdTransport.h +++ b/Source/ThirdParty/PhysX/pvd/PxPvdTransport.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,12 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PXPVDSDK_PXPVDTRANSPORT_H -#define PXPVDSDK_PXPVDTRANSPORT_H +#ifndef PX_PVD_TRANSPORT_H +#define PX_PVD_TRANSPORT_H /** \addtogroup pvd @{ @@ -126,4 +125,5 @@ PX_C_EXPORT PxPvdTransport* PX_CALL_CONV PxDefaultPvdFileTransportCreate(const c #endif /** @} */ -#endif // PXPVDSDK_PXPVDTRANSPORT_H +#endif + diff --git a/Source/ThirdParty/PhysX/solver/PxSolverDefs.h b/Source/ThirdParty/PhysX/solver/PxSolverDefs.h index f93b6835a..1e67f88ab 100644 --- a/Source/ThirdParty/PhysX/solver/PxSolverDefs.h +++ b/Source/ThirdParty/PhysX/solver/PxSolverDefs.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,7 +22,7 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. @@ -35,7 +34,7 @@ #include "foundation/PxMat33.h" #include "foundation/PxTransform.h" #include "PxConstraintDesc.h" -#include "geomutils/GuContactPoint.h" +#include "geomutils/PxContactPoint.h" #if PX_VC #pragma warning(push) @@ -49,17 +48,9 @@ namespace physx struct PxTGSSolverBodyVel; -namespace Dy -{ - class ArticulationV; - typedef size_t ArticulationLinkHandle; -} - -namespace Sc -{ - class ShapeInteraction; -} - +/** +\brief Struct that the solver uses to store velocity updates for a body +*/ struct PxSolverBody { PX_ALIGN(16, PxVec3) linearVelocity; //!< Delta linear velocity computed by the solver @@ -74,9 +65,11 @@ struct PxSolverBody { } }; - PX_COMPILE_TIME_ASSERT(sizeof(PxSolverBody) == 32); +/** +\brief Struct that the solver uses to store the state and other properties of a body +*/ struct PxSolverBodyData { PX_ALIGN(16, PxVec3 linearVelocity); //!< 12 Pre-solver linear velocity @@ -88,7 +81,6 @@ struct PxSolverBodyData PxU32 nodeIndex; //!< 76 the node idx of this solverBodyData. Used by solver to reference between solver bodies and island bodies. Not required by immediate mode PxReal maxContactImpulse; //!< 80 the max contact impulse PxTransform body2World; //!< 108 the body's transform - PxU16 lockFlags; //!< 110 lock flags PxU16 pad; //!< 112 pad PX_FORCE_INLINE PxReal projectVelocity(const PxVec3& lin, const PxVec3& ang) const @@ -96,10 +88,11 @@ struct PxSolverBodyData return linearVelocity.dot(lin) + angularVelocity.dot(ang); } }; +PX_COMPILE_TIME_ASSERT(0 == (sizeof(PxSolverBodyData) & 15)); //---------------------------------- -/* -* A header that defines the size of a specific batch of constraints (of same type and without dependencies) +/** +\brief A header that defines the size of a specific batch of constraints (of same type and without dependencies) */ struct PxConstraintBatchHeader { @@ -108,9 +101,12 @@ struct PxConstraintBatchHeader PxU16 constraintType; //!< The type of constraint this batch references }; +/** +\brief Constraint descriptor used inside the solver +*/ struct PxSolverConstraintDesc { - static const PxU16 NO_LINK = 0xffff; + static const PxU16 RIGID_BODY = 0xffff; enum ConstraintType { @@ -120,28 +116,34 @@ struct PxSolverConstraintDesc union { - PxSolverBody* bodyA; //!< bodyA pointer - PxTGSSolverBodyVel* tgsBodyA; //!< bodyA pointer - Dy::ArticulationV* articulationA; //!< Articulation pointer for body A - + PxSolverBody* bodyA; //!< bodyA pointer + PxTGSSolverBodyVel* tgsBodyA; //!< bodyA pointer + void* articulationA; //!< Articulation pointer for body A }; union { - PxSolverBody* bodyB; //!< BodyB pointer - PxTGSSolverBodyVel* tgsBodyB; //!< BodyB pointer - Dy::ArticulationV* articulationB; //!< Articulation pointer for body B + PxSolverBody* bodyB; //!< BodyB pointer + PxTGSSolverBodyVel* tgsBodyB; //!< BodyB pointer + void* articulationB; //!< Articulation pointer for body B }; - PxU16 linkIndexA; //!< Link index defining which link in Articulation A this constraint affects. If not an articulation, must be NO_LINK - PxU16 linkIndexB; //!< Link index defining which link in Articulation B this constraint affects. If not an articulation, must be NO_LINK. - PxU32 bodyADataIndex; //!< Body A's index into the SolverBodyData array - PxU32 bodyBDataIndex; //!< Body B's index into the SolverBodyData array - PxU16 writeBackLengthOver4; //!< writeBackLength/4, max writeback length is 256K, allows PxSolverConstraintDesc to fit in 32 bytes - PxU16 constraintLengthOver16; //!< constraintLength/16, max constraint length is 1MB, allows PxSolverConstraintDesc to fit in 32 bytes - PxU8* constraint; //!< Pointer to the constraint rows to be solved - void* writeBack; //!< Pointer to the writeback structure results for this given constraint are to be written to + PxU32 bodyADataIndex; //!< Body A's index into the SolverBodyData array + PxU32 bodyBDataIndex; //!< Body B's index into the SolverBodyData array + + PxU32 linkIndexA; //!< Link index defining which link in Articulation A this constraint affects. If not an articulation, must be NO_LINK + PxU32 linkIndexB; //!< Link index defining which link in Articulation B this constraint affects. If not an articulation, must be NO_LINK + PxU8* constraint; //!< Pointer to the constraint rows to be solved + void* writeBack; //!< Pointer to the writeback structure results for this given constraint are to be written to + + PxU16 progressA; //!< Internal progress counter + PxU16 progressB; //!< Internal progress counter + PxU16 constraintLengthOver16; //!< constraintLength/16, max constraint length is 1MB, allows PxSolverConstraintDesc to fit in 32 bytes + PxU8 padding[10]; }; +/** +\brief Data structure used for preparing constraints before solving them +*/ struct PxSolverConstraintPrepDescBase { enum BodyState @@ -169,6 +171,9 @@ struct PxSolverConstraintPrepDescBase BodyState bodyState1; //!< In: Defines what kind of actor the second body is }; +/** +\brief Data structure used for preparing constraints before solving them +*/ struct PxSolverConstraintPrepDesc : public PxSolverConstraintPrepDescBase { PX_ALIGN(16, Px1DConstraint* rows); //!< The start of the constraint rows @@ -181,15 +186,19 @@ struct PxSolverConstraintPrepDesc : public PxSolverConstraintPrepDescBase bool improvedSlerp; //!< Use improved slerp model bool driveLimitsAreForces; //!< Indicates whether drive limits are forces bool extendedLimits; //!< Indicates whether we want to use extended limits + bool disableConstraint; //!< Disables constraint - PxVec3 body0WorldOffset; //!< Body0 world offset + PxVec3p body0WorldOffset; //!< Body0 world offset }; +/** +\brief Data structure used for preparing constraints before solving them +*/ struct PxSolverContactDesc : public PxSolverConstraintPrepDescBase { - PX_ALIGN(16, Sc::ShapeInteraction* shapeInteraction); //!< Pointer to share interaction. Used for force threshold reports in solver. Set to NULL if using immediate mode. - Gu::ContactPoint* contacts; //!< The start of the contacts for this pair - PxU32 numContacts; //!< The total number of contacs this pair references. + void* shapeInteraction; //!< Pointer to shape interaction. Used for force threshold reports in solver. Set to NULL if using immediate mode. + PxContactPoint* contacts; //!< The start of the contacts for this pair + PxU32 numContacts; //!< The total number of contacts this pair references. bool hasMaxImpulse; //!< Defines whether this pairs has maxImpulses clamping enabled bool disableStrongFriction; //!< Defines whether this pair disables strong friction (sticky friction correlation) @@ -198,7 +207,7 @@ struct PxSolverContactDesc : public PxSolverConstraintPrepDescBase PxReal restDistance; //!< A distance at which the solver should aim to hold the bodies separated. Default is 0 PxReal maxCCDSeparation; //!< A distance used to configure speculative CCD behavior. Default is PX_MAX_F32. Set internally in PhysX for bodies with eENABLE_SPECULATIVE_CCD on. Do not set directly! - PxU8* frictionPtr; //!< InOut: Friction patch correlation data. Set each frame by solver. Can be retained for improved behaviour or discarded each frame. + PxU8* frictionPtr; //!< InOut: Friction patch correlation data. Set each frame by solver. Can be retained for improved behavior or discarded each frame. PxU8 frictionCount; //!< The total number of friction patches in this pair PxReal* contactForces; //!< Out: A buffer for the solver to write applied contact forces to. @@ -210,7 +219,8 @@ struct PxSolverContactDesc : public PxSolverConstraintPrepDescBase PxU16 numContactPatches; //!< Total number of contact patches. PxU16 axisConstraintCount; //!< Axis constraint count. Defines how many constraint rows this pair has produced. Useful for statistical purposes. - PxU8 pad[16 - sizeof(void*)]; + PxReal offsetSlop; //!< Slop value used to snap contact line of action back in-line with the COM. + //PxU8 pad[16 - sizeof(void*)]; }; class PxConstraintAllocator @@ -219,7 +229,7 @@ public: /** \brief Allocates constraint data. It is the application's responsibility to release this memory after PxSolveConstraints has completed. \param[in] byteSize Allocation size in bytes - \return the allocated memory. This address must be 16-byte aligned. + \return The allocated memory. This address must be 16-byte aligned. */ virtual PxU8* reserveConstraintData(const PxU32 byteSize) = 0; @@ -227,23 +237,25 @@ public: \brief Allocates friction data. Friction data can be retained by the application for a given pair and provided as an input to PxSolverContactDesc to improve simulation stability. It is the application's responsibility to release this memory. If this memory is released, the application should ensure it does not pass pointers to this memory to PxSolverContactDesc. \param[in] byteSize Allocation size in bytes - \return the allocated memory. This address must be 4-byte aligned. + \return The allocated memory. This address must be 4-byte aligned. */ virtual PxU8* reserveFrictionData(const PxU32 byteSize) = 0; virtual ~PxConstraintAllocator() {} }; +/** \addtogroup physics +@{ */ struct PxArticulationAxis { enum Enum { - eTWIST = 0, - eSWING1 = 1, - eSWING2 = 2, - eX = 3, - eY = 4, - eZ = 5, + eTWIST = 0, //!< Rotational about eX + eSWING1 = 1, //!< Rotational about eY + eSWING2 = 2, //!< Rotational about eZ + eX = 3, //!< Linear in eX + eY = 4, //!< Linear in eY + eZ = 5, //!< Linear in eZ eCOUNT = 6 }; }; @@ -254,9 +266,9 @@ struct PxArticulationMotion { enum Enum { - eLOCKED = 0, - eLIMITED = 1, - eFREE = 2 + eLOCKED = 0, //!< Locked axis, i.e. degree of freedom (DOF) + eLIMITED = 1, //!< Limited DOF - set limits of joint DOF together with this flag, see PxArticulationJointReducedCoordinate::setLimitParams + eFREE = 2 //!< Free DOF }; }; @@ -267,11 +279,12 @@ struct PxArticulationJointType { enum Enum { - ePRISMATIC = 0, - eREVOLUTE = 1, - eSPHERICAL = 2, - eFIX = 3, - eUNDEFINED = 4 + eFIX = 0, //!< All joint axes, i.e. degrees of freedom (DOFs) locked + ePRISMATIC = 1, //!< Single linear DOF, e.g. cart on a rail + eREVOLUTE = 2, //!< Single rotational DOF, e.g. an elbow joint or a rotational motor, position wrapped at 2pi radians + eREVOLUTE_UNWRAPPED = 3, //!< Single rotational DOF, e.g. an elbow joint or a rotational motor, position not wrapped + eSPHERICAL = 4, //!< Ball and socket joint with two or three DOFs + eUNDEFINED = 5 }; }; @@ -279,8 +292,10 @@ struct PxArticulationFlag { enum Enum { - eFIX_BASE = (1 << 0), - eDRIVE_LIMITS_ARE_FORCES = (1<<1) + eFIX_BASE = (1 << 0), //!< Set articulation base to be fixed. + eDRIVE_LIMITS_ARE_FORCES = (1<<1), //!< Limits for drive effort are forces and torques rather than impulses, see PxArticulationDrive::maxForce. + eDISABLE_SELF_COLLISION = (1<<2), //!< Disable collisions between the articulation's links (note that parent/child collisions are disabled internally in either case). + eCOMPUTE_JOINT_FORCES = (1<<3) //!< Enable in order to be able to query joint solver (i.e. constraint) forces using PxArticulationCache::jointSolverForces. }; }; @@ -291,31 +306,120 @@ struct PxArticulationDriveType { enum Enum { - eFORCE = 0, - eACCELERATION = 1, - eTARGET = 2, - eVELOCITY = 3, + eFORCE = 0, //!< The output of the implicit spring drive controller is a force/torque. + eACCELERATION = 1, //!< The output of the implicit spring drive controller is a joint acceleration (use this to get (spatial)-inertia-invariant behavior of the drive). + eTARGET = 2, //!< Sets the drive gains internally to track a target position almost kinematically (i.e. with very high drive gains). + eVELOCITY = 3, //!< Sets the drive gains internally to track a target velocity almost kinematically (i.e. with very high drive gains). eNONE = 4 }; }; +/** +\brief Data structure to set articulation joint limits. + +- The lower limit should be strictly smaller than the higher limit. If the limits should be equal, use PxArticulationMotion::eLOCKED +and an appropriate offset in the parent/child joint frames. +- The limit units are linear units (equivalent to scene units) for a translational axis, or radians for a rotational axis. + +@see PxArticulationJointReducedCoordinate::setLimitParams, PxArticulationReducedCoordinate +*/ struct PxArticulationLimit { - PxReal low, high; + PxArticulationLimit(){} + + PxArticulationLimit(const PxReal low_, const PxReal high_) + { + low = low_; + high = high_; + } + + /** + \brief The lower limit on the joint axis position. + + Range: [-PX_MAX_F32, high)
+ Default: 0.0f
+ */ + PxReal low; + + /** + \brief The higher limit on the joint axis position. + + Range: (low, PX_MAX_F32]
+ Default: 0.0f
+ */ + PxReal high; }; +/** +\brief Data structure for articulation joint drive configuration. + +@see PxArticulationJointReducedCoordinate::setDriveParams, PxArticulationReducedCoordinate +*/ struct PxArticulationDrive { - PxReal stiffness, damping, maxForce; + PxArticulationDrive(){} + + PxArticulationDrive(const PxReal stiffness_, const PxReal damping_, const PxReal maxForce_, PxArticulationDriveType::Enum driveType_=PxArticulationDriveType::eFORCE) + { + stiffness = stiffness_; + damping = damping_; + maxForce = maxForce_; + driveType = driveType_; + } + + /** + \brief The drive stiffness, i.e. the proportional gain of the implicit PD controller. + + See manual for further information, and the drives' implicit spring-damper (i.e. PD control) implementation in particular. + + Units: (distance = linear scene units)
+ Rotational axis: torque/rad if driveType = PxArticulationDriveType::eFORCE; or (rad/s^2)/rad if driveType = PxArticulationDriveType::eACCELERATION
+ Translational axis: force/distance if driveType = PxArticulationDriveType::eFORCE; or (distance/s^2)/distance if driveType = PxArticulationDriveType::eACCELERATION
+ Range: [0, PX_MAX_F32]
+ Default: 0.0f
+ */ + PxReal stiffness; + + /** + \brief The drive damping, i.e. the derivative gain of the implicit PD controller. + + See manual for further information, and the drives' implicit spring-damper (i.e. PD control) implementation in particular. + + Units: (distance = linear scene units)
+ Rotational axis: torque/(rad/s) if driveType = PxArticulationDriveType::eFORCE; or (rad/s^2)/(rad/s) if driveType = PxArticulationDriveType::eACCELERATION
+ Translational axis: force/(distance/s) if driveType = PxArticulationDriveType::eFORCE; or (distance/s^2)/(distance/s) if driveType = PxArticulationDriveType::eACCELERATION
+ Range: [0, PX_MAX_F32]
+ Default: 0.0f
+ */ + PxReal damping; + + /** + \brief The drive force limit. + + - The limit is enforced regardless of the drive type #PxArticulationDriveType. + - The limit corresponds to a force (linear axis) or torque (rotational axis) if PxArticulationFlag::eDRIVE_LIMITS_ARE_FORCES is set, and to an impulse (force|torque * dt) otherwise. + + Range: [0, PX_MAX_F32]
+ Default: 0.0f
+ + @see PxArticulationFlag::eDRIVE_LIMITS_ARE_FORCES + */ + PxReal maxForce; + + /** + \brief The drive type. + + @see PxArticulationDriveType + */ PxArticulationDriveType::Enum driveType; }; - +/** @} */ struct PxTGSSolverBodyVel { - PX_ALIGN(16, PxVec3) linearVelocity; //12 + PX_ALIGN(16, PxVec3) linearVelocity; //12 PxU16 nbStaticInteractions; //14 Used to accumulate the number of static interactions - PxU16 maxDynamicPartition; //16 Used to accumualte the max partition of dynamic interactions + PxU16 maxDynamicPartition; //16 Used to accumulate the max partition of dynamic interactions PxVec3 angularVelocity; //28 PxU32 partitionMask; //32 Used in partitioning as a bit-field PxVec3 deltaAngDt; //44 @@ -329,26 +433,25 @@ struct PxTGSSolverBodyVel { return linearVelocity.dot(lin) + angularVelocity.dot(ang); } - }; //Needed only by prep, integration and 1D constraints struct PxTGSSolverBodyTxInertia { PxTransform deltaBody2World; - PxMat33 sqrtInvInertia; + PxMat33 sqrtInvInertia; //!< inverse inertia in world space }; struct PxTGSSolverBodyData { - PX_ALIGN(16, PxVec3) originalLinearVelocity; - PxReal maxContactImpulse; - PxVec3 originalAngularVelocity; - PxReal penBiasClamp; + PX_ALIGN(16, PxVec3) originalLinearVelocity; //!< Pre-solver linear velocity. + PxReal maxContactImpulse; //!< The max contact impulse. + PxVec3 originalAngularVelocity; //!< Pre-solver angular velocity + PxReal penBiasClamp; //!< The penetration bias clamp. - PxReal invMass; - PxU32 nodeIndex; - PxReal reportThreshold; + PxReal invMass; //!< Inverse mass. + PxU32 nodeIndex; //!< The node idx of this solverBodyData. Used by solver to reference between solver bodies and island bodies. Not required by immediate mode. + PxReal reportThreshold; //!< Contact force threshold. PxU32 pad; PxReal projectVelocity(const PxVec3& linear, const PxVec3& angular) const @@ -359,52 +462,50 @@ struct PxTGSSolverBodyData struct PxTGSSolverConstraintPrepDescBase { - PxConstraintInvMassScale invMassScales; //!< In: The local mass scaling for this pair. + PxConstraintInvMassScale invMassScales; //!< In: The local mass scaling for this pair. PxSolverConstraintDesc* desc; //!< Output: The PxSolverConstraintDesc filled in by contact prep - const PxTGSSolverBodyVel* body0; //!< In: The first body. Stores velocity information. Unused unless contact involves articulations. - const PxTGSSolverBodyVel *body1; //!< In: The second body. Stores velocity information. Unused unless contact involves articulations. + const PxTGSSolverBodyVel* body0; //!< In: The first body. Stores velocity information. Unused unless contact involves articulations. + const PxTGSSolverBodyVel* body1; //!< In: The second body. Stores velocity information. Unused unless contact involves articulations. - const PxTGSSolverBodyTxInertia* body0TxI; - const PxTGSSolverBodyTxInertia* body1TxI; + const PxTGSSolverBodyTxInertia* body0TxI; //!< In: The first PxTGSSolverBodyTxInertia. Stores the delta body to world transform and sqrtInvInertia for first body. + const PxTGSSolverBodyTxInertia* body1TxI; //!< In: The second PxTGSSolverBodyTxInertia. Stores the delta body to world transform and sqrtInvInertia for second body. - const PxTGSSolverBodyData* bodyData0; - const PxTGSSolverBodyData* bodyData1; + const PxTGSSolverBodyData* bodyData0; //!< In: The first PxTGSSolverBodyData. Stores mass and miscellaneous information for the first body. + const PxTGSSolverBodyData* bodyData1; //!< In: The second PxTGSSolverBodyData. Stores mass and miscellaneous information for the second body. PxTransform bodyFrame0; //!< In: The world-space transform of the first body. PxTransform bodyFrame1; //!< In: The world-space transform of the second body. - PxSolverContactDesc::BodyState bodyState0; //!< In: Defines what kind of actor the first body is - PxSolverContactDesc::BodyState bodyState1; //!< In: Defines what kind of actor the second body is - + PxSolverContactDesc::BodyState bodyState0; //!< In: Defines what kind of actor the first body is + PxSolverContactDesc::BodyState bodyState1; //!< In: Defines what kind of actor the second body is }; struct PxTGSSolverConstraintPrepDesc : public PxTGSSolverConstraintPrepDescBase { - Px1DConstraint* rows; //!< The start of the constraint rows - PxU32 numRows; //!< The number of rows + Px1DConstraint* rows; //!< The start of the constraint rows + PxU32 numRows; //!< The number of rows - PxReal linBreakForce, angBreakForce; //!< Break forces - PxReal minResponseThreshold; //!< The minimum response threshold - void* writeback; //!< Pointer to constraint writeback structure. Reports back joint breaking. If not required, set to NULL. - bool disablePreprocessing; //!< Disable joint pre-processing. Pre-processing can improve stability but under certain circumstances, e.g. when some invInertia rows are zero/almost zero, can cause instabilities. - bool improvedSlerp; //!< Use improved slerp model - bool driveLimitsAreForces; //!< Indicates whether drive limits are forces - bool extendedLimits; //!< Indiciates whether extended limits are used + PxReal linBreakForce, angBreakForce; //!< Break forces + PxReal minResponseThreshold; //!< The minimum response threshold + void* writeback; //!< Pointer to constraint writeback structure. Reports back joint breaking. If not required, set to NULL. + bool disablePreprocessing; //!< Disable joint pre-processing. Pre-processing can improve stability but under certain circumstances, e.g. when some invInertia rows are zero/almost zero, can cause instabilities. + bool improvedSlerp; //!< Use improved slerp model + bool driveLimitsAreForces; //!< Indicates whether drive limits are forces + bool extendedLimits; //!< Indicates whether extended limits are used + bool disableConstraint; //!< Disables constraint - PxVec3 body0WorldOffset; //!< Body0 world offset - PxVec3 cA2w; //!< Location of anchor point A in world space - PxVec3 cB2w; //!< Location of anchor point B in world space + PxVec3p body0WorldOffset; //!< Body0 world offset + PxVec3p cA2w; //!< Location of anchor point A in world space + PxVec3p cB2w; //!< Location of anchor point B in world space }; - struct PxTGSSolverContactDesc : public PxTGSSolverConstraintPrepDescBase { - - Sc::ShapeInteraction* shapeInteraction; //!< Pointer to share interaction. Used for force threshold reports in solver. Set to NULL if using immediate mode. - Gu::ContactPoint* contacts; //!< The start of the contacts for this pair - PxU32 numContacts; //!< The total number of contacs this pair references. + void* shapeInteraction; //!< Pointer to shape interaction. Used for force threshold reports in solver. Set to NULL if using immediate mode. + PxContactPoint* contacts; //!< The start of the contacts for this pair + PxU32 numContacts; //!< The total number of contacts this pair references. bool hasMaxImpulse; //!< Defines whether this pairs has maxImpulses clamping enabled bool disableStrongFriction; //!< Defines whether this pair disables strong friction (sticky friction correlation) @@ -413,7 +514,7 @@ struct PxTGSSolverContactDesc : public PxTGSSolverConstraintPrepDescBase PxReal restDistance; //!< A distance at which the solver should aim to hold the bodies separated. Default is 0 PxReal maxCCDSeparation; //!< A distance used to configure speculative CCD behavior. Default is PX_MAX_F32. Set internally in PhysX for bodies with eENABLE_SPECULATIVE_CCD on. Do not set directly! - PxU8* frictionPtr; //!< InOut: Friction patch correlation data. Set each frame by solver. Can be retained for improved behaviour or discarded each frame. + PxU8* frictionPtr; //!< InOut: Friction patch correlation data. Set each frame by solver. Can be retained for improved behavior or discarded each frame. PxU8 frictionCount; //!< The total number of friction patches in this pair PxReal* contactForces; //!< Out: A buffer for the solver to write applied contact forces to. @@ -425,10 +526,11 @@ struct PxTGSSolverContactDesc : public PxTGSSolverConstraintPrepDescBase PxU16 numContactPatches; //!< Total number of contact patches. PxU16 axisConstraintCount; //!< Axis constraint count. Defines how many constraint rows this pair has produced. Useful for statistical purposes. - PxReal maxImpulse; + PxReal maxImpulse; //!< The maximum impulse the solver is allowed to introduce for this pair of bodies. - PxReal torsionalPatchRadius; - PxReal minTorsionalPatchRadius; + PxReal torsionalPatchRadius; //!< This defines the radius of the contact patch used to apply torsional friction. + PxReal minTorsionalPatchRadius; //!< This defines the minimum radius of the contact patch used to apply torsional friction. + PxReal offsetSlop; //!< Slop value used to snap contact line of action back in-line with the COM. }; #if !PX_DOXYGEN diff --git a/Source/ThirdParty/PhysX/task/PxCpuDispatcher.h b/Source/ThirdParty/PhysX/task/PxCpuDispatcher.h index a9993d5c9..fc2e30ca0 100644 --- a/Source/ThirdParty/PhysX/task/PxCpuDispatcher.h +++ b/Source/ThirdParty/PhysX/task/PxCpuDispatcher.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,16 +22,17 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. -#ifndef PXTASK_PXCPUDISPATCHER_H -#define PXTASK_PXCPUDISPATCHER_H +#ifndef PX_CPU_DISPATCHER_H +#define PX_CPU_DISPATCHER_H -#include "task/PxTaskDefine.h" #include "foundation/PxSimpleTypes.h" +#if !PX_DOXYGEN namespace physx { +#endif class PxBaseTask; @@ -52,15 +52,15 @@ public: /** \brief Called by the TaskManager when a task is to be queued for execution. - Upon receiving a task, the dispatcher should schedule the task - to run when resource is available. After the task has been run, - it should call the release() method and discard it's pointer. + Upon receiving a task, the dispatcher should schedule the task to run. + After the task has been run, it should call the release() method and + discard its pointer. \param[in] task The task to be run. @see PxBaseTask */ - virtual void submitTask( PxBaseTask& task ) = 0; + virtual void submitTask(PxBaseTask& task) = 0; /** \brief Returns the number of available worker threads for this dispatcher. @@ -74,6 +74,9 @@ public: virtual ~PxCpuDispatcher() {} }; -} // end physx namespace +#if !PX_DOXYGEN +} // namespace physx +#endif + +#endif -#endif // PXTASK_PXCPUDISPATCHER_H diff --git a/Source/ThirdParty/PhysX/task/PxTask.h b/Source/ThirdParty/PhysX/task/PxTask.h index d20400629..73851e5d4 100644 --- a/Source/ThirdParty/PhysX/task/PxTask.h +++ b/Source/ThirdParty/PhysX/task/PxTask.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,18 +22,19 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. -#ifndef PXTASK_PXTASK_H -#define PXTASK_PXTASK_H +#ifndef PX_TASK_H +#define PX_TASK_H -#include "task/PxTaskDefine.h" #include "task/PxTaskManager.h" #include "task/PxCpuDispatcher.h" #include "foundation/PxAssert.h" +#if !PX_DOXYGEN namespace physx { +#endif /** * \brief Base class of all task types @@ -114,58 +114,58 @@ public: virtual ~PxTask() {} //! \brief Release method implementation - virtual void release() + virtual void release() PX_OVERRIDE { PX_ASSERT(mTm); // clear mTm before calling taskCompleted() for safety PxTaskManager* save = mTm; mTm = NULL; - save->taskCompleted( *this ); + save->taskCompleted(*this); } //! \brief Inform the PxTaskManager this task must finish before the given // task is allowed to start. - PX_INLINE void finishBefore( PxTaskID taskID ) + PX_INLINE void finishBefore(PxTaskID taskID) { PX_ASSERT(mTm); - mTm->finishBefore( *this, taskID); + mTm->finishBefore(*this, taskID); } //! \brief Inform the PxTaskManager this task cannot start until the given // task has completed. - PX_INLINE void startAfter( PxTaskID taskID ) + PX_INLINE void startAfter(PxTaskID taskID) { PX_ASSERT(mTm); - mTm->startAfter( *this, taskID ); + mTm->startAfter(*this, taskID); } /** - * \brief Manually increment this task's reference count. The task will + * \brief Manually increment this task's reference count. The task will * not be allowed to run until removeReference() is called. */ - PX_INLINE void addReference() + virtual void addReference() PX_OVERRIDE { PX_ASSERT(mTm); - mTm->addReference( mTaskID ); + mTm->addReference(mTaskID); } /** - * \brief Manually decrement this task's reference count. If the reference + * \brief Manually decrement this task's reference count. If the reference * count reaches zero, the task will be dispatched. */ - PX_INLINE void removeReference() + virtual void removeReference() PX_OVERRIDE { PX_ASSERT(mTm); - mTm->decrReference( mTaskID ); + mTm->decrReference(mTaskID); } /** * \brief Return the ref-count for this task */ - PX_INLINE int32_t getReference() const + virtual int32_t getReference() const PX_OVERRIDE { - return mTm->getReference( mTaskID ); + return mTm->getReference(mTaskID); } /** @@ -229,14 +229,12 @@ public: */ PX_INLINE void setContinuation(PxTaskManager& tm, PxBaseTask* c) { - PX_ASSERT( mRefCount == 0 ); + PX_ASSERT(mRefCount == 0); mRefCount = 1; mCont = c; mTm = &tm; - if( mCont ) - { + if(mCont) mCont->addReference(); - } } /** @@ -246,17 +244,17 @@ public: * task, which cannot be NULL. * \param[in] c The task to be executed after this task has finished running */ - PX_INLINE void setContinuation( PxBaseTask* c ) + PX_INLINE void setContinuation(PxBaseTask* c) { - PX_ASSERT( c ); - PX_ASSERT( mRefCount == 0 ); + PX_ASSERT(c); + PX_ASSERT(mRefCount == 0); mRefCount = 1; mCont = c; - if( mCont ) + if(mCont) { mCont->addReference(); mTm = mCont->getTaskManager(); - PX_ASSERT( mTm ); + PX_ASSERT(mTm); } } @@ -269,25 +267,25 @@ public: } /** - * \brief Manually decrement this task's reference count. If the reference + * \brief Manually decrement this task's reference count. If the reference * count reaches zero, the task will be dispatched. */ - PX_INLINE void removeReference() + virtual void removeReference() PX_OVERRIDE { mTm->decrReference(*this); } /** \brief Return the ref-count for this task */ - PX_INLINE int32_t getReference() const + virtual int32_t getReference() const PX_OVERRIDE { return mRefCount; } /** - * \brief Manually increment this task's reference count. The task will + * \brief Manually increment this task's reference count. The task will * not be allowed to run until removeReference() is called. */ - PX_INLINE void addReference() + virtual void addReference() PX_OVERRIDE { mTm->addReference(*this); } @@ -297,12 +295,10 @@ public: * * Decrements the continuation task's reference count, if specified. */ - PX_INLINE void release() + virtual void release() PX_OVERRIDE { - if( mCont ) - { + if(mCont) mCont->removeReference(); - } } protected: @@ -314,7 +310,10 @@ protected: }; -}// end physx namespace +#if !PX_DOXYGEN +} // namespace physx +#endif -#endif // PXTASK_PXTASK_H +#endif + diff --git a/Source/ThirdParty/PhysX/task/PxTaskManager.h b/Source/ThirdParty/PhysX/task/PxTaskManager.h index 003bbb6c5..33af75478 100644 --- a/Source/ThirdParty/PhysX/task/PxTaskManager.h +++ b/Source/ThirdParty/PhysX/task/PxTaskManager.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,18 +22,18 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. -#ifndef PXTASK_PXTASKMANAGER_H -#define PXTASK_PXTASKMANAGER_H +#ifndef PX_TASK_MANAGER_H +#define PX_TASK_MANAGER_H -#include "task/PxTaskDefine.h" #include "foundation/PxSimpleTypes.h" #include "foundation/PxErrorCallback.h" +#if !PX_DOXYGEN namespace physx { -PX_PUSH_PACK_DEFAULT +#endif class PxBaseTask; class PxTask; @@ -44,7 +43,7 @@ typedef unsigned int PxTaskID; /** \brief Identifies the type of each heavyweight PxTask object -\note This enum type is only used by PxTask and GpuTask objects, LightCpuTasks do not use this enum. +\note This enum type is only used by PxTask objects, PxLightCpuTasks do not use this enum. @see PxTask @see PxLightCpuTask @@ -56,9 +55,12 @@ struct PxTaskType */ enum Enum { - TT_CPU, //!< PxTask will be run on the CPU - TT_NOT_PRESENT, //!< Return code when attempting to find a task that does not exist - TT_COMPLETED //!< PxTask execution has been completed + eCPU, //!< PxTask will be run on the CPU + eNOT_PRESENT, //!< Return code when attempting to find a task that does not exist + eCOMPLETED, //!< PxTask execution has been completed + TT_CPU PX_DEPRECATED = eCPU, + TT_NOT_PRESENT PX_DEPRECATED = eNOT_PRESENT, + TT_COMPLETED PX_DEPRECATED = eCOMPLETED }; }; @@ -67,12 +69,12 @@ class PxCpuDispatcher; /** \brief The PxTaskManager interface - A PxTaskManager instance holds references to user-provided dispatcher objects, when tasks are + A PxTaskManager instance holds references to user-provided dispatcher objects. When tasks are submitted the PxTaskManager routes them to the appropriate dispatcher and handles task profiling if enabled. Users should not implement the PxTaskManager interface, the SDK creates its own concrete PxTaskManager object per-scene which users can configure by passing dispatcher objects into the PxSceneDesc. - @see CpuDispatcher + @see PxCpuDispatcher */ class PxTaskManager @@ -84,7 +86,7 @@ public: \param[in] ref The dispatcher object. - @see CpuDispatcher + @see PxCpuDispatcher */ virtual void setCpuDispatcher(PxCpuDispatcher& ref) = 0; @@ -93,9 +95,9 @@ public: \return The CPU dispatcher object. - @see CpuDispatcher + @see PxCpuDispatcher */ - virtual PxCpuDispatcher* getCpuDispatcher() const = 0; + virtual PxCpuDispatcher* getCpuDispatcher() const = 0; /** \brief Reset any dependencies between Tasks @@ -109,7 +111,7 @@ public: /** \brief Called by the owning scene to start the task graph. - \note All tasks with with ref count of 1 will be dispatched. + \note All tasks with ref count of 1 will be dispatched. @see PxTask */ @@ -121,7 +123,7 @@ public: virtual void stopSimulation() = 0; /** - \brief Called by the worker threads to inform the PxTaskManager that a task has completed processing + \brief Called by the worker threads to inform the PxTaskManager that a task has completed processing. \param[in] task The task which has been completed */ @@ -131,7 +133,7 @@ public: \brief Retrieve a task by name \param[in] name The unique name of a task - \return The ID of the task with that name, or TT_NOT_PRESENT if not found + \return The ID of the task with that name, or eNOT_PRESENT if not found */ virtual PxTaskID getNamedTask(const char* name) = 0; @@ -140,20 +142,20 @@ public: \param[in] task The task to be executed \param[in] name The unique name of a task - \param[in] type The type of the task (default TT_CPU) - \return The ID of the task with that name, or TT_NOT_PRESENT if not found + \param[in] type The type of the task (default eCPU) + \return The ID of the task with that name, or eNOT_PRESENT if not found */ - virtual PxTaskID submitNamedTask(PxTask* task, const char* name, PxTaskType::Enum type = PxTaskType::TT_CPU) = 0; + virtual PxTaskID submitNamedTask(PxTask* task, const char* name, PxTaskType::Enum type = PxTaskType::eCPU) = 0; /** \brief Submit an unnamed task. \param[in] task The task to be executed - \param[in] type The type of the task (default TT_CPU) + \param[in] type The type of the task (default eCPU) - \return The ID of the task with that name, or TT_NOT_PRESENT if not found + \return The ID of the task with that name, or eNOT_PRESENT if not found */ - virtual PxTaskID submitUnnamedTask(PxTask& task, PxTaskType::Enum type = PxTaskType::TT_CPU) = 0; + virtual PxTaskID submitUnnamedTask(PxTask& task, PxTaskType::Enum type = PxTaskType::eCPU) = 0; /** \brief Retrieve a task given a task ID @@ -172,7 +174,7 @@ public: /** \brief Construct a new PxTaskManager instance with the given [optional] dispatchers */ - static PxTaskManager* createTaskManager(PxErrorCallback& errorCallback, PxCpuDispatcher* = 0); + static PxTaskManager* createTaskManager(PxErrorCallback& errorCallback, PxCpuDispatcher* = NULL); protected: virtual ~PxTaskManager() {} @@ -196,9 +198,9 @@ protected: friend class PxLightCpuTask; }; -PX_POP_PACK - -} // end physx namespace +#if !PX_DOXYGEN +} // namespace physx +#endif -#endif // PXTASK_PXTASKMANAGER_H +#endif diff --git a/Source/ThirdParty/PhysX/vehicle/PxVehicleComponents.h b/Source/ThirdParty/PhysX/vehicle/PxVehicleComponents.h index dbf0a1c65..1b2c38146 100644 --- a/Source/ThirdParty/PhysX/vehicle/PxVehicleComponents.h +++ b/Source/ThirdParty/PhysX/vehicle/PxVehicleComponents.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,15 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PX_VEHICLE_CORE_COMPONENTS_H -#define PX_VEHICLE_CORE_COMPONENTS_H -/** \addtogroup vehicle - @{ -*/ +#ifndef PX_VEHICLE_COMPONENTS_H +#define PX_VEHICLE_COMPONENTS_H #include "foundation/PxMemory.h" #include "foundation/PxVec3.h" @@ -44,7 +40,7 @@ namespace physx { #endif -class PxVehicleChassisData +class PX_DEPRECATED PxVehicleChassisData { public: @@ -86,7 +82,7 @@ private: }; PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleChassisData)& 0x0f)); -class PxVehicleEngineData +class PX_DEPRECATED PxVehicleEngineData { public: @@ -239,7 +235,7 @@ public: }; PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleEngineData)& 0x0f)); -class PxVehicleGearsData +class PX_DEPRECATED PxVehicleGearsData { public: @@ -344,7 +340,7 @@ public: }; PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleGearsData)& 0x0f)); -class PxVehicleAutoBoxData +class PX_DEPRECATED PxVehicleAutoBoxData { public: @@ -427,7 +423,7 @@ public: }; PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleAutoBoxData)& 0x0f)); -class PxVehicleDifferential4WData +class PX_DEPRECATED PxVehicleDifferential4WData { public: @@ -532,7 +528,7 @@ public: }; PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleDifferential4WData)& 0x0f)); -class PxVehicleDifferentialNWData +class PX_DEPRECATED PxVehicleDifferentialNWData { public: @@ -579,7 +575,7 @@ public: PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleDifferentialNWData)& 0x0f)); -class PxVehicleAckermannGeometryData +class PX_DEPRECATED PxVehicleAckermannGeometryData { public: @@ -652,7 +648,7 @@ PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleAckermannGeometryData)& 0x0f)); \brief Choose between a potentially more expensive but more accurate solution to the clutch model or a potentially cheaper but less accurate solution. @see PxVehicleClutchData */ -struct PxVehicleClutchAccuracyMode +struct PX_DEPRECATED PxVehicleClutchAccuracyMode { enum Enum { @@ -661,7 +657,7 @@ struct PxVehicleClutchAccuracyMode }; }; -class PxVehicleClutchData +class PX_DEPRECATED PxVehicleClutchData { public: @@ -759,7 +755,7 @@ to give less jerky handling behavior. \note The tire load applied as input to the tire force computation is the filtered normalized load multiplied by the rest load. */ -class PxVehicleTireLoadFilterData +class PX_DEPRECATED PxVehicleTireLoadFilterData { public: @@ -815,7 +811,7 @@ public: }; PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleTireLoadFilterData)& 0x0f)); -class PxVehicleWheelData +class PX_DEPRECATED PxVehicleWheelData { public: @@ -957,7 +953,7 @@ private: }; PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleWheelData)& 0x0f)); -class PxVehicleSuspensionData +class PX_DEPRECATED PxVehicleSuspensionData { public: @@ -1023,7 +1019,8 @@ public: \note The sum of the sprung masses of all suspensions of a vehicle should match the mass of the PxRigidDynamic associated with the vehicle. When this condition is satisfied for a vehicle on a horizontal plane the wheels of the vehicle are guaranteed to sit at the rest pose - defined by the wheel centre offset. The mass matching condition is not enforced. + defined by the wheel centre offset. For special cases, where this condition can not be met easily, the flag + #PxVehicleWheelsSimFlag::eDISABLE_SPRUNG_MASS_SUM_CHECK allows to provide sprung mass values that do not sum up to the mass of the PxRigidDynamic. \note As the wheel compresses or elongates along the suspension direction the force generated by the spring is F = |gravity|*mSprungMass + deltaX*mSpringStrength + deltaXDot*mSpringDamperRate @@ -1135,7 +1132,7 @@ private: }; PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleSuspensionData)& 0x0f)); -class PxVehicleAntiRollBarData +class PX_DEPRECATED PxVehicleAntiRollBarData { public: @@ -1175,7 +1172,7 @@ private: }; PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleAntiRollBarData)& 0x0f)); -class PxVehicleTireData +class PX_DEPRECATED PxVehicleTireData { public: friend class PxVehicleWheels4SimData; @@ -1355,5 +1352,4 @@ PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleTireData)& 0x0f)); } // namespace physx #endif -/** @} */ -#endif //PX_VEHICLE_CORE_COMPONENTS_H +#endif diff --git a/Source/ThirdParty/PhysX/vehicle/PxVehicleDrive.h b/Source/ThirdParty/PhysX/vehicle/PxVehicleDrive.h index c0ca3fc61..57be28f50 100644 --- a/Source/ThirdParty/PhysX/vehicle/PxVehicleDrive.h +++ b/Source/ThirdParty/PhysX/vehicle/PxVehicleDrive.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,15 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. #ifndef PX_VEHICLE_DRIVE_H #define PX_VEHICLE_DRIVE_H -/** \addtogroup vehicle - @{ -*/ #include "vehicle/PxVehicleWheels.h" #include "vehicle/PxVehicleComponents.h" @@ -53,7 +49,7 @@ class PxRigidDynamic; \brief Data structure describing non-wheel configuration data of a vehicle that has engine, gears, clutch, and auto-box. @see PxVehicleWheelsSimData for wheels configuration data. */ -class PxVehicleDriveSimData +class PX_DEPRECATED PxVehicleDriveSimData { //= ATTENTION! ===================================================================================== // Changing the data layout of this class breaks the binary serialization format. See comments for @@ -168,7 +164,7 @@ PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleDriveSimData) & 15)); \brief Data structure with instanced dynamics data for vehicle with engine, clutch, gears, autobox @see PxVehicleWheelsDynData for wheels dynamics data. */ -class PxVehicleDriveDynData +class PX_DEPRECATED PxVehicleDriveDynData { public: @@ -493,7 +489,7 @@ PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleDriveDynData) & 15)); \brief A complete vehicle with instance dynamics data and configuration data for wheels and engine,clutch,gears,autobox. @see PxVehicleDrive4W, PxVehicleDriveTank */ -class PxVehicleDrive : public PxVehicleWheels +class PX_DEPRECATED PxVehicleDrive : public PxVehicleWheels { //= ATTENTION! ===================================================================================== // Changing the data layout of this class breaks the binary serialization format. See comments for @@ -561,5 +557,4 @@ PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleDrive) & 15)); } // namespace physx #endif -/** @} */ -#endif //PX_VEHICLE_DRIVE_H +#endif diff --git a/Source/ThirdParty/PhysX/vehicle/PxVehicleDrive4W.h b/Source/ThirdParty/PhysX/vehicle/PxVehicleDrive4W.h index 270f1662e..e2212df48 100644 --- a/Source/ThirdParty/PhysX/vehicle/PxVehicleDrive4W.h +++ b/Source/ThirdParty/PhysX/vehicle/PxVehicleDrive4W.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,15 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. #ifndef PX_VEHICLE_4WDRIVE_H #define PX_VEHICLE_4WDRIVE_H -/** \addtogroup vehicle - @{ -*/ #include "vehicle/PxVehicleDrive.h" #include "vehicle/PxVehicleWheels.h" @@ -56,7 +52,7 @@ class PxRigidDynamic; The drive model incorporates engine, clutch, gears, autobox, differential, and Ackermann steer correction. @see PxVehicleDriveSimData */ -class PxVehicleDriveSimData4W : public PxVehicleDriveSimData +class PX_DEPRECATED PxVehicleDriveSimData4W : public PxVehicleDriveSimData { //= ATTENTION! ===================================================================================== // Changing the data layout of this class breaks the binary serialization format. See comments for @@ -140,7 +136,7 @@ PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleDriveSimData4W) & 15)); @see PxVehicleWheelsSimData, PxVehicleWheelsDynData */ -struct PxVehicleDrive4WWheelOrder +struct PX_DEPRECATED PxVehicleDrive4WWheelOrder { enum Enum { @@ -157,7 +153,7 @@ struct PxVehicleDrive4WWheelOrder @see PxVehicleDriveDynData::setAnalogInput, PxVehicleDriveDynData::getAnalogInput */ -struct PxVehicleDrive4WControl +struct PX_DEPRECATED PxVehicleDrive4WControl { enum Enum { @@ -173,7 +169,7 @@ struct PxVehicleDrive4WControl /** \brief Data structure with instanced dynamics data and configuration data of a vehicle with up to 4 driven wheels and up to 16 non-driven wheels. */ -class PxVehicleDrive4W : public PxVehicleDrive +class PX_DEPRECATED PxVehicleDrive4W : public PxVehicleDrive { //= ATTENTION! ===================================================================================== // Changing the data layout of this class breaks the binary serialization format. See comments for @@ -274,5 +270,4 @@ PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleDrive4W) & 15)); } // namespace physx #endif -/** @} */ -#endif //PX_VEHICLE_4WDRIVE_H +#endif diff --git a/Source/ThirdParty/PhysX/vehicle/PxVehicleDriveNW.h b/Source/ThirdParty/PhysX/vehicle/PxVehicleDriveNW.h index f9334d2a4..23c984bee 100644 --- a/Source/ThirdParty/PhysX/vehicle/PxVehicleDriveNW.h +++ b/Source/ThirdParty/PhysX/vehicle/PxVehicleDriveNW.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,15 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. #ifndef PX_VEHICLE_NWDRIVE_H #define PX_VEHICLE_NWDRIVE_H -/** \addtogroup vehicle - @{ -*/ #include "vehicle/PxVehicleDrive.h" #include "vehicle/PxVehicleWheels.h" @@ -55,7 +51,7 @@ class PxRigidDynamic; engine, clutch, gears, autobox, differential. @see PxVehicleDriveSimData */ -class PxVehicleDriveSimDataNW : public PxVehicleDriveSimData +class PX_DEPRECATED PxVehicleDriveSimDataNW : public PxVehicleDriveSimData { //= ATTENTION! ===================================================================================== // Changing the data layout of this class breaks the binary serialization format. See comments for @@ -115,7 +111,7 @@ PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleDriveSimDataNW) & 15)); @see PxVehicleDriveDynData::setAnalogInput, PxVehicleDriveDynData::getAnalogInput */ -struct PxVehicleDriveNWControl +struct PX_DEPRECATED PxVehicleDriveNWControl { enum Enum { @@ -131,7 +127,7 @@ struct PxVehicleDriveNWControl /** \brief Data structure with instanced dynamics data and configuration data of a vehicle with up to PX_MAX_NB_WHEELS driven wheels. */ -class PxVehicleDriveNW : public PxVehicleDrive +class PX_DEPRECATED PxVehicleDriveNW : public PxVehicleDrive { //= ATTENTION! ===================================================================================== // Changing the data layout of this class breaks the binary serialization format. See comments for @@ -232,5 +228,4 @@ PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleDriveNW) & 15)); } // namespace physx #endif -/** @} */ -#endif //PX_VEHICLE_NWDRIVE_H +#endif diff --git a/Source/ThirdParty/PhysX/vehicle/PxVehicleDriveTank.h b/Source/ThirdParty/PhysX/vehicle/PxVehicleDriveTank.h index b9f163512..420161217 100644 --- a/Source/ThirdParty/PhysX/vehicle/PxVehicleDriveTank.h +++ b/Source/ThirdParty/PhysX/vehicle/PxVehicleDriveTank.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,15 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. #ifndef PX_VEHICLE_DRIVE_TANK_H #define PX_VEHICLE_DRIVE_TANK_H -/** \addtogroup vehicle - @{ -*/ #include "vehicle/PxVehicleDrive.h" #include "vehicle/PxVehicleWheels.h" @@ -56,7 +52,7 @@ class PxRigidDynamic; @see PxVehicleWheelsSimData, PxVehicleWheelsDynData */ -struct PxVehicleDriveTankWheelOrder +struct PX_DEPRECATED PxVehicleDriveTankWheelOrder { enum Enum { @@ -102,7 +98,7 @@ the tank will turn to the left. @see PxVehicleDriveDynData::setAnalogInput, PxVehicleDriveDynData::getAnalogInput */ -struct PxVehicleDriveTankControl +struct PX_DEPRECATED PxVehicleDriveTankControl { enum Enum { @@ -134,7 +130,7 @@ thrust to the right wheels. @see PxVehicleDriveTank::setDriveModel */ -struct PxVehicleDriveTankControlModel +struct PX_DEPRECATED PxVehicleDriveTankControlModel { enum Enum { @@ -147,7 +143,7 @@ struct PxVehicleDriveTankControlModel /** \brief Data structure with instanced dynamics data and configuration data of a tank. */ -class PxVehicleDriveTank : public PxVehicleDrive +class PX_DEPRECATED PxVehicleDriveTank : public PxVehicleDrive { //= ATTENTION! ===================================================================================== // Changing the data layout of this class breaks the binary serialization format. See comments for @@ -276,5 +272,4 @@ PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleDriveTank) & 15)); } // namespace physx #endif -/** @} */ -#endif //PX_VEHICLE_DRIVE_TANK_H +#endif diff --git a/Source/ThirdParty/PhysX/vehicle/PxVehicleNoDrive.h b/Source/ThirdParty/PhysX/vehicle/PxVehicleNoDrive.h index 69982da2d..f8d8cc74d 100644 --- a/Source/ThirdParty/PhysX/vehicle/PxVehicleNoDrive.h +++ b/Source/ThirdParty/PhysX/vehicle/PxVehicleNoDrive.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,15 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. #ifndef PX_VEHICLE_NO_DRIVE_H #define PX_VEHICLE_NO_DRIVE_H -/** \addtogroup vehicle - @{ -*/ #include "vehicle/PxVehicleWheels.h" #include "vehicle/PxVehicleComponents.h" @@ -53,7 +49,7 @@ class PxRigidDynamic; /** \brief Data structure with instanced dynamics data and configuration data of a vehicle with no drive model. */ -class PxVehicleNoDrive : public PxVehicleWheels +class PX_DEPRECATED PxVehicleNoDrive : public PxVehicleWheels { //= ATTENTION! ===================================================================================== // Changing the data layout of this class breaks the binary serialization format. See comments for @@ -212,5 +208,4 @@ PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleNoDrive) & 15)); } // namespace physx #endif -/** @} */ -#endif //PX_VEHICLE_NO_DRIVE_H +#endif diff --git a/Source/ThirdParty/PhysX/vehicle/PxVehicleSDK.h b/Source/ThirdParty/PhysX/vehicle/PxVehicleSDK.h index d47aa5433..cfe58f01a 100644 --- a/Source/ThirdParty/PhysX/vehicle/PxVehicleSDK.h +++ b/Source/ThirdParty/PhysX/vehicle/PxVehicleSDK.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,17 +22,15 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. #ifndef PX_VEHICLE_SDK_H #define PX_VEHICLE_SDK_H -/** \addtogroup vehicle - @{ -*/ #include "foundation/Px.h" +#include "foundation/PxVec3.h" #include "common/PxTypeInfo.h" #if !PX_DOXYGEN @@ -57,7 +54,7 @@ Call this before using any of the vehicle functions. @see PxCloseVehicleSDK */ -PX_C_EXPORT bool PX_CALL_CONV PxInitVehicleSDK(PxPhysics& physics, PxSerializationRegistry* serializationRegistry = NULL); +PX_DEPRECATED PX_C_EXPORT bool PX_CALL_CONV PxInitVehicleSDK(PxPhysics& physics, PxSerializationRegistry* serializationRegistry = NULL); /** @@ -72,7 +69,7 @@ Call this function as part of the physx shutdown process. @see PxInitVehicleSDK */ -PX_C_EXPORT void PX_CALL_CONV PxCloseVehicleSDK(PxSerializationRegistry* serializationRegistry = NULL); +PX_DEPRECATED PX_C_EXPORT void PX_CALL_CONV PxCloseVehicleSDK(PxSerializationRegistry* serializationRegistry = NULL); /** @@ -92,7 +89,7 @@ PX_C_EXPORT void PX_CALL_CONV PxCloseVehicleSDK(PxSerializationRegistry* seriali /** @see PxVehicleDrive4W, PxVehicleDriveTank, PxVehicleDriveNW, PxVehicleNoDrive, PxVehicleWheels::getVehicleType */ -struct PxVehicleTypes +struct PX_DEPRECATED PxVehicleTypes { enum Enum { @@ -113,7 +110,7 @@ struct PxVehicleTypes \note This enum can be used to identify a vehicle object stored in a PxCollection. @see PxBase, PxTypeInfo, PxBase::getConcreteType */ -struct PxVehicleConcreteType +struct PX_DEPRECATED PxVehicleConcreteType { enum Enum { @@ -128,17 +125,20 @@ struct PxVehicleConcreteType /** \brief Set the basis vectors of the vehicle simulation -Default values PxVec3(0,1,0), PxVec3(0,0,1) +See PxVehicleContext for the default values. -Call this function before using PxVehicleUpdates unless the default values are correct. +Call this function before using PxVehicleUpdates unless the default values are correct +or the settings structure is explicitly provided. + +@see PxVehicleContext */ -void PxVehicleSetBasisVectors(const PxVec3& up, const PxVec3& forward); +PX_DEPRECATED void PxVehicleSetBasisVectors(const PxVec3& up, const PxVec3& forward); /** @see PxVehicleSetUpdateMode */ -struct PxVehicleUpdateMode +struct PX_DEPRECATED PxVehicleUpdateMode { enum Enum { @@ -153,13 +153,14 @@ struct PxVehicleUpdateMode with an acceleration to be applied in the next PhysX SDK update or as an immediate velocity modification. -Default behavior is immediate velocity modification. +See PxVehicleContext for the default value. -Call this function before using PxVehicleUpdates for the first time if the default is not the desired behavior. +Call this function before using PxVehicleUpdates for the first time if the default is not the desired behavior +or if the settings structure is not explicitly provided. -@see PxVehicleUpdates +@see PxVehicleUpdates, PxVehicleContext */ -void PxVehicleSetUpdateMode(PxVehicleUpdateMode::Enum vehicleUpdateMode); +PX_DEPRECATED void PxVehicleSetUpdateMode(PxVehicleUpdateMode::Enum vehicleUpdateMode); /** @@ -211,9 +212,9 @@ by the contact modification callback PxVehicleModifyWheelContacts. \note Both angles have default values of Pi/4. -@see PxVehicleSuspensionSweeps, PxVehicleModifyWheelContacts +@see PxVehicleSuspensionSweeps, PxVehicleModifyWheelContacts, PxVehicleContext */ -void PxVehicleSetSweepHitRejectionAngles(const PxF32 pointRejectAngle, const PxF32 normalRejectAngle); +PX_DEPRECATED void PxVehicleSetSweepHitRejectionAngles(const PxF32 pointRejectAngle, const PxF32 normalRejectAngle); /** @@ -225,13 +226,195 @@ the suspension must be applied to dynamic objects that lie under the wheel. This when a heavy wheel is driving on a light object. The value of maxHitActorAcceleration clamps the applied force so that it never generates an acceleration greater than the specified value. -\note Default value of maxHitActorAcceleration is PX_MAX_REAL +See PxVehicleContext for the default value. + +@see PxVehicleContext */ -void PxVehicleSetMaxHitActorAcceleration(const PxF32 maxHitActorAcceleration); +PX_DEPRECATED void PxVehicleSetMaxHitActorAcceleration(const PxF32 maxHitActorAcceleration); + + +/** +\brief Common parameters and settings used for the vehicle simulation. + +To be passed into PxVehicleUpdates(), for example. + +@see PxVehicleUpdates() +*/ +class PX_DEPRECATED PxVehicleContext +{ +public: + + /** + \brief The axis denoting the up direction for vehicles. + + Range: unit length vector
+ Default: PxVec3(0,1,0) + + @see PxVehicleSetBasisVectors() + */ + PxVec3 upAxis; + + /** + \brief The axis denoting the forward direction for vehicles. + + Range: unit length vector
+ Default: PxVec3(0,0,1) + + @see PxVehicleSetBasisVectors() + */ + PxVec3 forwardAxis; + + /** + \brief The axis denoting the side direction for vehicles. + + Has to be the cross product of the up- and forward-axis. The method + computeSideAxis() can be used to do that computation for you. + + Range: unit length vector
+ Default: PxVec3(1,0,0) + + @see PxVehicleSetBasisVectors(), computeSideAxis() + */ + PxVec3 sideAxis; + + /** + \brief Apply vehicle simulation results as acceleration or velocity modification. + + See PxVehicleSetUpdateMode() for details. + + Default: eVELOCITY_CHANGE + + @see PxVehicleSetUpdateMode() + */ + PxVehicleUpdateMode::Enum updateMode; + + /** + \brief Cosine of threshold angle for rejecting sweep hits. + + See PxVehicleSetSweepHitRejectionAngles() for details. + + Range: (1, -1)
+ Default: 0.707f (cosine of 45 degrees) + + @see PxVehicleSetSweepHitRejectionAngles() + */ + PxF32 pointRejectAngleThresholdCosine; + + /** + \brief Cosine of threshold angle for rejecting sweep hits. + + See PxVehicleSetSweepHitRejectionAngles() for details. + + Range: (1, -1)
+ Default: 0.707f (cosine of 45 degrees) + + @see PxVehicleSetSweepHitRejectionAngles() + */ + PxF32 normalRejectAngleThresholdCosine; + + /** + \brief Maximum acceleration experienced by PxRigidDynamic instances that are found to be in contact with a wheel. + + See PxVehicleSetMaxHitActorAcceleration() for details. + + Range: [0, PX_MAX_REAL]
+ Default: PX_MAX_REAL + + @see PxVehicleSetMaxHitActorAcceleration() + */ + PxF32 maxHitActorAcceleration; + + +public: + /** + \brief Constructor sets to default. + */ + PX_INLINE PxVehicleContext(); + + /** + \brief (re)sets the structure to the default. + */ + PX_INLINE void setToDefault(); + + /** + \brief Check if the settings descriptor is valid. + + \return True if the current settings are valid. + */ + PX_INLINE bool isValid() const; + + /** + \brief Compute the side-axis from the up- and forward-axis + */ + PX_INLINE void computeSideAxis(); +}; + +PX_INLINE PxVehicleContext::PxVehicleContext(): + upAxis(0.0f, 1.0f, 0.0f), + forwardAxis(0.0f, 0.0f, 1.0f), + sideAxis(1.0f, 0.0f, 0.0f), + updateMode(PxVehicleUpdateMode::eVELOCITY_CHANGE), + pointRejectAngleThresholdCosine(0.707f), // cosine of 45 degrees + normalRejectAngleThresholdCosine(0.707f), // cosine of 45 degrees + maxHitActorAcceleration(PX_MAX_REAL) +{ +} + +PX_INLINE void PxVehicleContext::setToDefault() +{ + *this = PxVehicleContext(); +} + +PX_INLINE bool PxVehicleContext::isValid() const +{ + if (!upAxis.isNormalized()) + return false; + + if (!forwardAxis.isNormalized()) + return false; + + if (!sideAxis.isNormalized()) + return false; + + if (((upAxis.cross(forwardAxis)) - sideAxis).magnitude() > 0.02f) // somewhat above 1 degree assuming both have unit length + return false; + + if ((pointRejectAngleThresholdCosine >= 1) || (pointRejectAngleThresholdCosine <= -1)) + return false; + + if ((normalRejectAngleThresholdCosine >= 1) || (normalRejectAngleThresholdCosine <= -1)) + return false; + + if (maxHitActorAcceleration < 0.0f) + return false; + + return true; +} + +PX_INLINE void PxVehicleContext::computeSideAxis() +{ + sideAxis = upAxis.cross(forwardAxis); +} + + +/** +\brief Get the default vehicle context. + +Will be used if the corresponding parameters are not specified in methods like +PxVehicleUpdates() etc. + +To set the default values, see the methods PxVehicleSetBasisVectors(), +PxVehicleSetUpdateMode() etc. + +\return The default vehicle context. + +@see PxVehicleSetBasisVectors() PxVehicleSetUpdateMode() +*/ +PX_DEPRECATED const PxVehicleContext& PxVehicleGetDefaultContext(); + #if !PX_DOXYGEN } // namespace physx #endif -/** @} */ -#endif //PX_VEHICLE_SDK_H +#endif diff --git a/Source/ThirdParty/PhysX/vehicle/PxVehicleShaders.h b/Source/ThirdParty/PhysX/vehicle/PxVehicleShaders.h index 18d92440d..0c08d9fd2 100644 --- a/Source/ThirdParty/PhysX/vehicle/PxVehicleShaders.h +++ b/Source/ThirdParty/PhysX/vehicle/PxVehicleShaders.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,15 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. #ifndef PX_VEHICLE_SHADERS_H #define PX_VEHICLE_SHADERS_H -/** \addtogroup vehicle - @{ -*/ #include "foundation/PxSimpleTypes.h" @@ -61,7 +57,7 @@ namespace physx \param[out] tireAlignMoment is the aligning moment of the tire that is to be applied to the vehicle's rigid body (not currently used). @see PxVehicleWheelsDynData::setTireForceShaderFunction, PxVehicleWheelsDynData::setTireForceShaderData */ -typedef void (*PxVehicleComputeTireForce) +PX_DEPRECATED typedef void (*PxVehicleComputeTireForce) (const void* shaderData, const PxF32 tireFriction, const PxF32 longSlip, const PxF32 latSlip, const PxF32 camber, @@ -75,5 +71,4 @@ typedef void (*PxVehicleComputeTireForce) } // namespace physx #endif -/** @} */ -#endif //PX_VEHICLE_SHADERS_H +#endif diff --git a/Source/ThirdParty/PhysX/vehicle/PxVehicleTireFriction.h b/Source/ThirdParty/PhysX/vehicle/PxVehicleTireFriction.h index cdc8ca750..d2408eace 100644 --- a/Source/ThirdParty/PhysX/vehicle/PxVehicleTireFriction.h +++ b/Source/ThirdParty/PhysX/vehicle/PxVehicleTireFriction.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,17 +22,15 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. #ifndef PX_VEHICLE_TIREFRICTION_H #define PX_VEHICLE_TIREFRICTION_H -/** \addtogroup vehicle - @{ -*/ #include "foundation/PxSimpleTypes.h" +#include "common/PxSerialFramework.h" #if !PX_DOXYGEN namespace physx @@ -41,12 +38,14 @@ namespace physx #endif class PxMaterial; +class PxCollection; +class PxOutputStream; /** \brief Driving surface type. Each PxMaterial is associated with a corresponding PxVehicleDrivableSurfaceType. @see PxMaterial, PxVehicleDrivableSurfaceToTireFrictionPairs */ -struct PxVehicleDrivableSurfaceType +struct PX_DEPRECATED PxVehicleDrivableSurfaceType { enum { @@ -59,7 +58,7 @@ struct PxVehicleDrivableSurfaceType \brief Friction for each combination of driving surface type and tire type. @see PxVehicleDrivableSurfaceType, PxVehicleTireData::mType */ -class PxVehicleDrivableSurfaceToTireFrictionPairs +class PX_DEPRECATED PxVehicleDrivableSurfaceToTireFrictionPairs { public: @@ -116,28 +115,83 @@ public: */ void setTypePairFriction(const PxU32 surfaceType, const PxU32 tireType, const PxReal value); + + /** + \brief Compute the surface type associated with a specified PxMaterial instance. + \param[in] surfaceMaterial is the material to be queried for its associated surface type. + \note The surface type may be used to query the friction of a surface type/tire type pair using getTypePairFriction() + \return The surface type associated with a specified PxMaterial instance. + If surfaceMaterial is not referenced by the PxVehicleDrivableSurfaceToTireFrictionPairs a value of 0 will be returned. + @see setup + @see getTypePairFriction + */ + PxU32 getSurfaceType(const PxMaterial& surfaceMaterial) const; + /** \brief Return the friction for a specified combination of surface type and tire type. \return The friction for a specified combination of surface type and tire type. \note The final friction value used by the tire model is the value returned by getTypePairFriction multiplied by the value computed from PxVehicleTireData::mFrictionVsSlipGraph + \note The surface type is associated with a PxMaterial. The mapping between the two may be queried using getSurfaceType(). @see PxVehicleTireData::mFrictionVsSlipGraph + @see getSurfaceType */ PxReal getTypePairFriction(const PxU32 surfaceType, const PxU32 tireType) const; + /** + \brief Return the friction for a specified combination of PxMaterial and tire type. + \return The friction for a specified combination of PxMaterial and tire type. + \note The final friction value used by the tire model is the value returned by getTypePairFriction + multiplied by the value computed from PxVehicleTireData::mFrictionVsSlipGraph + \note If surfaceMaterial is not referenced by the PxVehicleDrivableSurfaceToTireFrictionPairs + a surfaceType of value 0 will be assumed and the corresponding friction value will be returned. + @see PxVehicleTireData::mFrictionVsSlipGraph + */ + PxReal getTypePairFriction(const PxMaterial& surfaceMaterial, const PxU32 tireType) const; + /** \brief Return the maximum number of surface types \return The maximum number of surface types @see allocate */ - PxU32 getMaxNbSurfaceTypes() const {return mMaxNbSurfaceTypes;} + PX_FORCE_INLINE PxU32 getMaxNbSurfaceTypes() const {return mMaxNbSurfaceTypes;} /** \brief Return the maximum number of tire types \return The maximum number of tire types @see allocate */ - PxU32 getMaxNbTireTypes() const {return mMaxNbTireTypes;} + PX_FORCE_INLINE PxU32 getMaxNbTireTypes() const {return mMaxNbTireTypes;} + + /** + \brief Binary serialization of a PxVehicleDrivableSurfaceToTireFrictionPairs instance. + The PxVehicleDrivableSurfaceToTireFrictionPairs instance is serialized to a PxOutputStream. + The materials referenced by the PxVehicleDrivableSurfaceToTireFrictionPairs instance are + serialized to a PxCollection. + \param[in] frictionTable is the PxVehicleDrivableSurfaceToTireFrictionPairs instance to be serialized. + \param[in] materialIds are unique ids that will be used to add the materials to the collection. + \param[in] nbMaterialIds is the length of the materialIds array. It must be sufficient to cover all materials. + \param[out] collection is the PxCollection instance that is to be used to serialize the PxMaterial instances referenced by the + PxVehicleDrivableSurfaceToTireFrictionPairs instance. + \param[out] stream contains the memory block for the binary serialized friction table. + \note If a material has already been added to the collection with a PxSerialObjectId, it will not be added again. + \note If all materials have already been added to the collection with a PxSerialObjectId, it is legal to pass a NULL ptr for the materialIds array. + \note frictionTable references PxMaterial instances, which are serialized using PxCollection. + The PxCollection instance may be used to serialize an entire scene that also references some or none of those material instances + or particular objects in a scene or nothing at all. The complementary deserialize() function requires the same collection instance + or more typically a deserialized copy of the collection to be passed as a function argument. + @see deserializeFromBinary + */ + static void serializeToBinary(const PxVehicleDrivableSurfaceToTireFrictionPairs& frictionTable, const PxSerialObjectId* materialIds, const PxU32 nbMaterialIds, PxCollection* collection, PxOutputStream& stream); + + /** + \brief Deserialize from a memory block to create a PxVehicleDrivableSurfaceToTireFrictionPairs instance. + \param[in] collection contains the PxMaterial instances that will be referenced by the friction table. + \param[in] memBlock is a binary array that may be retrieved or copied from the stream in the complementary serializeToBinary function. + \return A PxVehicleDrivableSurfaceToTireFrictionPairs instance whose base address is equal to the memBlock ptr. + @see serializeToBinary + */ + static PxVehicleDrivableSurfaceToTireFrictionPairs* deserializeFromBinary(const PxCollection& collection, void* memBlock); private: @@ -173,6 +227,11 @@ private: */ PxVehicleDrivableSurfaceType* mDrivableSurfaceTypes; + /** + \brief A PxSerialObjectId per surface type used internally for serialization. + */ + PxSerialObjectId* mMaterialSerialIds; + /** \brief Number of different driving surface types. @@ -203,13 +262,6 @@ private: */ PxU32 mMaxNbTireTypes; - -#if !PX_P64_FAMILY - PxU32 mPad[1]; -#else - PxU32 mPad[2]; -#endif - PxVehicleDrivableSurfaceToTireFrictionPairs(){} ~PxVehicleDrivableSurfaceToTireFrictionPairs(){} }; @@ -219,5 +271,4 @@ PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleDrivableSurfaceToTireFrictionPairs) & } // namespace physx #endif -/** @} */ -#endif //PX_VEHICLE_TIREFRICTION_H +#endif diff --git a/Source/ThirdParty/PhysX/vehicle/PxVehicleUpdate.h b/Source/ThirdParty/PhysX/vehicle/PxVehicleUpdate.h index 40306fdcd..ae6bc5078 100644 --- a/Source/ThirdParty/PhysX/vehicle/PxVehicleUpdate.h +++ b/Source/ThirdParty/PhysX/vehicle/PxVehicleUpdate.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,40 +22,37 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. #ifndef PX_VEHICLE_UPDATE_H #define PX_VEHICLE_UPDATE_H -/** \addtogroup vehicle - @{ -*/ #include "vehicle/PxVehicleSDK.h" #include "vehicle/PxVehicleTireFriction.h" #include "foundation/PxSimpleTypes.h" #include "foundation/PxMemory.h" #include "foundation/PxTransform.h" -#include "PxBatchQueryDesc.h" +#include "PxQueryFiltering.h" #if !PX_DOXYGEN namespace physx { #endif - class PxBatchQuery; class PxContactModifyPair; class PxVehicleWheels; class PxVehicleDrivableSurfaceToTireFrictionPairs; class PxVehicleTelemetryData; + class PxBatchQueryExt; /** \brief Structure containing data describing the non-persistent state of each suspension/wheel/tire unit. This structure is filled out in PxVehicleUpdates and PxVehicleUpdateSingleVehicleAndStoreTelemetryData @see PxVehicleUpdates, PxVehicleUpdateSingleVehicleAndStoreTelemetryData */ - struct PxWheelQueryResult + struct PX_DEPRECATED PxWheelQueryResult { PxWheelQueryResult() { @@ -220,7 +216,7 @@ namespace physx PxTransform localPose; }; - struct PxVehicleWheelQueryResult + struct PX_DEPRECATED PxVehicleWheelQueryResult { /** \brief Pointer to an PxWheelQueryResult buffer of length nbWheelQueryResults @@ -240,12 +236,12 @@ namespace physx }; /** - \brief Structure containing data that is computed for a wheel during concurrent calls to PxVehicleUpdates - but which cannot be safely concurrently applied. + \brief Structure containing data that is computed for a wheel during concurrent calls to PxVehicleUpdates or + PxVehicleUpdateSingleVehicleAndStoreTelemetryData but which cannot be safely concurrently applied. - @see PxVehicleUpdates, PxVehiclePostUpdates, PxVehicleConcurrentUpdate + @see PxVehicleUpdates, PxVehicleUpdateSingleVehicleAndStoreTelemetryData, PxVehiclePostUpdates, PxVehicleConcurrentUpdate */ - struct PxVehicleWheelConcurrentUpdateData + struct PX_DEPRECATED PxVehicleWheelConcurrentUpdateData { friend class PxVehicleUpdate; @@ -266,13 +262,13 @@ namespace physx }; /** - \brief Structure containing data that is computed for a vehicle and its wheels during concurrent calls to PxVehicleUpdates - but which cannot be safely concurrently applied. + \brief Structure containing data that is computed for a vehicle and its wheels during concurrent calls to PxVehicleUpdates or + PxVehicleUpdateSingleVehicleAndStoreTelemetryData but which cannot be safely concurrently applied. - @see PxVehicleUpdates, PxVehiclePostUpdates, PxVehicleWheelConcurrentUpdateData + @see PxVehicleUpdates, PxVehicleUpdateSingleVehicleAndStoreTelemetryData, PxVehiclePostUpdates, PxVehicleWheelConcurrentUpdateData */ - struct PxVehicleConcurrentUpdateData + struct PX_DEPRECATED PxVehicleConcurrentUpdateData { friend class PxVehicleUpdate; @@ -311,21 +307,18 @@ namespace physx /** \brief Perform raycasts for all suspension lines for all vehicles. - \param[in] batchQuery is a PxBatchQuery instance used to specify shader data and functions for the raycast scene queries. + \param[in] batchQuery is a PxBatchQueryExt instance used to specify shader data and functions for the raycast scene queries. \param[in] nbVehicles is the number of vehicles in the vehicles array. \param[in] vehicles is an array of all vehicles that are to have a raycast issued from each wheel. - \param[in] nbSceneQueryResults must be greater than or equal to the total number of wheels of all the vehicles in the vehicles array; that is, - sceneQueryResults must have dimensions large enough for one raycast hit result per wheel for all the vehicles in the vehicles array. - - \param[in] sceneQueryResults must persist without being overwritten until the end of the next PxVehicleUpdates call. - \param[in] vehiclesToRaycast is an array of bools of length nbVehicles that is used to decide if raycasts will be performed for the corresponding vehicle in the vehicles array. If vehiclesToRaycast[i] is true then suspension line raycasts will be performed for vehicles[i]. If vehiclesToRaycast[i] is false then suspension line raycasts will not be performed for vehicles[i]. + \param[in] queryFlags filter flags for the batched scene queries + \note If vehiclesToRaycast is NULL then raycasts are performed for all vehicles in the vehicles array. \note If vehiclesToRaycast[i] is false then the vehicle stored in vehicles[i] will automatically use the raycast or sweep hit planes recorded by the most recent @@ -344,28 +337,23 @@ namespace physx \note Only blocking hits are supported (PxQueryHitType::eBLOCK). @see PxVehicleDrive4W::setToRestState, PxVehicleDriveNW::setToRestState, PxVehicleDriveTank::setToRestState, PxVehicleNoDrive::setToRestState - */ - void PxVehicleSuspensionRaycasts - (PxBatchQuery* batchQuery, - const PxU32 nbVehicles, PxVehicleWheels** vehicles, - const PxU32 nbSceneQueryResults, PxRaycastQueryResult* sceneQueryResults, - const bool* vehiclesToRaycast = NULL); + @see PxBatchQueryExt::raycast + */ + PX_DEPRECATED void PxVehicleSuspensionRaycasts( PxBatchQueryExt* batchQuery, + const PxU32 nbVehicles, PxVehicleWheels** vehicles, + const bool* vehiclesToRaycast = NULL, + const PxQueryFlags queryFlags = PxQueryFlag::eSTATIC | PxQueryFlag::eDYNAMIC | PxQueryFlag::ePREFILTER); /** \brief Perform sweeps for all suspension lines for all vehicles. - \param[in] batchQuery is a PxBatchQuery instance used to specify shader data and functions for the sweep scene queries. + \param[in] batchQuery is a PxBatchQueryExt instance used to specify shader data and functions for the sweep scene queries. \param[in] nbVehicles is the number of vehicles in the vehicles array. \param[in] vehicles is an array of all vehicles that are to have a sweep issued from each wheel. - \param[in] nbSceneQueryResults must be greater than or equal to the total number of wheels of all the vehicles in the vehicles array; that is, - sceneQueryResults must have dimensions large enough for one sweep hit result per wheel for all the vehicles in the vehicles array. - - \param[in] sceneQueryResults must persist without being overwritten until the end of the next PxVehicleUpdates call. - \param[in] nbHitsPerQuery is the maximum numbers of hits that will be returned for each query. \param[in] vehiclesToSweep is an array of bools of length nbVehicles that is used to decide if sweeps will be performed for the corresponding vehicle @@ -374,7 +362,14 @@ namespace physx \param[in] sweepWidthScale scales the geometry of the wheel used in the sweep. Values < 1 result in a thinner swept wheel, while values > 1 result in a fatter swept wheel. - \param[in] sweepRadiusScale scales the geometry of the wheel used in the sweep. Values < 1 result in a larger swept wheel, while values > 1 result in a smaller swept wheel. + \param[in] sweepRadiusScale scales the geometry of the wheel used in the sweep. Values < 1 result in a smaller swept wheel, while values > 1 result in a larger swept wheel. + + \param[in] sweepInflation Inflation parameter for sweeps. This is the inflation parameter from PxScene::sweep(). It inflates the shape and makes it rounder, + which gives smoother and more reliable normals. + + \param[in] queryFlags filter flags for the batched scene queries + + \param[in] context the vehicle context to use for the suspension sweeps. \note If vehiclesToSweep is NULL then sweeps are performed for all vehicles in the vehicles array. @@ -403,16 +398,17 @@ namespace physx @see PxVehicleDrive4W::setToRestState, PxVehicleDriveNW::setToRestState, PxVehicleDriveTank::setToRestState, PxVehicleNoDrive::setToRestState - @see PxBatchQuery::sweep + @see PxBatchQueryExt::sweep PxScene::sweep() @see PxVehicleSetSweepHitRejectionAngles */ - void PxVehicleSuspensionSweeps - (PxBatchQuery* batchQuery, - const PxU32 nbVehicles, PxVehicleWheels** vehicles, - const PxU32 nbSceneQueryResults, PxSweepQueryResult* sceneQueryResults, const PxU16 nbHitsPerQuery, - const bool* vehiclesToSweep = NULL, - const PxF32 sweepWidthScale = 1.0f, const PxF32 sweepRadiusScale = 1.0f); + PX_DEPRECATED void PxVehicleSuspensionSweeps( PxBatchQueryExt* batchQuery, + const PxU32 nbVehicles, PxVehicleWheels** vehicles, + const PxU16 nbHitsPerQuery, + const bool* vehiclesToSweep = NULL, + const PxF32 sweepWidthScale = 1.0f, const PxF32 sweepRadiusScale = 1.0f, const PxF32 sweepInflation = 0.0f, + const PxQueryFlags queryFlags = PxQueryFlag::eSTATIC | PxQueryFlag::eDYNAMIC | PxQueryFlag::ePREFILTER, + const PxVehicleContext& context = PxVehicleGetDefaultContext()); /** \brief A function called from PxContactModifyCallback::onContactModify. The function determines if rigid body contact points @@ -435,7 +431,9 @@ namespace physx \param[in,out] contactModifyPair describes the set of contacts involving the PxShape of the specified wheel and one other shape. The contacts in the contact set are ignored or modified as required. - \note[in] Contact points are accepted or rejected using the threshold angles specified in the function PxVehicleSetSweepHitRejectionAngles. + \param[in] context the vehicle context to use for the contact modification. + + \note Contact points are accepted or rejected using the threshold angles specified in the function PxVehicleSetSweepHitRejectionAngles. \note If a contact point is not rejected it is modified to account for the wheel rotation speed. @@ -444,12 +442,13 @@ namespace physx \note Reduce maxImpulse if the wheels are frequently colliding with light objects with mass much less than the vehicle's mass. Reducing this value encourages numerical stability. - @see PxContactModifyCallback::onContactModify, PxVehicleSetSweepHitRejectionAngles + @see PxContactModifyCallback::onContactModify, PxVehicleSetSweepHitRejectionAngles, PxVehicleContext */ - PxU32 PxVehicleModifyWheelContacts + PX_DEPRECATED PxU32 PxVehicleModifyWheelContacts (const PxVehicleWheels& vehicle, const PxU32 wheelId, const PxF32 wheelTangentVelocityMultiplier, const PxReal maxImpulse, - PxContactModifyPair& contactModifyPair); + PxContactModifyPair& contactModifyPair, + const PxVehicleContext& context = PxVehicleGetDefaultContext()); /** @@ -472,16 +471,18 @@ namespace physx \param[out] vehicleWheelQueryResults is an array of length nbVehicles storing the wheel query results of each corresponding vehicle and wheel in the vehicles array. A NULL pointer is permitted. - \param[out] vehicleConcurrentUpdates is an array of length nbVehicles. It is only necessary to specify vehicleConcurrentUpdates if PxVehicleUpdates is - called concurrently. The element vehicleWheelQueryResults[i] of the array stores data that is computed for vehicle[i] during PxVehicleUpdates but which - cannot be safely written when concurrently called. The data computed and stored in vehicleConcurrentUpdates must be passed to PxVehiclePostUpdates, where - it is applied to all relevant actors in sequence. A NULL pointer is permitted. + \param[out] vehicleConcurrentUpdates is an array of length nbVehicles. It is only necessary to specify vehicleConcurrentUpdates if PxVehicleUpdates is + called concurrently (also concurrently with PxVehicleUpdateSingleVehicleAndStoreTelemetryData). The element vehicleConcurrentUpdates[i] of the array + stores data that is computed for vehicle[i] during PxVehicleUpdates but which cannot be safely written when concurrently called. The data computed and + stored in vehicleConcurrentUpdates must be passed to PxVehiclePostUpdates, where it is applied to all relevant actors in sequence. A NULL pointer is permitted. + + \param[in] context the vehicle context to use for the vehicle update. \note The vehicleWheelQueryResults buffer must persist until the end of PxVehicleUpdates. \note The vehicleWheelQueryResults buffer is left unmodified for vehicles with sleeping rigid bodies whose control inputs indicate they should remain inert. - \note If PxVehicleUpdates is called concurrently then vehicleConcurrentUpdates must be specified. Do not specify vehicleConcurrentUpdates is PxVehicleUpdates + \note If PxVehicleUpdates is called concurrently then vehicleConcurrentUpdates must be specified. Do not specify vehicleConcurrentUpdates if PxVehicleUpdates is not called concurrently. \note The vehicleConcurrentUpdates buffer must persist until the end of PxVehiclePostUpdate. @@ -490,32 +491,38 @@ namespace physx with a PxShape (PxVehicleWheelsSimData::setWheelShapeMapping); the differential of the vehicle must be configured so that no drive torque is delivered to a disabled wheel; and the wheel must have zero rotation speed (PxVehicleWheelsDynData::setWheelRotationSpeed) - \note PxVehicleUpdates may be called concurrently provided all concurrent calls to PxVehicleUpdates involve only vehicles in the scene specified by PxVehicleUpdateSetScene. - PxVehicleUpdates must never run concurrently with PxVehicleUpdateSingleVehicleAndStoreTelemetryData. + \note Concurrent calls to PxVehicleUpdates and PxVehicleUpdateSingleVehicleAndStoreTelemetryData are permitted if the parameter + vehicleConcurrentUpdates is used. @see PxVehicleSetUpdateMode, PxVehicleWheelsSimData::disableWheel, PxVehicleWheelsSimData::setWheelShapeMapping, PxVehicleWheelsDynData::setWheelRotationSpeed, PxVehiclePostUpdates */ - void PxVehicleUpdates( + PX_DEPRECATED void PxVehicleUpdates( const PxReal timestep, const PxVec3& gravity, const PxVehicleDrivableSurfaceToTireFrictionPairs& vehicleDrivableSurfaceToTireFrictionPairs, - const PxU32 nbVehicles, PxVehicleWheels** vehicles, PxVehicleWheelQueryResult* vehicleWheelQueryResults, PxVehicleConcurrentUpdateData* vehicleConcurrentUpdates = NULL); + const PxU32 nbVehicles, PxVehicleWheels** vehicles, PxVehicleWheelQueryResult* vehicleWheelQueryResults, PxVehicleConcurrentUpdateData* vehicleConcurrentUpdates = NULL, + const PxVehicleContext& context = PxVehicleGetDefaultContext()); /** - \brief Apply actor changes that were computed in concurrent calls to PxVehicleUpdates but which could not be safely applied due to the concurrency. + \brief Apply actor changes that were computed in concurrent calls to PxVehicleUpdates or PxVehicleUpdateSingleVehicleAndStoreTelemetryData but + which could not be safely applied due to the concurrency. \param[in] vehicleConcurrentUpdates is an array of length nbVehicles where vehicleConcurrentUpdates[i] contains data describing actor changes that - were computed for vehicles[i] during concurrent calls to PxVehicleUpdates. + were computed for vehicles[i] during concurrent calls to PxVehicleUpdates or PxVehicleUpdateSingleVehicleAndStoreTelemetryData. \param[in] nbVehicles is the number of vehicles pointers in the vehicles array - \param[in,out] vehicles is an array of length nbVehicles containing all vehicles that were partially updated in concurrent calls to PxVehicleUpdates. + \param[in,out] vehicles is an array of length nbVehicles containing all vehicles that were partially updated in concurrent calls to PxVehicleUpdates or + PxVehicleUpdateSingleVehicleAndStoreTelemetryData. - @see PxVehicleUpdates + \param[in] context the vehicle context to use for the vehicle post update. + + @see PxVehicleUpdates, PxVehicleUpdateSingleVehicleAndStoreTelemetryData */ - void PxVehiclePostUpdates( - const PxVehicleConcurrentUpdateData* vehicleConcurrentUpdates, const PxU32 nbVehicles, PxVehicleWheels** vehicles); + PX_DEPRECATED void PxVehiclePostUpdates( + const PxVehicleConcurrentUpdateData* vehicleConcurrentUpdates, const PxU32 nbVehicles, PxVehicleWheels** vehicles, + const PxVehicleContext& context = PxVehicleGetDefaultContext()); /** @@ -534,7 +541,7 @@ namespace physx \param[in,out] vehicles is an array of all vehicles that should be updated to map to the new scene origin. */ - void PxVehicleShiftOrigin(const PxVec3& shift, const PxU32 nbVehicles, PxVehicleWheels** vehicles); + PX_DEPRECATED void PxVehicleShiftOrigin(const PxVec3& shift, const PxU32 nbVehicles, PxVehicleWheels** vehicles); #if PX_DEBUG_VEHICLE_ON /** @@ -558,24 +565,34 @@ namespace physx \param[out] telemetryData is the data structure used to record telemetry data during the update for later query or visualization - \note The vehicleWheelQueryResults buffer must persist until the end of PxVehicleUpdates + \param[out] vehicleConcurrentUpdates is an array of length 1. It is only necessary to specify vehicleConcurrentUpdates if + PxVehicleUpdateSingleVehicleAndStoreTelemetryData is called concurrently (also concurrently with PxVehicleUpdates). The + PxVehicleConcurrentUpdateData struct stores data that cannot be safely written when concurrently called. The data computed and + stored in vehicleConcurrentUpdates must be passed to PxVehiclePostUpdates, where it is applied to the vehicle actor. A NULL + pointer is permitted. + + \param[in] context the vehicle context to use for the vehicle update. + + \note The vehicleWheelQueryResults buffer must persist until the end of PxVehicleUpdateSingleVehicleAndStoreTelemetryData \note The vehicleWheelQueryResults buffer is left unmodified for vehicles with sleeping rigid bodies whose control inputs indicate they should remain inert. - \note PxVehicleUpdateSingleVehicleAndStoreTelemetryData is not thread-safe. As a consequence, it must run sequentially and never concurrently with PxVehicleUpdates + \note Concurrent calls to PxVehicleUpdateSingleVehicleAndStoreTelemetryData and PxVehicleUpdates are permitted if the parameter + vehicleConcurrentUpdates is used. - @see PxVehicleSetUpdateMode, PxVehicleTelemetryData + @see PxVehiclePostUpdates, PxVehicleSetUpdateMode, PxVehicleTelemetryData */ - void PxVehicleUpdateSingleVehicleAndStoreTelemetryData + PX_DEPRECATED void PxVehicleUpdateSingleVehicleAndStoreTelemetryData (const PxReal timestep, const PxVec3& gravity, const PxVehicleDrivableSurfaceToTireFrictionPairs& vehicleDrivableSurfaceToTireFrictionPairs, PxVehicleWheels* focusVehicle, PxVehicleWheelQueryResult* vehicleWheelQueryResults, - PxVehicleTelemetryData& telemetryData); + PxVehicleTelemetryData& telemetryData, + PxVehicleConcurrentUpdateData* vehicleConcurrentUpdates = NULL, + const PxVehicleContext& context = PxVehicleGetDefaultContext()); #endif #if !PX_DOXYGEN } // namespace physx #endif -/** @} */ -#endif //PX_VEHICLE_UPDATE_H +#endif diff --git a/Source/ThirdParty/PhysX/vehicle/PxVehicleUtil.h b/Source/ThirdParty/PhysX/vehicle/PxVehicleUtil.h index b2bfd2d25..3eea356cd 100644 --- a/Source/ThirdParty/PhysX/vehicle/PxVehicleUtil.h +++ b/Source/ThirdParty/PhysX/vehicle/PxVehicleUtil.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,15 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PX_VEHICLE_UTILHELPER_H -#define PX_VEHICLE_UTILHELPER_H -/** \addtogroup vehicle - @{ -*/ +#ifndef PX_VEHICLE_UTIL_H +#define PX_VEHICLE_UTIL_H #include "foundation/Px.h" @@ -54,11 +50,10 @@ that wheels disabled more recently than the last call to PxVehicleUpdates report \return True if the vehicle is in the air, false if any wheel is touching the ground. */ -bool PxVehicleIsInAir(const PxVehicleWheelQueryResult& vehWheelQueryResults); +PX_DEPRECATED bool PxVehicleIsInAir(const PxVehicleWheelQueryResult& vehWheelQueryResults); #if !PX_DOXYGEN } // namespace physx #endif -/** @} */ -#endif //PX_VEHICLE_UTILHELPER_H +#endif diff --git a/Source/ThirdParty/PhysX/vehicle/PxVehicleUtilControl.h b/Source/ThirdParty/PhysX/vehicle/PxVehicleUtilControl.h index 62a86cff5..3a6361ece 100644 --- a/Source/ThirdParty/PhysX/vehicle/PxVehicleUtilControl.h +++ b/Source/ThirdParty/PhysX/vehicle/PxVehicleUtilControl.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,15 +22,13 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PX_VEHICLE_CONTROL_H -#define PX_VEHICLE_CONTROL_H -/** \addtogroup vehicle - @{ -*/ +#ifndef PX_VEHICLE_UTIL_CONTROL_H +#define PX_VEHICLE_UTIL_CONTROL_H + #include "vehicle/PxVehicleSDK.h" #include "vehicle/PxVehicleDrive4W.h" #include "vehicle/PxVehicleDriveNW.h" @@ -47,14 +44,41 @@ namespace physx void testValidAnalogValue(const PxF32 actualValue, const PxF32 minVal, const PxF32 maxVal, const char* errorString); #endif +/** +\brief Used to produce smooth steering values in the presence of discontinuities when a vehicle e.g. lands on the ground. +Use a zero sharpness value to disable the feature (backward compatibility with previous PhysX versions). +*/ +struct PX_DEPRECATED PxVehicleSteerFilter +{ + PxVehicleSteerFilter(float sharpness=0.0f) : mSharpness(sharpness), mFilteredMaxSteer(0.0f) {} + + static PX_FORCE_INLINE float feedbackFilter(float val, float& memory, float sharpness) + { + if(sharpness<0.0f) sharpness = 0.0f; + else if(sharpness>1.0f) sharpness = 1.0f; + return memory = val * sharpness + memory * (1.0f - sharpness); + } + + PX_FORCE_INLINE float computeMaxSteer(const bool isVehicleInAir, const PxFixedSizeLookupTable<8>& steerVsForwardSpeedTable, + const PxF32 vzAbs, const PxF32 timestep) const + { + const PxF32 targetMaxSteer = (isVehicleInAir ? 1.0f : steerVsForwardSpeedTable.getYVal(vzAbs)); + if(mSharpness==0.0f) + return targetMaxSteer; + else + return feedbackFilter(targetMaxSteer, mFilteredMaxSteer, mSharpness*timestep); + } + + PxReal mSharpness; + mutable PxReal mFilteredMaxSteer; +}; + /** \brief Used to produce smooth vehicle driving control values from key inputs. @see PxVehicle4WSmoothDigitalRawInputsAndSetAnalogInputs, PxVehicle4WSmoothAnalogRawInputsAndSetAnalogInputs */ -struct PxVehicleKeySmoothingData +struct PX_DEPRECATED PxVehicleKeySmoothingData { -public: - /** \brief Rise rate of each analog value if digital value is 1 */ @@ -71,10 +95,8 @@ PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleKeySmoothingData)& 0x0f)); \brief Used to produce smooth analog vehicle control values from analog inputs. @see PxVehicleDrive4WSmoothDigitalRawInputsAndSetAnalogInputs, PxVehicleDrive4WSmoothAnalogRawInputsAndSetAnalogInputs */ -struct PxVehiclePadSmoothingData +struct PX_DEPRECATED PxVehiclePadSmoothingData { -public: - /** \brief Rise rate of each analog value from previous value towards target if target>previous */ @@ -91,7 +113,7 @@ PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehiclePadSmoothingData)& 0x0f)); \brief Used to produce smooth vehicle driving control values from analog and digital inputs. @see PxVehicleDrive4WSmoothDigitalRawInputsAndSetAnalogInputs, PxVehicleDrive4WSmoothAnalogRawInputsAndSetAnalogInputs */ -class PxVehicleDrive4WRawInputData +class PX_DEPRECATED PxVehicleDrive4WRawInputData { public: @@ -286,13 +308,14 @@ private: \param[in] timestep is the time that has passed since the last call to PxVehicleDrive4WSmoothDigitalRawInputsAndSetAnalogInputs \param[in] isVehicleInAir describes if the vehicle is in the air or on the ground and is used to decide whether or not to apply steerVsForwardSpeedTable. \param[in] focusVehicle is the vehicle that will be given analog and gearup/geardown control values arising from the digital inputs. + \param[in] steerFilter is an optional smoothing filter for the steering angle. + \param[in] forwardAxis The axis denoting the local space forward direction of the vehicle. */ -void PxVehicleDrive4WSmoothDigitalRawInputsAndSetAnalogInputs +PX_DEPRECATED void PxVehicleDrive4WSmoothDigitalRawInputsAndSetAnalogInputs (const PxVehicleKeySmoothingData& keySmoothing, const PxFixedSizeLookupTable<8>& steerVsForwardSpeedTable, - const PxVehicleDrive4WRawInputData& rawInputData, - const PxReal timestep, - const bool isVehicleInAir, - PxVehicleDrive4W& focusVehicle); + const PxVehicleDrive4WRawInputData& rawInputData, const PxReal timestep, const bool isVehicleInAir, + PxVehicleDrive4W& focusVehicle, const PxVehicleSteerFilter& steerFilter = PxVehicleSteerFilter(), + const PxVec3& forwardAxis = PxVehicleGetDefaultContext().forwardAxis); /** \brief Used to smooth and set analog vehicle control values from analog inputs (gamepad). @@ -300,23 +323,24 @@ Also used to set boolean gearup, geardown values. \param[in] padSmoothing describes how quickly the control values applied to the vehicle blend from the current vehicle values towards the raw analog values from the gamepad. \param[in] steerVsForwardSpeedTable is a table of maximum allowed steer versus forward vehicle speed. \param[in] rawInputData is the state of all gamepad analog inputs that will be used control the vehicle. -\param[in] timestep is the time that has passed since the last call to PxVehicleDrive4WSmoothDigitalRawInputsAndSetAnalogInputs +\param[in] timestep is the time that has passed since the last call to PxVehicleDrive4WSmoothAnalogRawInputsAndSetAnalogInputs \param[in] isVehicleInAir describes if the vehicle is in the air or on the ground and is used to decide whether or not to apply steerVsForwardSpeedTable. \param[in] focusVehicle is the vehicle that will be given analog control values arising from the gamepad inputs. +\param[in] steerFilter is an optional smoothing filter for the steering angle. +\param[in] forwardAxis The axis denoting the local space forward direction of the vehicle. */ -void PxVehicleDrive4WSmoothAnalogRawInputsAndSetAnalogInputs +PX_DEPRECATED void PxVehicleDrive4WSmoothAnalogRawInputsAndSetAnalogInputs (const PxVehiclePadSmoothingData& padSmoothing, const PxFixedSizeLookupTable<8>& steerVsForwardSpeedTable, - const PxVehicleDrive4WRawInputData& rawInputData, - const PxReal timestep, - const bool isVehicleInAir, - PxVehicleDrive4W& focusVehicle); + const PxVehicleDrive4WRawInputData& rawInputData, const PxReal timestep, const bool isVehicleInAir, + PxVehicleDrive4W& focusVehicle, const PxVehicleSteerFilter& steerFilter = PxVehicleSteerFilter(), + const PxVec3& forwardAxis = PxVehicleGetDefaultContext().forwardAxis); /** \brief Used to produce smooth vehicle driving control values from analog and digital inputs. @see PxVehicleDriveNWSmoothDigitalRawInputsAndSetAnalogInputs, PxVehicleDriveNWSmoothAnalogRawInputsAndSetAnalogInputs */ -class PxVehicleDriveNWRawInputData : public PxVehicleDrive4WRawInputData +class PX_DEPRECATED PxVehicleDriveNWRawInputData : public PxVehicleDrive4WRawInputData { public: @@ -330,16 +354,17 @@ public: \param[in] keySmoothing describes the rise and fall rates of the corresponding analog values when keys are pressed on and off. \param[in] steerVsForwardSpeedTable is a table of maximum allowed steer versus forward vehicle speed. \param[in] rawInputData is the state of all digital inputs that control the vehicle. - \param[in] timestep is the time that has passed since the last call to PxVehicleDrive4WSmoothDigitalRawInputsAndSetAnalogInputs + \param[in] timestep is the time that has passed since the last call to PxVehicleDriveNWSmoothDigitalRawInputsAndSetAnalogInputs \param[in] isVehicleInAir describes if the vehicle is in the air or on the ground and is used to decide whether or not to apply steerVsForwardSpeedTable. \param[in] focusVehicle is the vehicle that will be given analog and gearup/geardown control values arising from the digital inputs. + \param[in] steerFilter is an optional smoothing filter for the steering angle. + \param[in] forwardAxis The axis denoting the local space forward direction of the vehicle. */ -void PxVehicleDriveNWSmoothDigitalRawInputsAndSetAnalogInputs +PX_DEPRECATED void PxVehicleDriveNWSmoothDigitalRawInputsAndSetAnalogInputs (const PxVehicleKeySmoothingData& keySmoothing, const PxFixedSizeLookupTable<8>& steerVsForwardSpeedTable, - const PxVehicleDriveNWRawInputData& rawInputData, - const PxReal timestep, - const bool isVehicleInAir, - PxVehicleDriveNW& focusVehicle); + const PxVehicleDriveNWRawInputData& rawInputData, const PxReal timestep, const bool isVehicleInAir, + PxVehicleDriveNW& focusVehicle, const PxVehicleSteerFilter& steerFilter = PxVehicleSteerFilter(), + const PxVec3& forwardAxis = PxVehicleGetDefaultContext().forwardAxis); /** \brief Used to smooth and set analog vehicle control values from analog inputs (gamepad). @@ -347,23 +372,24 @@ Also used to set boolean gearup, geardown values. \param[in] padSmoothing describes how quickly the control values applied to the vehicle blend from the current vehicle values towards the raw analog values from the gamepad. \param[in] steerVsForwardSpeedTable is a table of maximum allowed steer versus forward vehicle speed. \param[in] rawInputData is the state of all gamepad analog inputs that will be used control the vehicle. -\param[in] timestep is the time that has passed since the last call to PxVehicleDrive4WSmoothDigitalRawInputsAndSetAnalogInputs +\param[in] timestep is the time that has passed since the last call to PxVehicleDriveNWSmoothAnalogRawInputsAndSetAnalogInputs \param[in] isVehicleInAir describes if the vehicle is in the air or on the ground and is used to decide whether or not to apply steerVsForwardSpeedTable. \param[in] focusVehicle is the vehicle that will be given analog control values arising from the gamepad inputs. +\param[in] steerFilter is an optional smoothing filter for the steering angle. +\param[in] forwardAxis The axis denoting the local space forward direction of the vehicle. */ -void PxVehicleDriveNWSmoothAnalogRawInputsAndSetAnalogInputs +PX_DEPRECATED void PxVehicleDriveNWSmoothAnalogRawInputsAndSetAnalogInputs (const PxVehiclePadSmoothingData& padSmoothing, const PxFixedSizeLookupTable<8>& steerVsForwardSpeedTable, - const PxVehicleDriveNWRawInputData& rawInputData, - const PxReal timestep, - const bool isVehicleInAir, - PxVehicleDriveNW& focusVehicle); + const PxVehicleDriveNWRawInputData& rawInputData, const PxReal timestep, const bool isVehicleInAir, + PxVehicleDriveNW& focusVehicle, const PxVehicleSteerFilter& steerFilter = PxVehicleSteerFilter(), + const PxVec3& forwardAxis = PxVehicleGetDefaultContext().forwardAxis); /** \brief Used to produce smooth analog tank control values from analog and digital inputs. @see PxVehicleDriveTankSmoothDigitalRawInputsAndSetAnalogInputs, PxVehicleDriveTankSmoothAnalogRawInputsAndSetAnalogInputs */ -class PxVehicleDriveTankRawInputData +class PX_DEPRECATED PxVehicleDriveTankRawInputData { public: @@ -618,10 +644,10 @@ private: Also used to set boolean gearup, geardown values. \param[in] keySmoothing describes the rise and fall rates of the corresponding analog values when keys are pressed on and off. \param[in] rawInputData is the state of all digital inputs that control the vehicle. -\param[in] timestep is the time that has passed since the last call to PxVehicleDrive4WSmoothDigitalRawInputsAndSetAnalogInputs +\param[in] timestep is the time that has passed since the last call to PxVehicleDriveTankSmoothDigitalRawInputsAndSetAnalogInputs \param[in] focusVehicle is the vehicle that will be given analog and gearup/geardown control values arising from the digital inputs. */ -void PxVehicleDriveTankSmoothDigitalRawInputsAndSetAnalogInputs +PX_DEPRECATED void PxVehicleDriveTankSmoothDigitalRawInputsAndSetAnalogInputs (const PxVehicleKeySmoothingData& keySmoothing, const PxVehicleDriveTankRawInputData& rawInputData, const PxReal timestep, @@ -633,10 +659,10 @@ void PxVehicleDriveTankSmoothDigitalRawInputsAndSetAnalogInputs Also used to set boolean gearup, geardown values. \param[in] padSmoothing describes how quickly the control values applied to the vehicle blend from the current vehicle values towards the raw analog values from the gamepad. \param[in] rawInputData is the state of all gamepad analog inputs that will be used control the vehicle. -\param[in] timestep is the time that has passed since the last call to PxVehicleDrive4WSmoothDigitalRawInputsAndSetAnalogInputs +\param[in] timestep is the time that has passed since the last call to PxVehicleDriveTankSmoothAnalogRawInputsAndSetAnalogInputs \param[in] focusVehicle is the vehicle that will be given analog control values arising from the gamepad inputs. */ -void PxVehicleDriveTankSmoothAnalogRawInputsAndSetAnalogInputs +PX_DEPRECATED void PxVehicleDriveTankSmoothAnalogRawInputsAndSetAnalogInputs (const PxVehiclePadSmoothingData& padSmoothing, const PxVehicleDriveTankRawInputData& rawInputData, const PxReal timestep, @@ -647,5 +673,4 @@ void PxVehicleDriveTankSmoothAnalogRawInputsAndSetAnalogInputs } // namespace physx #endif -/** @} */ -#endif //PX_VEHICLE_CONTROL_H +#endif diff --git a/Source/ThirdParty/PhysX/vehicle/PxVehicleUtilSetup.h b/Source/ThirdParty/PhysX/vehicle/PxVehicleUtilSetup.h index d3d53a4b5..cbec49cf5 100644 --- a/Source/ThirdParty/PhysX/vehicle/PxVehicleUtilSetup.h +++ b/Source/ThirdParty/PhysX/vehicle/PxVehicleUtilSetup.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,15 +22,13 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PX_VEHICLE_UTILSSETUP_H -#define PX_VEHICLE_UTILSSETUP_H -/** \addtogroup vehicle - @{ -*/ +#ifndef PX_VEHICLE_UTIL_SETUP_H +#define PX_VEHICLE_UTIL_SETUP_H + #include "foundation/PxSimpleTypes.h" #include "vehicle/PxVehicleSDK.h" @@ -55,8 +52,10 @@ The suspension of the rear-right wheel is modified to support the entire mass of \param[in,out] wheelsSimData is the data describing the wheels/suspensions/tires of the vehicle. \param[in,out] wheelsDynData is the data describing the dynamic state of the wheels of the vehicle. \param[in,out] driveSimData is the data describing the drive model of the vehicle. +\param[in] context the vehicle context to use for the setup. */ -void PxVehicle4WEnable3WTadpoleMode(PxVehicleWheelsSimData& wheelsSimData, PxVehicleWheelsDynData& wheelsDynData, PxVehicleDriveSimData4W& driveSimData); +PX_DEPRECATED void PxVehicle4WEnable3WTadpoleMode(PxVehicleWheelsSimData& wheelsSimData, PxVehicleWheelsDynData& wheelsDynData, PxVehicleDriveSimData4W& driveSimData, + const PxVehicleContext& context = PxVehicleGetDefaultContext()); /** \brief Reconfigure a PxVehicle4W instance as a three-wheeled car with delta config (1 front wheel, 2 rear wheels) @@ -67,8 +66,10 @@ The suspension of the front-right wheel is modified to support the entire mass o \param[in,out] wheelsSimData is the data describing the wheels/suspensions/tires of the vehicle. \param[in,out] wheelsDynData is the data describing the dynamic state of the wheels of the vehicle. \param[in,out] driveSimData is the data describing the drive model of the vehicle. +\param[in] context the vehicle context to use for the setup. */ -void PxVehicle4WEnable3WDeltaMode(PxVehicleWheelsSimData& wheelsSimData, PxVehicleWheelsDynData& wheelsDynData, PxVehicleDriveSimData4W& driveSimData); +PX_DEPRECATED void PxVehicle4WEnable3WDeltaMode(PxVehicleWheelsSimData& wheelsSimData, PxVehicleWheelsDynData& wheelsDynData, PxVehicleDriveSimData4W& driveSimData, + const PxVehicleContext& context = PxVehicleGetDefaultContext()); /** \brief Compute the sprung masses of the suspension springs given (i) the number of sprung masses, @@ -87,7 +88,7 @@ a value of 1 corresponds to (0,-1,0) and a value of 2 corresponds to (0,0,-1). nbSprungMasses or greater. Each element in the sprungMasses array corresponds to the suspension located at the same array element in sprungMassCoordinates. The center of mass of the masses in sprungMasses with the coordinates in sprungMassCoordinates satisfy the specified centerOfMass. */ -void PxVehicleComputeSprungMasses(const PxU32 nbSprungMasses, const PxVec3* sprungMassCoordinates, const PxVec3& centreOfMass, const PxReal totalMass, const PxU32 gravityDirection, PxReal* sprungMasses); +PX_DEPRECATED void PxVehicleComputeSprungMasses(const PxU32 nbSprungMasses, const PxVec3* sprungMassCoordinates, const PxVec3& centreOfMass, const PxReal totalMass, const PxU32 gravityDirection, PxReal* sprungMasses); /** @@ -106,13 +107,13 @@ a value of 1 corresponds to (0,-1,0) and a value of 2 corresponds to (0,0,-1). \note The suspension sprung masses are updated so that the natural frequency and damping ratio of the springs are preserved. This involves altering the stiffness and damping rate of the suspension springs. */ -void PxVehicleUpdateCMassLocalPose(const PxTransform& oldCMassLocalPose, const PxTransform& newCMassLocalPose, const PxU32 gravityDirection, PxVehicleWheels* vehicle); +PX_DEPRECATED void PxVehicleUpdateCMassLocalPose(const PxTransform& oldCMassLocalPose, const PxTransform& newCMassLocalPose, const PxU32 gravityDirection, PxVehicleWheels* vehicle); /** \brief Used by PxVehicleCopyDynamicsData @see PxVehicleCopyDynamicsData */ -class PxVehicleCopyDynamicsMap +class PX_DEPRECATED PxVehicleCopyDynamicsMap { public: @@ -149,12 +150,11 @@ speed of all enabled src wheels. \note src and trg must be the same vehicle type. */ -void PxVehicleCopyDynamicsData(const PxVehicleCopyDynamicsMap& wheelMap, const PxVehicleWheels& src, PxVehicleWheels* trg); +PX_DEPRECATED void PxVehicleCopyDynamicsData(const PxVehicleCopyDynamicsMap& wheelMap, const PxVehicleWheels& src, PxVehicleWheels* trg); #if !PX_DOXYGEN } // namespace physx #endif -/** @} */ -#endif //PX_VEHICLE_UTILSSETUP_H +#endif diff --git a/Source/ThirdParty/PhysX/vehicle/PxVehicleUtilTelemetry.h b/Source/ThirdParty/PhysX/vehicle/PxVehicleUtilTelemetry.h index b32a30f93..936a95af2 100644 --- a/Source/ThirdParty/PhysX/vehicle/PxVehicleUtilTelemetry.h +++ b/Source/ThirdParty/PhysX/vehicle/PxVehicleUtilTelemetry.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,15 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PX_VEHICLE_UTILSTELEMETRY_H -#define PX_VEHICLE_UTILSTELEMETRY_H -/** \addtogroup vehicle - @{ -*/ +#ifndef PX_VEHICLE_UTIL_TELEMETRY_H +#define PX_VEHICLE_UTIL_TELEMETRY_H #include "vehicle/PxVehicleSDK.h" #include "foundation/PxSimpleTypes.h" @@ -44,7 +40,7 @@ namespace physx #if PX_DEBUG_VEHICLE_ON -class PxVehicleGraphDesc +class PX_DEPRECATED PxVehicleGraphDesc { friend class PxVehicleGraph; @@ -90,7 +86,7 @@ private: bool isValid() const; }; -struct PxVehicleGraphChannelDesc +struct PX_DEPRECATED PxVehicleGraphChannelDesc { public: @@ -134,7 +130,7 @@ private: bool isValid() const; }; -struct PxVehicleWheelGraphChannel +struct PX_DEPRECATED PxVehicleWheelGraphChannel { enum Enum { @@ -153,7 +149,7 @@ struct PxVehicleWheelGraphChannel }; }; -struct PxVehicleDriveGraphChannel +struct PX_DEPRECATED PxVehicleDriveGraphChannel { enum Enum { @@ -170,7 +166,7 @@ struct PxVehicleDriveGraphChannel }; }; -struct PxVehicleGraphType +struct PX_DEPRECATED PxVehicleGraphType { enum Enum { @@ -180,7 +176,7 @@ struct PxVehicleGraphType }; -class PxVehicleGraph +class PX_DEPRECATED PxVehicleGraph { public: @@ -246,6 +242,14 @@ public: */ PxF32 getLatestValue(const PxU32 channel) const ; + /** + \brief Get the raw data of a specific graph channel. + + \param[in] channel is the ID of the graph channel to get data from. + \param[out] values is the buffer to write the data to. Minimum required size is eMAX_NB_SAMPLES. + */ + void getRawData(const PxU32 channel, PxReal* values) const; + private: //Min and max of each sample. @@ -300,7 +304,7 @@ private: PX_COMPILE_TIME_ASSERT(PxU32(PxVehicleGraph::eMAX_NB_CHANNELS) >= PxU32(PxVehicleWheelGraphChannel::eMAX_NB_WHEEL_CHANNELS) && PxU32(PxVehicleGraph::eMAX_NB_CHANNELS) >= PxU32(PxVehicleDriveGraphChannel::eMAX_NB_DRIVE_CHANNELS)); PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleGraph) & 15)); -class PxVehicleTelemetryData +class PX_DEPRECATED PxVehicleTelemetryData { public: @@ -406,5 +410,4 @@ PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleTelemetryData) & 15)); } // namespace physx #endif -/** @} */ -#endif //PX_VEHICLE_UTILSTELEMETRY_H +#endif diff --git a/Source/ThirdParty/PhysX/vehicle/PxVehicleWheels.h b/Source/ThirdParty/PhysX/vehicle/PxVehicleWheels.h index 322701c43..4a000d82c 100644 --- a/Source/ThirdParty/PhysX/vehicle/PxVehicleWheels.h +++ b/Source/ThirdParty/PhysX/vehicle/PxVehicleWheels.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,16 +22,12 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. // Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. // Copyright (c) 2001-2004 NovodeX AG. All rights reserved. - #ifndef PX_VEHICLE_WHEELS_H #define PX_VEHICLE_WHEELS_H -/** \addtogroup vehicle - @{ -*/ #include "foundation/PxSimpleTypes.h" #include "vehicle/PxVehicleShaders.h" @@ -57,7 +52,7 @@ class PxMaterial; @see PxVehicleWheelsSimData::setFlags(), PxVehicleWheelsSimData::getFlags() */ -struct PxVehicleWheelsSimFlag +struct PX_DEPRECATED PxVehicleWheelsSimFlag { enum Enum { @@ -72,7 +67,49 @@ struct PxVehicleWheelsSimFlag this feature gives a slightly more realisitic behavior at the potential cost of more easily losing control when steering the vehicle. */ - eLIMIT_SUSPENSION_EXPANSION_VELOCITY = (1 << 0) + eLIMIT_SUSPENSION_EXPANSION_VELOCITY = (1 << 0), + + /** + \brief Disable internal cylinder-plane intersection test. + + By default the internal code runs a post-process on sweep results, approximating the wheel shape with a + cylinder and tweaking the sweep hit results accordingly. This can produce artefacts in certain cases, in + particular when the swept shape is very different from a cylinder - e.g. with swept spheres. This flag + tells the system to disable this internal test, and reuse the direct user-provided sweep results. + + The default code refines the sweep results in each substep. Enabling this flag makes the system partially + reuse the same sweep results over each substep, which could potentially create other artefacts. + */ + eDISABLE_INTERNAL_CYLINDER_PLANE_INTERSECTION_TEST = (1 << 1), + + /** + \brief Disable suspension force projection. + + By default the internal code modulates the suspension force with the contact normal, i.e. the more the contact + normal is aligned with the suspension direction, the bigger the force. This can create issues when using a + single blocking hit, whose unique contact normal sometimes does not accurately capture the reality of the + surrounding geometry. For example it can weaken the suspension force too much, which visually makes the wheel + move up and down against e.g. a kerb. Enabling this flag tells the system to disable the modulation of the + suspension force by the contact normal. + + The rationale is that a real tire has a deformed contact patch containing multiple normals, and even if some + of these normals are bent when colliding against a kerb, there would still be a large area of the contact patch + touching the ground, and getting normals aligned with the suspension. This is difficult to capture with simple + sweep results, especially with a single sweep hit whose normal is computed by a less than accurate algorithm + like GJK. Using this flag shortcuts these issues, which can improves the behavior when driving over kerbs or + small obstacles. + */ + eDISABLE_SUSPENSION_FORCE_PROJECTION = (1 << 2), + + /** + \brief Disable check for sprung mass values summing up to chassis mass. + + Generally, the sum of the suspension sprung mass values should match the chassis mass. However, there can be + scenarios where this is not necessarily desired. Taking a semi-trailer truck as an example, a large part of + the trailer mass will rest on the tractor unit and not the trailer wheels. This flag allows the user to set + the values as desired without error messages being sent. + */ + eDISABLE_SPRUNG_MASS_SUM_CHECK = (1 << 3) }; }; @@ -88,7 +125,7 @@ PX_FLAGS_OPERATORS(PxVehicleWheelsSimFlag::Enum, PxU32) \brief Data structure describing configuration data of a vehicle with up to 20 wheels. */ -class PxVehicleWheelsSimData +class PX_DEPRECATED PxVehicleWheelsSimData { //= ATTENTION! ===================================================================================== // Changing the data layout of this class breaks the binary serialization format. See comments for @@ -584,10 +621,23 @@ public: }; PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleWheelsSimData) & 15)); + +/** +\brief Description of the per wheel intersection method to be used by PxVehicleWheelsDynData::setTireContacts() +*/ +struct PX_DEPRECATED PxTireContactIntersectionMethod +{ + enum Enum + { + eRAY = 0, + eCYLINDER + }; +}; + /** \brief Data structure with instanced dynamics data for wheels */ -class PxVehicleWheelsDynData +class PX_DEPRECATED PxVehicleWheelsDynData { //= ATTENTION! ===================================================================================== // Changing the data layout of this class breaks the binary serialization format. See comments for @@ -674,6 +724,24 @@ public: */ void copy(const PxVehicleWheelsDynData& src, const PxU32 srcWheel, const PxU32 trgWheel); + /** + \brief Directly set tire contact plane and friction for all tires on the vehicle as an alternative to using PxVehicleSuspensionSweeps() or PxVehicleSuspensionRaycasts(). + \param[in] nbHits is an array describing whether each tire has a contact plane or not. Each element of the array is either 0 (no contact) or 1 (contact). + \param[in] contactPlanes is an array of contact planes describing the contact plane per tire. + \param[in] contactFrictions is the friction value of each tire contact with the drivable surface. + \param[in] intersectionMethods describes how each tire will individually interact with its contact plane in order to compute the spring + compression that places the tire on the contact plane. A value of eCYLINDER will compute the spring compression by intersecting the wheel's + cylindrical shape with the contact plane. A value of eRAY will compute the spring compression by casting a ray through the wheel center + and along the suspension direction until it hits the contact plane. + \param[in] nbWheels is the length of the arrays nbContacts, contactPlanes, contactFrictions and intersectionMethods. + \note Each contact plane (n, d) obeys the rule that all points P on the plane satisfy n.dot(P) + d = 0.0. + \note The contact planes specified by setTireContacts() will persist as driving surfaces until either the next call to setTireContacts() or the next call to + \note The friction values are scaled by PxVehicleTireData::mFrictionVsSlipGraph before being applied to the tire. + \note The vehicle model assumes that the tire contacts are with static objects. + PxVehicleSuspensionSweeps() or PxVehicleSuspensionRaycasts(). + */ + void setTireContacts(const PxU32* nbHits, const PxPlane* contactPlanes, const PxReal* contactFrictions, const PxTireContactIntersectionMethod::Enum* intersectionMethods, const PxU32 nbWheels); + private: /** @@ -723,6 +791,31 @@ public: PxU32 getNbWheelRotationAngle() const { return mNbActiveWheels; } PxVehicleWheels4DynData* getWheel4DynData() const { return mWheels4DynData; } //~serialization + + /** + \brief Retrieve the number of PxConstraint objects associated with the vehicle. + + You can use #getConstraints() to retrieve the constraint pointers. + + \return Number of constraints associated with this vehicle. + + @see PxConstraint getConstraints() + */ + PxU32 getNbConstraints() const { return mNbWheels4; } + + /** + \brief Retrieve all the PxConstraint objects associated with the vehicle. + + There is one PxConstraint per block of 4 wheels. The count can be extracted through #getNbConstraints() + + \param[out] userBuffer The buffer to store the constraint pointers. + \param[in] bufferSize Size of provided user buffer. + \param[in] startIndex Index of first constraint pointer to be retrieved + \return Number of constraint pointers written to the buffer. + + @see PxConstraint getNbConstraints() + */ + PxU32 getConstraints(PxConstraint** userBuffer, PxU32 bufferSize, PxU32 startIndex = 0) const; }; PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleWheelsDynData) & 15)); @@ -730,7 +823,7 @@ PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleWheelsDynData) & 15)); \brief Data structure with instanced dynamics data and configuration data of a vehicle with just wheels @see PxVehicleDrive, PxVehicleDrive4W, PxVehicleDriveTank */ -class PxVehicleWheels : public PxBase +class PX_DEPRECATED PxVehicleWheels : public PxBase { //= ATTENTION! ===================================================================================== // Changing the data layout of this class breaks the binary serialization format. See comments for @@ -761,15 +854,21 @@ public: /** \brief Compute the rigid body velocity component along the forward vector of the rigid body transform. + + \param[in] forwardAxis The axis denoting the local space forward direction of the vehicle. + @see PxVehicleSetBasisVectors */ - PxReal computeForwardSpeed() const; + PxReal computeForwardSpeed(const PxVec3& forwardAxis = PxVehicleGetDefaultContext().forwardAxis) const; /** \brief Compute the rigid body velocity component along the right vector of the rigid body transform. + + \param[in] sideAxis The axis denoting the local space side direction of the vehicle. + @see PxVehicleSetBasisVectors */ - PxReal computeSidewaysSpeed() const; + PxReal computeSidewaysSpeed(const PxVec3& sideAxis = PxVehicleGetDefaultContext().sideAxis) const; /** \brief Data describing the setup of all the wheels/suspensions/tires. @@ -844,7 +943,7 @@ protected: #if PX_P64_FAMILY PxU8 mPad0[14]; #else - PxU8 mPad0[14]; + PxU8 mPad0[8]; #endif //serialization @@ -870,5 +969,4 @@ PX_COMPILE_TIME_ASSERT(0==(sizeof(PxVehicleWheels) & 15)); } // namespace physx #endif -/** @} */ -#endif //PX_VEHICLE_WHEELS_H +#endif diff --git a/Source/ThirdParty/PhysX/vehicle2/PxVehicleAPI.h b/Source/ThirdParty/PhysX/vehicle2/PxVehicleAPI.h new file mode 100644 index 000000000..922a5f117 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/PxVehicleAPI.h @@ -0,0 +1,147 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "vehicle2/PxVehicleLimits.h" +#include "vehicle2/PxVehicleComponent.h" +#include "vehicle2/PxVehicleComponentSequence.h" +#include "vehicle2/PxVehicleParams.h" +#include "vehicle2/PxVehicleFunctions.h" +#include "vehicle2/PxVehicleMaths.h" + +#include "vehicle2/braking/PxVehicleBrakingParams.h" +#include "vehicle2/braking/PxVehicleBrakingFunctions.h" + +#include "vehicle2/commands/PxVehicleCommandParams.h" +#include "vehicle2/commands/PxVehicleCommandStates.h" +#include "vehicle2/commands/PxVehicleCommandHelpers.h" + +#include "vehicle2/drivetrain/PxVehicleDrivetrainParams.h" +#include "vehicle2/drivetrain/PxVehicleDrivetrainStates.h" +#include "vehicle2/drivetrain/PxVehicleDrivetrainHelpers.h" +#include "vehicle2/drivetrain/PxVehicleDrivetrainFunctions.h" +#include "vehicle2/drivetrain/PxVehicleDrivetrainComponents.h" + +#include "vehicle2/physxActor/PxVehiclePhysXActorStates.h" +#include "vehicle2/physxActor/PxVehiclePhysXActorHelpers.h" +#include "vehicle2/physxActor/PxVehiclePhysXActorFunctions.h" +#include "vehicle2/physxActor/PxVehiclePhysXActorComponents.h" + +#include "vehicle2/physxConstraints/PxVehiclePhysXConstraintParams.h" +#include "vehicle2/physxConstraints/PxVehiclePhysXConstraintStates.h" +#include "vehicle2/physxConstraints/PxVehiclePhysXConstraintHelpers.h" +#include "vehicle2/physxConstraints/PxVehiclePhysXConstraintFunctions.h" +#include "vehicle2/physxConstraints/PxVehiclePhysXConstraintComponents.h" + +#include "vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryState.h" +#include "vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryParams.h" +#include "vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryHelpers.h" +#include "vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryFunctions.h" +#include "vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryComponents.h" + +#include "vehicle2/pvd/PxVehiclePvdHelpers.h" +#include "vehicle2/pvd/PxVehiclePvdFunctions.h" +#include "vehicle2/pvd/PxVehiclePvdComponents.h" + +#include "vehicle2/rigidBody/PxVehicleRigidBodyParams.h" +#include "vehicle2/rigidBody/PxVehicleRigidBodyStates.h" +#include "vehicle2/rigidBody/PxVehicleRigidBodyFunctions.h" +#include "vehicle2/rigidBody/PxVehicleRigidBodyComponents.h" + +#include "vehicle2/roadGeometry/PxVehicleRoadGeometryState.h" + +#include "vehicle2/steering/PxVehicleSteeringParams.h" +#include "vehicle2/steering/PxVehicleSteeringFunctions.h" + +#include "vehicle2/suspension/PxVehicleSuspensionParams.h" +#include "vehicle2/suspension/PxVehicleSuspensionStates.h" +#include "vehicle2/suspension/PxVehicleSuspensionHelpers.h" +#include "vehicle2/suspension/PxVehicleSuspensionFunctions.h" +#include "vehicle2/suspension/PxVehicleSuspensionComponents.h" + +#include "vehicle2/tire/PxVehicleTireParams.h" +#include "vehicle2/tire/PxVehicleTireStates.h" +#include "vehicle2/tire/PxVehicleTireHelpers.h" +#include "vehicle2/tire/PxVehicleTireFunctions.h" +#include "vehicle2/tire/PxVehicleTireComponents.h" + +#include "vehicle2/wheel/PxVehicleWheelParams.h" +#include "vehicle2/wheel/PxVehicleWheelStates.h" +#include "vehicle2/wheel/PxVehicleWheelHelpers.h" +#include "vehicle2/wheel/PxVehicleWheelFunctions.h" +#include "vehicle2/wheel/PxVehicleWheelComponents.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + + /** \brief Initialize the PhysX Vehicle library. + + This should be called before calling any functions or methods in extensions which may require allocation. + \note This function does not need to be called before creating a PxDefaultAllocator object. + + \param foundation a PxFoundation object + + @see PxCloseVehicleExtension PxFoundation + */ + PX_FORCE_INLINE bool PxInitVehicleExtension(physx::PxFoundation& foundation) + { + PX_UNUSED(foundation); + PX_CHECK_AND_RETURN_VAL(&PxGetFoundation() == &foundation, "Supplied foundation must match the one that will be used to perform allocations", false); + PxIncFoundationRefCount(); + return true; + } + + /** \brief Shut down the PhysX Vehicle library. + + This function should be called to cleanly shut down the PhysX Vehicle library before application exit. + + \note This function is required to be called to release foundation usage. + + @see PxInitVehicleExtension + */ + PX_FORCE_INLINE void PxCloseVehicleExtension() + { + PxDecFoundationRefCount(); + } + + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/PxVehicleComponent.h b/Source/ThirdParty/PhysX/vehicle2/PxVehicleComponent.h new file mode 100644 index 000000000..0e2d5f813 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/PxVehicleComponent.h @@ -0,0 +1,70 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once +/** \addtogroup vehicle2 + @{ +*/ + +#include "foundation/PxSimpleTypes.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif +struct PxVehicleSimulationContext; + +class PxVehicleComponent +{ +public: + + virtual ~PxVehicleComponent() {} + + /** + \brief Update function for a vehicle component. + + \param[in] dt The timestep size to use for the update step. + \param[in] context Vehicle simulation context holding global data or data that usually applies to a + large group of vehicles. + \return True if subsequent components in a sequence should get updated, false if the sequence should + be aborted. + + @see PxVehicleComponentSequence + */ + virtual bool update(const PxReal dt, const PxVehicleSimulationContext& context) = 0; + +}; + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/PxVehicleComponentSequence.h b/Source/ThirdParty/PhysX/vehicle2/PxVehicleComponentSequence.h new file mode 100644 index 000000000..8ddb99a06 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/PxVehicleComponentSequence.h @@ -0,0 +1,326 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once +/** \addtogroup vehicle2 + @{ +*/ +#include "foundation/PxAssert.h" +#include "foundation/PxErrors.h" +#include "foundation/PxFoundation.h" +#include "PxVehicleComponent.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + + +struct PxVehicleComponentSequenceLimits +{ + enum Enum + { + eMAX_NB_SUBGROUPS = 16, + eMAX_NB_COMPONENTS = 64, + eMAX_NB_SUBGROUPELEMENTS = eMAX_NB_SUBGROUPS + eMAX_NB_COMPONENTS + }; +}; + +struct PxVehicleComponentSequence +{ + enum + { + eINVALID_SUBSTEP_GROUP = 0xff + }; + + PxVehicleComponentSequence() + : mNbComponents(0), mNbSubgroups(1), mNbSubGroupElements(0), mActiveSubgroup(0) + { + } + + /** + \brief Add a component to the sequence. + + \param[in] component The component to add to the sequence. + \return True on success, else false (for example due to component count limit being reached). + */ + PX_FORCE_INLINE bool add(PxVehicleComponent* component); + + /** + \brief Start a substepping group. + \note All components added using #add() will be added to the new substepping group until either the group + is marked as complete with a call to #endSubstepGroup() or a subsequent substepping group is started with + a call to #beginSubstepGroup(). + \note Groups can be nested with stacked calls to #beginSubstepGroup(). + \note Each group opened by #beginSubstepGroup() must be closed with a complementary #endSubstepGroup() prior to calling #update(). + \param[in] nbSubSteps is the number of substeps for the group's sequence. This can be changed with a call to #setSubsteps(). + \return Handle for the substepping group on success, else eINVALID_SUBSTEP_GROUP + @see setSubsteps() + @see endSubstepGroup() + */ + PX_FORCE_INLINE PxU8 beginSubstepGroup(const PxU8 nbSubSteps = 1); + + /** + \brief End a substepping group + \note The group most recently opened with #beginSubstepGroup() will be closed by this call. + @see setSubsteps() + @see beginSubstepGroup() + */ + PX_FORCE_INLINE void endSubstepGroup() + { + mActiveSubgroup = mSubGroups[mActiveSubgroup].parentGroup; + } + + /** + \brief Set the number of substeps to perform for a specific substepping group. + \param[in] subGroupHandle specifies the substepping group + \param[in] nbSteps is the number of times to invoke the sequence of components and groups in the specified substepping group. + @see beginSubstepGroup() + @see endSubstepGroup() + */ + void setSubsteps(const PxU8 subGroupHandle, const PxU8 nbSteps) + { + PX_ASSERT(subGroupHandle < mNbSubgroups); + mSubGroups[subGroupHandle].nbSteps = nbSteps; + } + + /** + \brief Update each component in the sequence. + + \note If the update method of a component in the sequence returns false, the update process gets aborted. + + \param[in] dt is the timestep of the update. The provided value has to be positive. + \param[in] context specifies global quantities of the simulation such as gravitational acceleration. + */ + void update(const PxReal dt, const PxVehicleSimulationContext& context) + { + PX_ASSERT(0 == mActiveSubgroup); + + if (dt > 0.0f) + { + updateSubGroup(dt, context, 0, 1); + } + else + { + PxGetFoundation().error(PxErrorCode::eINVALID_PARAMETER, __FILE__, __LINE__, + "PxVehicleComponentSequence::update: The timestep must be positive!"); + } + } + +private: + enum + { + eINVALID_COMPONENT = 0xff, + eINVALID_SUB_GROUP_ELEMENT = 0xff + }; + + //Elements have the form of a linked list to allow traversal over a list of elements. + //Each element is either a single component or a subgroup. + struct SubGroupElement + { + SubGroupElement() + : childGroup(eINVALID_SUBSTEP_GROUP), + component(eINVALID_COMPONENT), + nextElement(eINVALID_SUB_GROUP_ELEMENT) + { + } + + PxU8 childGroup; + PxU8 component; + PxU8 nextElement; + }; + + //A group is a linked list of elements to be processed in sequence. + //Each group stores the first element in the sequence. + //Each element in the sequence stores the next element in the sequence + //to allow traversal over the list of elements in the group. + struct Group + { + Group() + : parentGroup(eINVALID_SUBSTEP_GROUP), + firstElement(eINVALID_SUB_GROUP_ELEMENT), + nbSteps(1) + { + } + PxU8 parentGroup; + PxU8 firstElement; + PxU8 nbSteps; + }; + + PxVehicleComponent* mComponents[PxVehicleComponentSequenceLimits::eMAX_NB_COMPONENTS]; + PxU8 mNbComponents; + + Group mSubGroups[PxVehicleComponentSequenceLimits::eMAX_NB_SUBGROUPS]; + PxU8 mNbSubgroups; + + SubGroupElement mSubGroupElements[PxVehicleComponentSequenceLimits::eMAX_NB_SUBGROUPELEMENTS]; + PxU8 mNbSubGroupElements; + + PxU8 mActiveSubgroup; + + bool updateSubGroup(const PxReal dt, const PxVehicleSimulationContext& context, const PxU8 groupId, const PxU8 parentSepMultiplier) + { + const PxU8 nbSteps = mSubGroups[groupId].nbSteps; + const PxU8 stepMultiplier = parentSepMultiplier * nbSteps; + const PxReal timestepForGroup = dt / PxReal(stepMultiplier); + for (PxU8 k = 0; k < nbSteps; k++) + { + PxU8 nextElement = mSubGroups[groupId].firstElement; + while (eINVALID_SUB_GROUP_ELEMENT != nextElement) + { + const SubGroupElement& e = mSubGroupElements[nextElement]; + PX_ASSERT(e.component != eINVALID_COMPONENT || e.childGroup != eINVALID_SUBSTEP_GROUP); + if (eINVALID_COMPONENT != e.component) + { + PxVehicleComponent* c = mComponents[e.component]; + if (!c->update(timestepForGroup, context)) + return false; + } + else + { + PX_ASSERT(eINVALID_SUBSTEP_GROUP != e.childGroup); + if (!updateSubGroup(dt, context, e.childGroup, stepMultiplier)) + return false; + } + nextElement = e.nextElement; + } + } + + return true; + } + + PxU8 getLastKnownElementInGroup(const PxU8 groupId) const + { + PxU8 currElement = mSubGroups[groupId].firstElement; + PxU8 nextElement = mSubGroups[groupId].firstElement; + while (nextElement != eINVALID_SUB_GROUP_ELEMENT) + { + currElement = nextElement; + nextElement = mSubGroupElements[nextElement].nextElement; + } + return currElement; + } +}; + + +bool PxVehicleComponentSequence::add(PxVehicleComponent* c) +{ + if (PxVehicleComponentSequenceLimits::eMAX_NB_COMPONENTS == mNbComponents) + return false; + if (PxVehicleComponentSequenceLimits::eMAX_NB_SUBGROUPELEMENTS == mNbSubGroupElements) + return false; + + //Create a new element and point it at the component. + SubGroupElement& nextElementInGroup = mSubGroupElements[mNbSubGroupElements]; + nextElementInGroup.childGroup = eINVALID_SUBSTEP_GROUP; + nextElementInGroup.component = mNbComponents; + nextElementInGroup.nextElement = eINVALID_SUB_GROUP_ELEMENT; + + if (eINVALID_SUB_GROUP_ELEMENT == mSubGroups[mActiveSubgroup].firstElement) + { + //The group is empty so add the first element to it. + //Point the group at the new element because this will + //be the first element in the group. + mSubGroups[mActiveSubgroup].firstElement = mNbSubGroupElements; + } + else + { + //We are extending the sequence of element of the group. + //Add the new element to the end of the group's sequence. + mSubGroupElements[getLastKnownElementInGroup(mActiveSubgroup)].nextElement = mNbSubGroupElements; + } + + //Increment the number of elements. + mNbSubGroupElements++; + + //Record the component and increment the number of components. + mComponents[mNbComponents] = c; + mNbComponents++; + + return true; +} + +PxU8 PxVehicleComponentSequence::beginSubstepGroup(const PxU8 nbSubSteps) +{ + if (mNbSubgroups == PxVehicleComponentSequenceLimits::eMAX_NB_SUBGROUPS) + return eINVALID_SUBSTEP_GROUP; + if (mNbSubGroupElements == PxVehicleComponentSequenceLimits::eMAX_NB_SUBGROUPELEMENTS) + return eINVALID_SUBSTEP_GROUP; + + //We have a parent and child group relationship. + const PxU8 parentGroup = mActiveSubgroup; + const PxU8 childGroup = mNbSubgroups; + + //Set up the child group. + mSubGroups[childGroup].parentGroup = parentGroup; + mSubGroups[childGroup].firstElement = eINVALID_SUB_GROUP_ELEMENT; + mSubGroups[childGroup].nbSteps = nbSubSteps; + + //Create a new element to add to the parent group and point it at the child group. + SubGroupElement& nextElementIInGroup = mSubGroupElements[mNbSubGroupElements]; + nextElementIInGroup.childGroup = childGroup; + nextElementIInGroup.nextElement = eINVALID_SUB_GROUP_ELEMENT; + nextElementIInGroup.component = eINVALID_COMPONENT; + + //Add the new element to the parent group. + if (eINVALID_SUB_GROUP_ELEMENT == mSubGroups[parentGroup].firstElement) + { + //The parent group is empty so add the first element to it. + //Point the parent group at the new element because this will + //be the first element in the group. + mSubGroups[parentGroup].firstElement = mNbSubGroupElements; + } + else + { + //We are extending the sequence of elements of the parent group. + //Add the new element to the end of the group's sequence. + mSubGroupElements[getLastKnownElementInGroup(parentGroup)].nextElement = mNbSubGroupElements; + } + + //Push the active group. + //All subsequent operations will now address the child group and we push or pop the group. + mActiveSubgroup = childGroup; + + //Increment the number of elements. + mNbSubGroupElements++; + + //Increment the number of groups. + mNbSubgroups++; + + //Return the group id. + return mActiveSubgroup; +} + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/PxVehicleFunctions.h b/Source/ThirdParty/PhysX/vehicle2/PxVehicleFunctions.h new file mode 100644 index 000000000..9cfafdc57 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/PxVehicleFunctions.h @@ -0,0 +1,199 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once +/** \addtogroup vehicle2 + @{ +*/ + +#include "foundation/PxTransform.h" +#include "foundation/PxMat33.h" +#include "foundation/PxSimpleTypes.h" +#include "PxRigidBody.h" +#include "PxVehicleParams.h" +#include "roadGeometry/PxVehicleRoadGeometryState.h" +#include "rigidBody/PxVehicleRigidBodyStates.h" +#include "physxRoadGeometry/PxVehiclePhysXRoadGeometryState.h" +#include "physxActor/PxVehiclePhysXActorStates.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif +PX_FORCE_INLINE PxVec3 PxVehicleTransformFrameToFrame +(const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVec3& v) +{ + PxVec3 result = v; + if ((srcFrame.lngAxis != trgFrame.lngAxis) || (srcFrame.latAxis != trgFrame.latAxis) || (srcFrame.vrtAxis != trgFrame.vrtAxis)) + { + const PxMat33 a = srcFrame.getFrame(); + const PxMat33 r = trgFrame.getFrame(); + result = (r * a.getTranspose() * v); + } + return result; +} + +PX_FORCE_INLINE PxVec3 PxVehicleTransformFrameToFrame +(const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, + const PxVehicleScale& srcScale, const PxVehicleScale& trgScale, + const PxVec3& v) +{ + PxVec3 result = PxVehicleTransformFrameToFrame(srcFrame, trgFrame, v); + if((srcScale.scale != trgScale.scale)) + result *= (trgScale.scale / srcScale.scale); + return result; +} + +PX_FORCE_INLINE PxTransform PxVehicleTransformFrameToFrame +(const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, + const PxVehicleScale& srcScale, const PxVehicleScale& trgScale, + const PxTransform& v) +{ + PxTransform result(PxVehicleTransformFrameToFrame(srcFrame, trgFrame, srcScale, trgScale, v.p), v.q); + if ((srcFrame.lngAxis != trgFrame.lngAxis) || (srcFrame.latAxis != trgFrame.latAxis) || (srcFrame.vrtAxis != trgFrame.vrtAxis)) + { + PxF32 angle; + PxVec3 axis; + v.q.toRadiansAndUnitAxis(angle, axis); + result.q = PxQuat(angle, PxVehicleTransformFrameToFrame(srcFrame, trgFrame, axis)); + } + return result; +} + +PX_FORCE_INLINE PxVec3 PxVehicleComputeTranslation(const PxVehicleFrame& frame, const PxReal lng, const PxReal lat, const PxReal vrt) +{ + const PxVec3 v = frame.getFrame()*PxVec3(lng, lat, vrt); + return v; +} + +PX_FORCE_INLINE PxQuat PxVehicleComputeRotation(const PxVehicleFrame& frame, const PxReal roll, const PxReal pitch, const PxReal yaw) +{ + const PxMat33 m = frame.getFrame(); + const PxVec3& lngAxis = m.column0; + const PxVec3& latAxis = m.column1; + const PxVec3& vrtAxis = m.column2; + const PxQuat quatPitch(pitch, latAxis); + const PxQuat quatRoll(roll, lngAxis); + const PxQuat quatYaw(yaw, vrtAxis); + const PxQuat result = quatYaw * quatRoll * quatPitch; + return result; +} + +PX_FORCE_INLINE PxF32 PxVehicleComputeSign(const PxReal f) +{ + return physx::intrinsics::fsel(f, physx::intrinsics::fsel(-f, 0.0f, 1.0f), -1.0f); +} + + +/** +\brief Shift the origin of a vehicle by the specified vector. + +Call this method to adjust the internal data structures of vehicles to reflect the shifted origin location +(the shift vector will get subtracted from all world space spatial data). + +\param[in] axleDesc is a description of the wheels on the vehicle. +\param[in] shift is the translation vector used to shift the origin. +\param[in] rigidBodyState stores the current position of the vehicle +\param[in] roadGeometryStates stores the hit plane under each wheel. +\param[in] physxActor stores the PxRigidActor that is the vehicle's PhysX representation. +\param[in] physxQueryStates stores the hit point of the most recent execution of PxVehiclePhysXRoadGeometryQueryUpdate() for each wheel. +\note It is the user's responsibility to keep track of the summed total origin shift and adjust all input/output to/from the vehicle accordingly. +\note This call will not automatically shift the PhysX scene and its objects. PxScene::shiftOrigin() must be called seperately to keep the systems in sync. +\note If there is no associated PxRigidActor then set physxActor to NULL. +\note If there is an associated PxRigidActor and it is already in a PxScene then the complementary call to PxScene::shiftOrigin() will take care of +shifting the associated PxRigidActor. This being the case, set physxActor to NULL. physxActor should be a non-NULL pointer only when there is an +associated PxRigidActor and it is not part of a PxScene. This can occur if the associated PxRigidActor is updated using PhysX immediate mode. +\note If scene queries are independent of PhysX geometry then set queryStates to NULL. +*/ +PX_FORCE_INLINE void PxVehicleShiftOrigin +(const PxVehicleAxleDescription& axleDesc, const PxVec3& shift, + PxVehicleRigidBodyState& rigidBodyState, PxVehicleRoadGeometryState* roadGeometryStates, + PxVehiclePhysXActor* physxActor = NULL, PxVehiclePhysXRoadGeometryQueryState* physxQueryStates = NULL) +{ + //Adjust the vehicle's internal pose. + rigidBodyState.pose.p -= shift; + + //Optionally adjust the PxRigidActor pose. + if (physxActor && !physxActor->rigidBody->getScene()) + { + const PxTransform oldPose = physxActor->rigidBody->getGlobalPose(); + const PxTransform newPose(oldPose.p - shift, oldPose.q); + physxActor->rigidBody->setGlobalPose(newPose); + } + + for (PxU32 i = 0; i < axleDesc.nbWheels; i++) + { + const PxU32 wheelId = axleDesc.wheelIdsInAxleOrder[i]; + + //Optionally adjust the hit position. + if (physxQueryStates && physxQueryStates[wheelId].actor) + physxQueryStates[wheelId].hitPosition -= shift; + + //Adjust the hit plane. + if (roadGeometryStates[wheelId].hitState) + { + const PxPlane plane = roadGeometryStates[wheelId].plane; + PxU32 largestNormalComponentAxis = 0; + PxReal largestNormalComponent = 0.0f; + const PxF32 normalComponents[3] = { plane.n.x, plane.n.y, plane.n.z }; + for (PxU32 k = 0; k < 3; k++) + { + if (PxAbs(normalComponents[k]) > largestNormalComponent) + { + largestNormalComponent = PxAbs(normalComponents[k]); + largestNormalComponentAxis = k; + } + } + PxVec3 pointInPlane(PxZero); + switch (largestNormalComponentAxis) + { + case 0: + pointInPlane.x = -plane.d / plane.n.x; + break; + case 1: + pointInPlane.y = -plane.d / plane.n.y; + break; + case 2: + pointInPlane.z = -plane.d / plane.n.z; + break; + default: + break; + } + roadGeometryStates[wheelId].plane.d = -plane.n.dot(pointInPlane - shift); + } + } +} + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/task/PxTaskDefine.h b/Source/ThirdParty/PhysX/vehicle2/PxVehicleLimits.h similarity index 73% rename from Source/ThirdParty/PhysX/task/PxTaskDefine.h rename to Source/ThirdParty/PhysX/vehicle2/PxVehicleLimits.h index 401d36ebf..e91c53cd0 100644 --- a/Source/ThirdParty/PhysX/task/PxTaskDefine.h +++ b/Source/ThirdParty/PhysX/vehicle2/PxVehicleLimits.h @@ -1,4 +1,3 @@ -// // Redistribution and use in source and binary forms, with or without // modification, are permitted provided that the following conditions // are met: @@ -11,7 +10,7 @@ // contributors may be used to endorse or promote products derived // from this software without specific prior written permission. // -// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR @@ -23,15 +22,36 @@ // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. // -// Copyright (c) 2008-2019 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. -#ifndef PXTASK_PXTASKDEFINE_H -#define PXTASK_PXTASKDEFINE_H +#pragma once +/** \addtogroup vehicle2 + @{ +*/ #include "foundation/PxPreprocessor.h" -#ifndef PX_SUPPORT_PXTASK_PROFILING -#define PX_SUPPORT_PXTASK_PROFILING 1 +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif +struct PxVehicleLimits +{ + enum Enum + { + eMAX_NB_WHEELS = 20, + eMAX_NB_AXLES = eMAX_NB_WHEELS + }; +}; + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx #endif -#endif // PXTASK_PXTASKDEFINE_H +/** @} */ + diff --git a/Source/ThirdParty/PhysX/vehicle2/PxVehicleMaths.h b/Source/ThirdParty/PhysX/vehicle2/PxVehicleMaths.h new file mode 100644 index 000000000..a4d409884 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/PxVehicleMaths.h @@ -0,0 +1,237 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once +/** \addtogroup vehicle2 + @{ +*/ + +#include "foundation/PxSimpleTypes.h" +#include "foundation/PxMemory.h" + +#include "PxVehicleLimits.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +class PxVehicleVectorN +{ +public: + enum + { + eMAX_SIZE = PxVehicleLimits::eMAX_NB_WHEELS + 3 + }; + + PxVehicleVectorN(const PxU32 size) + : mSize(size) + { + PX_ASSERT(mSize <= PxVehicleVectorN::eMAX_SIZE); + PxMemZero(mValues, sizeof(PxReal)*PxVehicleVectorN::eMAX_SIZE); + } + + ~PxVehicleVectorN() + { + } + + PxVehicleVectorN(const PxVehicleVectorN& src) + { + for (PxU32 i = 0; i < src.mSize; i++) + { + mValues[i] = src.mValues[i]; + } + mSize = src.mSize; + } + + PX_FORCE_INLINE PxVehicleVectorN& operator=(const PxVehicleVectorN& src) + { + for (PxU32 i = 0; i < src.mSize; i++) + { + mValues[i] = src.mValues[i]; + } + mSize = src.mSize; + return *this; + } + + PX_FORCE_INLINE PxReal& operator[] (const PxU32 i) + { + PX_ASSERT(i < mSize); + return (mValues[i]); + } + + PX_FORCE_INLINE const PxReal& operator[] (const PxU32 i) const + { + //PX_ASSERT(i < mSize); + return (mValues[i]); + } + + PX_FORCE_INLINE PxU32 getSize() const { return mSize; } + +private: + + PxReal mValues[PxVehicleVectorN::eMAX_SIZE]; + PxU32 mSize; +}; + +class PxVehicleMatrixNN +{ +public: + + PxVehicleMatrixNN() + : mSize(0) + { + } + + PxVehicleMatrixNN(const PxU32 size) + : mSize(size) + { + PX_ASSERT(mSize <= PxVehicleVectorN::eMAX_SIZE); + PxMemZero(mValues, sizeof(PxReal)*PxVehicleVectorN::eMAX_SIZE*PxVehicleVectorN::eMAX_SIZE); + } + + PxVehicleMatrixNN(const PxVehicleMatrixNN& src) + { + for (PxU32 i = 0; i < src.mSize; i++) + { + for (PxU32 j = 0; j < src.mSize; j++) + { + mValues[i][j] = src.mValues[i][j]; + } + } + mSize = src.mSize; + } + + ~PxVehicleMatrixNN() + { + } + + PX_FORCE_INLINE PxVehicleMatrixNN& operator=(const PxVehicleMatrixNN& src) + { + for (PxU32 i = 0; i < src.mSize; i++) + { + for (PxU32 j = 0; j < src.mSize; j++) + { + mValues[i][j] = src.mValues[i][j]; + } + } + mSize = src.mSize; + return *this; + } + + PX_FORCE_INLINE PxReal get(const PxU32 i, const PxU32 j) const + { + PX_ASSERT(i < mSize); + PX_ASSERT(j < mSize); + return mValues[i][j]; + } + + PX_FORCE_INLINE void set(const PxU32 i, const PxU32 j, const PxReal val) + { + PX_ASSERT(i < mSize); + PX_ASSERT(j < mSize); + mValues[i][j] = val; + } + + PX_FORCE_INLINE PxU32 getSize() const { return mSize; } + + PX_FORCE_INLINE void setSize(const PxU32 size) + { + PX_ASSERT(size <= PxVehicleVectorN::eMAX_SIZE); + mSize = size; + } + +public: + + PxReal mValues[PxVehicleVectorN::eMAX_SIZE][PxVehicleVectorN::eMAX_SIZE]; + PxU32 mSize; +}; + + +/* + LUPQ decomposition + + Based upon "Outer Product LU with Complete Pivoting," from Matrix Computations (4th Edition), Golub and Van Loan + + Solve A*x = b using: + + MatrixNNLUSolver solver; + solver.decomposeLU(A); + solver.solve(b, x); +*/ +class PxVehicleMatrixNNLUSolver +{ +private: + + PxVehicleMatrixNN mLU; + PxU32 mP[PxVehicleVectorN::eMAX_SIZE - 1]; // Row permutation + PxU32 mQ[PxVehicleVectorN::eMAX_SIZE - 1]; // Column permutation + PxReal mDetM; + +public: + + PxVehicleMatrixNNLUSolver() {} + ~PxVehicleMatrixNNLUSolver() {} + + PxReal getDet() const { return mDetM; } + + void decomposeLU(const PxVehicleMatrixNN& A); + + //Given a matrix A and a vector b find x that satisfies Ax = b, where the matrix A is the matrix that was passed to #decomposeLU. + //Returns true if the lu decomposition indicates that the matrix has an inverse and x was successfully computed. + //Returns false if the lu decomposition resulted in zero determinant ie the matrix has no inverse and no solution exists for x. + //Returns false if the size of either b or x doesn't match the size of the matrix passed to #decomposeLU. + //If false is returned then each relevant element of x is set to zero. + bool solve(const PxVehicleVectorN& b, PxVehicleVectorN& x) const; +}; + + +class PxVehicleMatrixNGaussSeidelSolver +{ +public: + + void solve(const PxU32 maxIterations, const PxReal tolerance, const PxVehicleMatrixNN& A, const PxVehicleVectorN& b, PxVehicleVectorN& result) const; +}; + +class PxVehicleMatrix33Solver +{ +public: + + bool solve(const PxVehicleMatrixNN& A_, const PxVehicleVectorN& b_, PxVehicleVectorN& result) const; +}; + +#if !PX_DOXYGEN +} //namespace vehicle2 +} //namespace physx +#endif + +/** @} */ + + diff --git a/Source/ThirdParty/PhysX/vehicle2/PxVehicleParams.h b/Source/ThirdParty/PhysX/vehicle2/PxVehicleParams.h new file mode 100644 index 000000000..7eb58e492 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/PxVehicleParams.h @@ -0,0 +1,914 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once +/** \addtogroup vehicle2 + @{ +*/ +#include "foundation/PxFoundation.h" +#include "foundation/PxAssert.h" +#include "foundation/PxMemory.h" +#include "foundation/PxVec3.h" +#include "foundation/PxMat33.h" + +#include "PxVehicleLimits.h" + +class OmniPvdWriter; + +#if !PX_DOXYGEN +namespace physx +{ +class PxConvexMesh; +class PxScene; +namespace vehicle2 +{ +#endif + +struct PxVehicleAxleDescription +{ + PX_FORCE_INLINE void setToDefault() + { + PxMemZero(this, sizeof(PxVehicleAxleDescription)); + } + + /** + \brief Add an axle to the vehicle by specifying the number of wheels on the axle and an array of wheel ids specifying each wheel on the axle. + \param[in] nbWheelsOnAxle is the number of wheels on the axle to be added. + \param[in] wheelIdsOnAxle is an array of wheel ids specifying all the wheels on the axle to be added. + */ + void addAxle(const PxU32 nbWheelsOnAxle, const PxU32* const wheelIdsOnAxle) + { + PX_ASSERT((nbWheels + nbWheelsOnAxle) < PxVehicleLimits::eMAX_NB_WHEELS); + PX_ASSERT(nbAxles < PxVehicleLimits::eMAX_NB_AXLES); + nbWheelsPerAxle[nbAxles] = nbWheelsOnAxle; + axleToWheelIds[nbAxles] = nbWheels; + for (PxU32 i = 0; i < nbWheelsOnAxle; i++) + { + wheelIdsInAxleOrder[nbWheels + i] = wheelIdsOnAxle[i]; + } + nbWheels += nbWheelsOnAxle; + nbAxles++; + } + + /** + \brief Return the number of axles on the vehicle. + \return The number of axles. + @see getNbWheelsOnAxle() + */ + PX_FORCE_INLINE PxU32 getNbAxles() const + { + return nbAxles; + } + + /** + \brief Return the number of wheels on the ith axle. + \param[in] i specifies the axle to be queried for its wheel count. + \return The number of wheels on the specified axle. + @see getWheelOnAxle() + */ + PX_FORCE_INLINE PxU32 getNbWheelsOnAxle(const PxU32 i) const + { + return nbWheelsPerAxle[i]; + } + + /** + \brief Return the wheel id of the jth wheel on the ith axle. + \param[in] j specifies that the wheel id to be returned is the jth wheel in the list of wheels on the specified axle. + \param[in] i specifies the axle to be queried. + \return The wheel id of the jth wheel on the ith axle. + @see getNbWheelsOnAxle() + */ + PX_FORCE_INLINE PxU32 getWheelOnAxle(const PxU32 j, const PxU32 i) const + { + return wheelIdsInAxleOrder[axleToWheelIds[i] + j]; + } + + /** + \brief Return the number of wheels on the vehicle. + \return The number of wheels. + */ + PX_FORCE_INLINE PxU32 getNbWheels() const + { + return nbWheels; + } + + /** + \brief Return the axle of a specified wheel. + \param[in] wheelId is the wheel whose axle is to be queried. + \return The axle of the specified wheel. + */ + PX_FORCE_INLINE PxU32 getAxle(const PxU32 wheelId) const + { + for (PxU32 i = 0; i < getNbAxles(); i++) + { + for (PxU32 j = 0; j < getNbWheelsOnAxle(i); j++) + { + if (getWheelOnAxle(j, i) == wheelId) + return i; + } + } + return 0xffffffff; + } + + PX_FORCE_INLINE bool isValid() const + { + PX_CHECK_AND_RETURN_VAL(nbAxles > 0, "PxVehicleAxleDescription.nbAxles must be greater than zero", false); + PX_CHECK_AND_RETURN_VAL(nbWheels > 0, "PxVehicleAxleDescription.nbWheels must be greater than zero", false); + return true; + } + + PxU32 nbAxles; //!< The number of axles on the vehicle + PxU32 nbWheelsPerAxle[PxVehicleLimits::eMAX_NB_AXLES]; //!< The number of wheels on each axle. + PxU32 axleToWheelIds[PxVehicleLimits::eMAX_NB_AXLES]; //!< The list of wheel ids for the ith axle begins at wheelIdsInAxleOrder[axleToWheelIds[i]] + + PxU32 wheelIdsInAxleOrder[PxVehicleLimits::eMAX_NB_WHEELS]; //!< The list of all wheel ids on the vehicle. + PxU32 nbWheels; //!< The number of wheels on the vehicle. + + + PX_COMPILE_TIME_ASSERT(PxVehicleLimits::eMAX_NB_AXLES == PxVehicleLimits::eMAX_NB_WHEELS); + // It should be possible to support cases where each wheel is controlled individually and thus + // having a wheel per axle for up to the max wheel count. +}; + + +struct PxVehicleAxes +{ + enum Enum + { + ePosX = 0, //!< The +x axis + eNegX, //!< The -x axis + ePosY, //!< The +y axis + eNegY, //!< The -y axis + ePosZ, //!< The +z axis + eNegZ, //!< The -z axis + eMAX_NB_AXES + }; +}; + +struct PxVehicleFrame +{ + PxVehicleAxes::Enum lngAxis; //!< The axis defining the longitudinal (forward) direction of the vehicle. + PxVehicleAxes::Enum latAxis; //!< The axis defining the lateral (side) direction of the vehicle. + PxVehicleAxes::Enum vrtAxis; //!< The axis defining the vertical (up) direction of the vehicle. + + PX_FORCE_INLINE void setToDefault() + { + lngAxis = PxVehicleAxes::ePosX; + latAxis = PxVehicleAxes::ePosY; + vrtAxis = PxVehicleAxes::ePosZ; + } + + PX_FORCE_INLINE PxMat33 getFrame() const + { + const PxVec3 basisDirs[6] = { PxVec3(1,0,0), PxVec3(-1,0,0), PxVec3(0,1,0), PxVec3(0,-1,0), PxVec3(0,0,1), PxVec3(0,0,-1) }; + const PxMat33 mat33(basisDirs[lngAxis], basisDirs[latAxis], basisDirs[vrtAxis]); + return mat33; + } + + PX_FORCE_INLINE PxVec3 getLngAxis() const + { + const PxVec3 basisDirs[6] = { PxVec3(1,0,0), PxVec3(-1,0,0), PxVec3(0,1,0), PxVec3(0,-1,0), PxVec3(0,0,1), PxVec3(0,0,-1) }; + return basisDirs[lngAxis]; + } + + PX_FORCE_INLINE PxVec3 getLatAxis() const + { + const PxVec3 basisDirs[6] = { PxVec3(1,0,0), PxVec3(-1,0,0), PxVec3(0,1,0), PxVec3(0,-1,0), PxVec3(0,0,1), PxVec3(0,0,-1) }; + return basisDirs[latAxis]; + } + + PX_FORCE_INLINE PxVec3 getVrtAxis() const + { + const PxVec3 basisDirs[6] = { PxVec3(1,0,0), PxVec3(-1,0,0), PxVec3(0,1,0), PxVec3(0,-1,0), PxVec3(0,0,1), PxVec3(0,0,-1) }; + return basisDirs[vrtAxis]; + } + + PX_FORCE_INLINE bool isValid() const + { + PX_CHECK_AND_RETURN_VAL(lngAxis < PxVehicleAxes::eMAX_NB_AXES, "PxVehicleFrame.lngAxis is invalid", false); + PX_CHECK_AND_RETURN_VAL(latAxis < PxVehicleAxes::eMAX_NB_AXES, "PxVehicleFrame.latAxis is invalid", false); + PX_CHECK_AND_RETURN_VAL(vrtAxis < PxVehicleAxes::eMAX_NB_AXES, "PxVehicleFrame.vrtAxis is invalid", false); + const PxMat33 frame = getFrame(); + const PxQuat quat(frame); + PX_CHECK_AND_RETURN_VAL(quat.isFinite() && quat.isUnit() && quat.isSane(), "PxVehicleFrame is not a legal frame", false); + return true; + } +}; + +struct PxVehicleScale +{ + PxReal scale; //!< The length scale used for the vehicle. For example, if 1.0 is considered meters, then 100.0 would be for centimeters. + + PX_FORCE_INLINE void setToDefault() + { + scale = 1.0f; + } + + PX_FORCE_INLINE bool isValid() const + { + PX_CHECK_AND_RETURN_VAL(scale > 0.0f, "PxVehicleScale.scale must be greater than zero", false); + return true; + } +}; + +/** +\brief Helper struct to pass array type data to vehice components and functions. + +The Vehicle SDK tries to give the user a certain freedom in how the parameters and +states are stored. This helper struct presents a way to either use array of structs +or array of pointers to structs to pass data into the provided vehicle components +and functions. +*/ +template +struct PxVehicleArrayData +{ + enum DataFormat + { + eARRAY_OF_STRUCTS = 0, //!< The data is provided as an array of structs and stored in #arrayOfStructs. + eARRAY_OF_POINTERS //!< The data is provided as an array of pointers and stored in #arrayOfPointers. + }; + + /** + \brief Set the data as an array of structs. + + \param[in] data The data as an array of structs. + */ + PX_FORCE_INLINE void setData(T* data) + { + arrayOfStructs = data; + dataFormat = eARRAY_OF_STRUCTS; + } + + /** + \brief Set the data as an array of pointers. + + \param[in] data The data as an array of pointers. + */ + PX_FORCE_INLINE void setData(T*const* data) + { + arrayOfPointers= data; + dataFormat = eARRAY_OF_POINTERS; + } + + PX_FORCE_INLINE PxVehicleArrayData() + { + } + + PX_FORCE_INLINE explicit PxVehicleArrayData(T* data) + { + setData(data); + } + + PX_FORCE_INLINE explicit PxVehicleArrayData(T*const* data) + { + setData(data); + } + + /** + \brief Get the data entry at a given index. + + \param[in] index The index to retrieve the data entry for. + \return Reference to the requested data entry. + */ + PX_FORCE_INLINE T& getData(PxU32 index) + { + if (dataFormat == eARRAY_OF_STRUCTS) + return arrayOfStructs[index]; + else + return *arrayOfPointers[index]; + } + + PX_FORCE_INLINE T& operator[](PxU32 index) + { + return getData(index); + } + + /** + \brief Get the data entry at a given index. + + \param[in] index The index to retrieve the data entry for. + \return Reference to the requested data entry. + */ + PX_FORCE_INLINE const T& getData(PxU32 index) const + { + if (dataFormat == eARRAY_OF_STRUCTS) + return arrayOfStructs[index]; + else + return *arrayOfPointers[index]; + } + + PX_FORCE_INLINE const T& operator[](PxU32 index) const + { + return getData(index); + } + + /** + \brief Set as empty. + */ + PX_FORCE_INLINE void setEmpty() + { + arrayOfStructs = NULL; + } + + /** + \brief Check if declared as empty. + + \return True if empty, else false. + */ + PX_FORCE_INLINE bool isEmpty() const + { + return (arrayOfStructs == NULL); + } + + /** + \brief Get a reference to the array but read only. + + \return Read only version of the data. + */ + PX_FORCE_INLINE const PxVehicleArrayData& getConst() const + { + return reinterpret_cast&>(*this); + } + + + union + { + T* arrayOfStructs; //!< The data stored as an array of structs. + T*const* arrayOfPointers; //!< The data stored as an array of pointers. + }; + PxU8 dataFormat; +}; + +template +struct PxVehicleSizedArrayData : public PxVehicleArrayData +{ + /** + \brief Set the data as an array of structs and set the number of data entries. + + \param[in] data The data as an array of structs. + \param[in] count The number of entries in the data array. + */ + PX_FORCE_INLINE void setDataAndCount(T* data, const PxU32 count) + { + PxVehicleArrayData::setData(data); + size = count; + } + + /** + \brief Set the data as an array of pointers and set the number of data entries. + + \param[in] data The data as an array of pointers. + \param[in] count The number of entries in the data array. + */ + PX_FORCE_INLINE void setDataAndCount(T*const* data, const PxU32 count) + { + PxVehicleArrayData::setData(data); + size = count; + } + + /** + \brief Set as empty. + */ + PX_FORCE_INLINE void setEmpty() + { + PxVehicleArrayData::setEmpty(); + size = 0; + } + + /** + \brief Check if declared as empty. + + \return True if empty, else false. + */ + PX_FORCE_INLINE bool isEmpty() const + { + return ((size == 0) || PxVehicleArrayData::isEmpty()); + } + + PxU32 size; +}; + +/** +\brief Determine whether the PhysX actor associated with a vehicle is to be updated with a velocity change or an acceleration change. +A velocity change will be immediately reflected in linear and angular velocity queries against the vehicle. An acceleration change, on the other hand, +will leave the linear and angular velocities unchanged until the next PhysX scene update has applied the acceleration update to the actor's linear and +angular velocities. +@see PxVehiclePhysXActorEndComponent +@see PxVehicleWriteRigidBodyStateToPhysXActor +*/ +struct PxVehiclePhysXActorUpdateMode +{ + enum Enum + { + eAPPLY_VELOCITY = 0, + eAPPLY_ACCELERATION + }; +}; + +/** +\brief Tire slip values are computed using ratios with potential for divide-by-zero errors. PxVehicleTireSlipParams +introduces a minimum value for the denominator of each of these ratios. +*/ +struct PxVehicleTireSlipParams +{ + /** + \brief The lateral slip angle is typically computed as a function of the ratio of lateral and longitudinal speeds + of the rigid body in the tire's frame. This leads to a divide-by-zero in the event that the longitudinal speed + approaches zero. The parameter minLatSlipDenominator sets a minimum denominator for the ratio of speeds used to + compute the lateral slip angle. + \note Larger timesteps typically require larger values of minLatSlipDenominator. + + Range: (0, inf)
+ Unit: velocity = length / time + */ + PxReal minLatSlipDenominator; + + /** + \brief The longitudinal slip represents the difference between the longitudinal speed of the rigid body in the tire's + frame and the linear speed arising from the rotation of the wheel. This is typically normalized using the reciprocal + of the longitudinal speed of the rigid body in the tire's frame. This leads to a divide-by-zero in the event that the + longitudinal speed approaches zero. The parameter minPassiveLongSlipDenominator sets a minimum denominator for the normalized + longitudinal slip when the wheel experiences zero drive torque and zero brake torque and zero handbrake torque. The aim is + to bring the vehicle to rest without experiencing wheel rotational speeds that oscillate around zero. + \note The vehicle will come to rest more smoothly with larger values of minPassiveLongSlipDenominator, particularly + with large timesteps that often lead to oscillation in wheel rotation speeds when the wheel rotation speed approaches + zero. + \note It is recommended that minActiveLongSlipDenominator < minPassiveLongSlipDenominator. + + Range: (0, inf)
+ Unit: velocity = length / time + */ + PxReal minPassiveLongSlipDenominator; + + /** + \brief The longitudinal slip represents the difference between the longitudinal speed of the rigid body in the tire's + frame and the linear speed arising from the rotation of the wheel. This is typically normalized using the reciprocal + of the longitudinal speed of the rigid body in the tire's frame. This leads to a divide-by-zero in the event that the + longitudinal speed approaches zero. The parameter minActiveLongSlipDenominator sets a minimum denominator for the normalized + longitudinal slip when the wheel experiences either a non-zero drive torque or a non-zero brake torque or a non-zero handbrake + torque. + \note Larger timesteps typically require larger values of minActiveLongSlipDenominator to avoid instabilities occurring when + the vehicle is aggressively throttled from rest. + \note It is recommended that minActiveLongSlipDenominator < minPassiveLongSlipDenominator. + + Range: (0, inf)
+ Unit: velocity = length / time + */ + PxReal minActiveLongSlipDenominator; + + PX_FORCE_INLINE void setToDefault() + { + minLatSlipDenominator = 1.0f; + minActiveLongSlipDenominator = 0.1f; + minPassiveLongSlipDenominator = 4.0f; + } + + PX_FORCE_INLINE PxVehicleTireSlipParams transformAndScale( + const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const + { + PX_UNUSED(srcFrame); + PX_UNUSED(trgFrame); + PxVehicleTireSlipParams p = *this; + const PxReal scaleRatio = trgScale.scale / srcScale.scale; + p.minLatSlipDenominator *= scaleRatio; + p.minPassiveLongSlipDenominator *= scaleRatio; + p.minActiveLongSlipDenominator *= scaleRatio; + return p; + } + + PX_FORCE_INLINE bool isValid() const + { + PX_CHECK_AND_RETURN_VAL(minLatSlipDenominator > 0.0f, "PxVehicleTireSlipParams.minLatSlipDenominator must be greater than zero", false); + PX_CHECK_AND_RETURN_VAL(minPassiveLongSlipDenominator > 0.0f, "PxVehicleTireSlipParams.minPassiveLongSlipDenominator must be greater than zero", false); + PX_CHECK_AND_RETURN_VAL(minActiveLongSlipDenominator > 0.0f, "PxVehicleTireSlipParams.minActiveLongSlipDenominator must be greater than zero", false); + return true; + } +}; + +/** +\brief Tires have two important directions for the purposes of tire force computation: longitudinal and lateral. +*/ +struct PxVehicleTireDirectionModes +{ + enum Enum + { + eLONGITUDINAL = 0, + eLATERAL, + eMAX_NB_PLANAR_DIRECTIONS + }; +}; + +/** +\brief The low speed regime often presents numerical difficulties for the tire model due to the potential for divide-by-zero errors. +This particularly affects scenarios where the vehicle is slowing down due to damping and drag. In scenarios where there is no +significant brake or drive torque, numerical error begins to dominate and it can be difficult to bring the vehicle to rest. A solution +to this problem is to recognise that the vehicle is close to rest and to replace the tire forces with velocity constraints that will +bring the vehicle to rest. This regime is known as the "sticky tire" regime. PxVehicleTireAxisStickyParams describes velocity and time +thresholds that categorise the "sticky tire" regime. It also describes the rate at which the velocity constraints approach zero speed. +*/ +struct PxVehicleTireAxisStickyParams +{ + /** + \brief A tire enters the "sticky tire" regime when it has been below a speed specified by #thresholdSpeed for a continuous time + specified by #thresholdTime. + + Range: [0, inf)
+ Unit: velocity = length / time + */ + PxReal thresholdSpeed; + + /** + \brief A tire enters the "sticky tire" regime when it has been below a speed specified by #thresholdSpeed for a continuous time + specified by #thresholdTime. + + Range: [0, inf)
+ Unit: time + */ + PxReal thresholdTime; + + /** + \brief The rate at which the velocity constraint approaches zero is controlled by the damping parameter. + \note Larger values of damping lead to faster approaches to zero. Since the damping behaves like a + stiffness with respect to the velocity, too large a value can lead to instabilities. + + Range: [0, inf)
+ Unit: 1 / time (acceleration instead of force based damping, thus not mass/time) + */ + PxReal damping; + + + PX_FORCE_INLINE PxVehicleTireAxisStickyParams transformAndScale( + const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const + { + PX_UNUSED(srcFrame); + PX_UNUSED(trgFrame); + PxVehicleTireAxisStickyParams p = *this; + const PxReal scaleRatio = trgScale.scale / srcScale.scale; + p.thresholdSpeed *= scaleRatio; + return p; + } + + PX_FORCE_INLINE bool isValid() const + { + PX_CHECK_AND_RETURN_VAL(thresholdSpeed >= 0.0f, "PxVehicleTireAxisStickyParams.thresholdSpeed must be greater than or equal to zero", false); + PX_CHECK_AND_RETURN_VAL(thresholdTime >= 0.0f, "PxVehicleTireAxisStickyParams.thresholdTime must be greater than or equal to zero", false); + PX_CHECK_AND_RETURN_VAL(damping >= 0.0f, "PxVehicleTireAxisStickyParams.damping must be greater than or equal to zero", false); + return true; + } +}; + +/** +\brief For each tire, the forces of the tire model may be replaced by velocity constraints when the tire enters the "sticky tire" +regime. The "sticky tire" regime of the lateral and longitudinal directions of the tire are managed separately. +*/ +struct PxVehicleTireStickyParams +{ + /** + The "sticky tire" regime of the lateral and longitudinal directions of the tire are managed separately and are individually + parameterized. + */ + PxVehicleTireAxisStickyParams stickyParams[PxVehicleTireDirectionModes::eMAX_NB_PLANAR_DIRECTIONS]; + + PX_FORCE_INLINE void setToDefault() + { + stickyParams[PxVehicleTireDirectionModes::eLONGITUDINAL].thresholdSpeed = 0.2f; + stickyParams[PxVehicleTireDirectionModes::eLONGITUDINAL].thresholdTime = 1.0f; + stickyParams[PxVehicleTireDirectionModes::eLONGITUDINAL].damping = 1.0f; + stickyParams[PxVehicleTireDirectionModes::eLATERAL].thresholdSpeed = 0.2f; + stickyParams[PxVehicleTireDirectionModes::eLATERAL].thresholdTime = 1.0f; + stickyParams[PxVehicleTireDirectionModes::eLATERAL].damping = 0.1f; + } + + PX_FORCE_INLINE PxVehicleTireStickyParams transformAndScale( + const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const + { + PxVehicleTireStickyParams p = *this; + p.stickyParams[PxVehicleTireDirectionModes::eLONGITUDINAL] = + stickyParams[PxVehicleTireDirectionModes::eLONGITUDINAL].transformAndScale(srcFrame, trgFrame, srcScale, trgScale); + p.stickyParams[PxVehicleTireDirectionModes::eLATERAL] = + stickyParams[PxVehicleTireDirectionModes::eLATERAL].transformAndScale(srcFrame, trgFrame, srcScale, trgScale); + return p; + } + + PX_FORCE_INLINE bool isValid() const + { + if (!stickyParams[PxVehicleTireDirectionModes::eLONGITUDINAL].isValid()) + return false; + if (!stickyParams[PxVehicleTireDirectionModes::eLATERAL].isValid()) + return false; + return true; + } +}; + +struct PxVehicleSimulationContextType +{ + enum Enum + { + eDEFAULT, //!< The simulation context inherits from PxVehicleSimulationContext + ePHYSX //!< The simulation context inherits from PxVehiclePhysXSimulationContext + }; +}; + +/** +\brief Structure to support Omni PVD, the PhysX Visual Debugger. +*/ +struct PxVehiclePvdContext +{ +public: + PX_FORCE_INLINE void setToDefault() + { + attributeHandles = NULL; + writer = NULL; + } + + + /** + \brief The attribute handles used to reflect vehicle parameter and state data in omnipvd. + \note A null value will result in no values being reflected in omnipvd. + \note #attributeHandles and #writer both need to be non-NULL to reflect vehicle values in omnipvd. + @see PxVehiclePvdAttributesCreate + @see PxVehiclePvdAttributesRelease + @see PxVehiclePVDComponent + */ + const struct PxVehiclePvdAttributeHandles* attributeHandles; + + /** + \brief An instance of OmniPvdWriter used to write vehicle prameter and state data to omnipvd. + \note A null value will result in no values being reflected in omnipvd. + \note #attributeHandles and #writer both need to be non-NULL to reflect vehicle values in omnipvd. + @see PxVehiclePvdAttributesCreate + @see PxVehiclePvdAttributesRelease + @see PxVehiclePVDComponent + */ + OmniPvdWriter* writer; +}; + +struct PxVehicleSimulationContext +{ + PxVehicleSimulationContext() + : type(PxVehicleSimulationContextType::eDEFAULT) + {} + + PxVec3 gravity; + + PxVehicleFrame frame; + PxVehicleScale scale; + + //Tire + PxVehicleTireSlipParams tireSlipParams; + PxVehicleTireStickyParams tireStickyParams; + + /** + \brief Forward wheel speed below which the wheel rotation speed gets blended with the rolling speed. + + The blended rotation speed is used to integrate the wheel rotation angle. At low forward wheel speed, + the wheel rotation speed can get unstable (depending on the tire model used) and, for example, oscillate. + + \note If brake or throttle is applied, there will be no blending. + + Unit: velocity = length / time + */ + PxReal thresholdForwardSpeedForWheelAngleIntegration; + + /** + \brief Structure to support Omni PVD, the PhysX Visual Debugger. + */ + PxVehiclePvdContext pvdContext; + +protected: + PxVehicleSimulationContextType::Enum type; + + +public: + PX_FORCE_INLINE PxVehicleSimulationContextType::Enum getType() const { return type; } + + PX_FORCE_INLINE void setToDefault() + { + frame.setToDefault(); + scale.setToDefault(); + + gravity = frame.getVrtAxis() * (-9.81f * scale.scale); + + tireSlipParams.setToDefault(); + tireStickyParams.setToDefault(); + + thresholdForwardSpeedForWheelAngleIntegration = 5.0f * scale.scale; + + pvdContext.setToDefault(); + } + + PX_FORCE_INLINE PxVehicleSimulationContext transformAndScale( + const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const + { + PxVehicleSimulationContext c = *this; + const PxReal scaleRatio = trgScale.scale / srcScale.scale; + c.gravity = trgFrame.getFrame()*srcFrame.getFrame().getTranspose()*c.gravity; + c.gravity *= scaleRatio; + c.tireSlipParams = tireSlipParams.transformAndScale(srcFrame, trgFrame, srcScale, trgScale); + c.tireStickyParams = tireStickyParams.transformAndScale(srcFrame, trgFrame, srcScale, trgScale); + c.thresholdForwardSpeedForWheelAngleIntegration *= scaleRatio; + c.frame = trgFrame; + c.scale = trgScale; + return c; + } +}; + +struct PxVehiclePhysXSimulationContext : public PxVehicleSimulationContext +{ + PxVehiclePhysXSimulationContext() + : PxVehicleSimulationContext() + { + type = PxVehicleSimulationContextType::ePHYSX; + } + + //Road geometry queries to find the plane under the wheel. + const PxConvexMesh* physxUnitCylinderSweepMesh; + const PxScene* physxScene; + + //PhysX actor update + PxVehiclePhysXActorUpdateMode::Enum physxActorUpdateMode; + + /** + \brief Wake counter value to set on the physx actor if a reset is required. + + Certain vehicle states should keep a physx actor of a vehicle awake. This + will be achieved by resetting the wake counter value if needed. The wake + counter value is the minimum simulation time that a physx actor will stay + awake. + + Unit: time + + @see physxActorWakeCounterThreshold PxVehiclePhysxActorKeepAwakeCheck + */ + PxReal physxActorWakeCounterResetValue; + + /** + \brief Threshold below which to check whether the physx actor wake counter + should get reset. + + Unit: time + + @see physxActorWakeCounterResetValue PxVehiclePhysxActorKeepAwakeCheck + */ + PxReal physxActorWakeCounterThreshold; + + + PX_FORCE_INLINE void setToDefault() + { + PxVehicleSimulationContext::setToDefault(); + + physxUnitCylinderSweepMesh = NULL; + physxScene = NULL; + + physxActorUpdateMode = PxVehiclePhysXActorUpdateMode::eAPPLY_VELOCITY; + + physxActorWakeCounterResetValue = 20.0f * 0.02f; // 20 timesteps of size 0.02 + physxActorWakeCounterThreshold = 0.5f * physxActorWakeCounterResetValue; + } + + PX_FORCE_INLINE PxVehiclePhysXSimulationContext transformAndScale( + const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const + { + PxVehiclePhysXSimulationContext r = *this; + static_cast(r) = PxVehicleSimulationContext::transformAndScale(srcFrame, trgFrame, srcScale, trgScale); + return r; + } +}; + +/** +* \brief Express a function as a sequence of points {(x, y)} that form a piecewise polynomial. +*/ +template +class PxVehicleFixedSizeLookupTable +{ +public: + + PxVehicleFixedSizeLookupTable() + : nbDataPairs(0) + { + } + + PxVehicleFixedSizeLookupTable(const PxVehicleFixedSizeLookupTable& src) + { + PxMemCopy(xVals, src.xVals, sizeof(PxReal)* src.nbDataPairs); + PxMemCopy(yVals, src.yVals, sizeof(T)*src.nbDataPairs); + nbDataPairs = src.nbDataPairs; + } + + ~PxVehicleFixedSizeLookupTable() + { + } + + PxVehicleFixedSizeLookupTable& operator=(const PxVehicleFixedSizeLookupTable& src) + { + PxMemCopy(xVals, src.xVals, sizeof(PxReal)*src.nbDataPairs); + PxMemCopy(yVals, src.yVals, sizeof(T)*src.nbDataPairs); + nbDataPairs = src.nbDataPairs; + return *this; + } + + /** + \brief Add one more point to create one more polynomial segment of a piecewise polynomial. + */ + PX_FORCE_INLINE bool addPair(const PxReal x, const T y) + { + PX_CHECK_AND_RETURN_VAL(nbDataPairs < NB_ELEMENTS, "PxVehicleFixedSizeLookupTable::addPair() exceeded fixed size capacity", false); + xVals[nbDataPairs] = x; + yVals[nbDataPairs] = y; + nbDataPairs++; + return true; + } + + /** + \brief Identify the segment of the piecewise polynomial that includes x and compute the corresponding y value by linearly interpolating the gradient of the segment. + \param[in] x is the value on the x-axis of the piecewise polynomial. + \return Returns the y value that corresponds to the input x. + */ + PX_FORCE_INLINE T interpolate(const PxReal x) const + { + if (0 == nbDataPairs) + { + return T(0); + } + + if (1 == nbDataPairs || x < xVals[0]) + { + return yVals[0]; + } + + PxReal x0 = xVals[0]; + T y0 = yVals[0]; + + for (PxU32 i = 1; i < nbDataPairs; i++) + { + const PxReal x1 = xVals[i]; + const T y1 = yVals[i]; + + if ((x >= x0) && (x < x1)) + { + return (y0 + (y1 - y0) * (x - x0) / (x1 - x0)); + } + + x0 = x1; + y0 = y1; + } + + PX_ASSERT(x >= xVals[nbDataPairs - 1]); + return yVals[nbDataPairs - 1]; + } + + void clear() + { + PxMemSet(xVals, 0, NB_ELEMENTS * sizeof(PxReal)); + PxMemSet(yVals, 0, NB_ELEMENTS * sizeof(T)); + nbDataPairs = 0; + } + + PxReal xVals[NB_ELEMENTS]; + T yVals[NB_ELEMENTS]; + PxU32 nbDataPairs; + + PX_FORCE_INLINE bool isValid() const + { + for (PxU32 i = 1; i < nbDataPairs; i++) + { + PX_CHECK_AND_RETURN_VAL(xVals[i] > xVals[i - 1], "PxVehicleFixedSizeLookupTable:: xVals[i+1] must be greater than xVals[i]", false); + } + return true; + } +}; + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + + + + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/braking/PxVehicleBrakingFunctions.h b/Source/ThirdParty/PhysX/vehicle2/braking/PxVehicleBrakingFunctions.h new file mode 100644 index 000000000..f72fed12e --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/braking/PxVehicleBrakingFunctions.h @@ -0,0 +1,79 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "foundation/PxPreprocessor.h" +#include "foundation/PxMath.h" +#include "PxVehicleBrakingParams.h" +#include "../commands/PxVehicleCommandStates.h" +#include "../commands/PxVehicleCommandHelpers.h" +#include "../drivetrain/PxVehicleDrivetrainParams.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +/** +\brief Compute the brake torque response to an array of brake commands. +\param[in] brakeCommands is the array of input brake commands to be applied to the vehicle. +\param[in] nbBrakeCommands is the number of input brake commands to be applied to the vehicle. +\param[in] longitudinalSpeed is the longitudinal speed of the vehicle. +\param[in] wheelId specifies the wheel that is to have its brake response computed. +\param[in] brakeResponseParams specifies the per wheel brake torque response to each brake command as a nonlinear function of brake command and longitudinal speed. +\param[out] brakeResponseState is the brake torque response to the input brake command. +\note commands.brakes[i] and brakeResponseParams[i] are treated as pairs of brake command and brake command response. +*/ +PX_FORCE_INLINE void PxVehicleBrakeCommandResponseUpdate +(const PxReal* brakeCommands, const PxU32 nbBrakeCommands, const PxReal longitudinalSpeed, + const PxU32 wheelId, const PxVehicleSizedArrayData& brakeResponseParams, + PxReal& brakeResponseState) +{ + PX_CHECK_AND_RETURN(nbBrakeCommands <= brakeResponseParams.size, "PxVehicleBrakeCommandLinearUpdate: nbBrakes must be less than or equal to brakeResponseParams.size"); + PxReal sum = 0.0f; + for (PxU32 i = 0; i < nbBrakeCommands; i++) + { + sum += PxVehicleNonLinearResponseCompute(brakeCommands[i], longitudinalSpeed, wheelId, brakeResponseParams[i]); + } + brakeResponseState = sum; +} + + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/braking/PxVehicleBrakingParams.h b/Source/ThirdParty/PhysX/vehicle2/braking/PxVehicleBrakingParams.h new file mode 100644 index 000000000..c48259aef --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/braking/PxVehicleBrakingParams.h @@ -0,0 +1,86 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "foundation/PxFoundation.h" + +#include "vehicle2/PxVehicleParams.h" + +#include "vehicle2/commands/PxVehicleCommandParams.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +/** +\brief Distribute a brake response to the wheels of a vehicle. +\note The brake torque of each wheel on the ith wheel is brakeCommand * maxResponse * wheelResponseMultipliers[i]. +\note A typical use case is to set maxResponse to be the vehicle's maximum achievable brake torque +that occurs when the brake command is equal to 1.0. The array wheelResponseMultipliers[i] would then be used +to specify the maximum achievable brake torque per wheel as a fractional multiplier of the vehicle's maximum achievable brake torque. +*/ +struct PxVehicleBrakeCommandResponseParams : public PxVehicleCommandResponseParams +{ + PX_FORCE_INLINE PxVehicleBrakeCommandResponseParams transformAndScale( + const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const + { + PX_UNUSED(srcFrame); + PX_UNUSED(trgFrame); + PxVehicleBrakeCommandResponseParams r = *this; + const PxReal scale = trgScale.scale/srcScale.scale; + r.maxResponse *= (scale*scale); //maxResponse is a torque! + return r; + } + + PX_FORCE_INLINE bool isValid(const PxVehicleAxleDescription& axleDesc) const + { + if (!axleDesc.isValid()) + return false; + PX_CHECK_AND_RETURN_VAL(maxResponse >= 0.0f, "PxVehicleBrakeCommandResponseParams.maxResponse must be greater than or equal to zero", false); + for (PxU32 i = 0; i < axleDesc.nbWheels; i++) + { + PX_CHECK_AND_RETURN_VAL(wheelResponseMultipliers[axleDesc.wheelIdsInAxleOrder[i]] >= 0.0f, "PxVehicleBrakeCommandResponseParams.wheelResponseMultipliers[i] must be greater than or equal to zero.", false); + } + return true; + } +}; + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/commands/PxVehicleCommandHelpers.h b/Source/ThirdParty/PhysX/vehicle2/commands/PxVehicleCommandHelpers.h new file mode 100644 index 000000000..b746bfc25 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/commands/PxVehicleCommandHelpers.h @@ -0,0 +1,76 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "vehicle2/PxVehicleParams.h" +#include "PxVehicleCommandParams.h" +#include "PxVehicleCommandStates.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +/** +\brief Compute the linear response to a command. +\param[in] command is a normalised command value. +\param[in] wheelId specifies the wheel that is to respond to the command. +\param[in] responseParams specifies the wheel responses for all wheels on a vehicle. +\return The linear response of the specified wheel to the command. +*/ +PX_FORCE_INLINE PxReal PxVehicleLinearResponseCompute +(const PxReal command, const PxU32 wheelId, const PxVehicleCommandResponseParams& responseParams) +{ + return command*responseParams.maxResponse*responseParams.wheelResponseMultipliers[wheelId]; +} + +/** +\brief Compute the non-linear response to a command. +\param[in] command is a normalised command value. +\param[in] longitudinalSpeed is the longitudional speed of the vehicle. +\param[in] wheelId specifies the wheel that is to respond to the command. +\param[in] responseParams specifies the wheel responses for all wheels on a vehicle. +\note responseParams is used to compute an interpolated normalized response to the combination of command and longitudinalSpeed. +The interpolated normalized response is then used in place of the command as input to PxVehicleComputeLinearResponse(). +*/ +PxReal PxVehicleNonLinearResponseCompute +(const PxReal command, const PxReal longitudinalSpeed, const PxU32 wheelId, const PxVehicleCommandResponseParams& responseParams); + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/commands/PxVehicleCommandParams.h b/Source/ThirdParty/PhysX/vehicle2/commands/PxVehicleCommandParams.h new file mode 100644 index 000000000..3b8265603 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/commands/PxVehicleCommandParams.h @@ -0,0 +1,202 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "foundation/PxFoundation.h" +#include "vehicle2/PxVehicleLimits.h" +#include "vehicle2/PxVehicleParams.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + + + +/** +\brief Each command value may be associated with a table specifying a normalized response as a function of longitudinal speed. +Multiple instances of PxVehicleCommandValueResponseTable allow a normalized response to be authored as a multi-variate +piecewise polynomial with normalized command response expressed as a nonlinear function of command value and speed. +*/ +struct PxVehicleCommandValueResponseTable +{ + enum Enum + { + eMAX_NB_SPEED_RESPONSES = 64 + }; + + /** + \brief The command value associated with the table of speed responses. + */ + PxReal commandValue; + + /** + \brief A lookup table specifying the normalised response to the specified command value as a function of longitudinal speed. + \note Each entry in the speedResponses table must be of the form (speed, normalizedResponse). + \note The longitudinal speeds in the table must form a monotonically increasing series. + \note The normalized responses must be in range (0,1). + */ + PxVehicleFixedSizeLookupTable speedResponses; +}; + +/** +\note Brake, drive and steer response typically reduce at increased longitudinal speed. Moreover, response to a brake, throttle or steer command is typically +nonlinear and may be subject to dead zones where response is constant with either zero or non-zero response. PxVehicleCommandNonLinearResponseParams allows +command responses to be authored as multi-variate piecewise polynomials with normalized command response a function of command value and longitudinal speed. +*/ +class PxVehicleCommandNonLinearResponseParams +{ +public: + + enum Enum + { + eMAX_NB_COMMAND_VALUES = 8 + }; + + PxVehicleCommandNonLinearResponseParams() + : nbSpeedResponses(0), + nbCommandValues(0) + { + } + + void clear() + { + nbCommandValues = 0; + nbSpeedResponses = 0; + } + + /** + \brief Add a table of normalised response vs speed and associated it with a specified command value. + \note commandValueSpeedResponses must be authored as a series of monotonically increasing series of speeds with form {speed, normalizedResponse} + \note The responses added must form a series of monotonically increasing commands. + */ + bool addResponse(const PxVehicleCommandValueResponseTable& commandValueSpeedResponses) + { + const PxReal commandValue = commandValueSpeedResponses.commandValue; + const PxReal* speeds = commandValueSpeedResponses.speedResponses.xVals; + const PxReal* responses = commandValueSpeedResponses.speedResponses.yVals; + const PxU16 nb = PxU16(commandValueSpeedResponses.speedResponses.nbDataPairs); + + PX_CHECK_AND_RETURN_VAL(commandValue >= 0.0f && commandValue <= 1.0f, "PxVehicleCommandAndResponseTable::commandValue must be in range (0,1)", false); + + PX_CHECK_AND_RETURN_VAL(nbCommandValues < eMAX_NB_COMMAND_VALUES, "PxVehicleNonLinearCommandResponse::addResponse - exceeded maximum number of command responses", false); + + PX_CHECK_AND_RETURN_VAL(((nbSpeedResponses + nb) <= PxVehicleCommandValueResponseTable::eMAX_NB_SPEED_RESPONSES), "PxVehicleNonLinearCommandResponse::addResponse - exceeded maximum number of command responses", false); + + PX_CHECK_AND_RETURN_VAL((0 == nbCommandValues) || (commandValue > commandValues[nbCommandValues - 1]), "PxVehicleNonLinearCommandResponse::addResponse - command must be part of a a monotonically increasing series", false); + + PX_CHECK_AND_RETURN_VAL(nb > 0, "PxVehicleNonLinearCommandResponse::addResponse - each command response must have at least 1 point", false); + +#if PX_CHECKED + for (PxU32 i = 1; i < nb; i++) + { + PX_CHECK_AND_RETURN_VAL(speeds[i] > speeds[i - 1], "PxVehicleNonLinearCommandResponse::addResponse - speeds array must be a monotonically increasing series", false); + PX_CHECK_AND_RETURN_VAL(responses[i] >= 0.0f && responses[i] <= 1.0f , "PxVehicleNonLinearCommandResponse::addResponse - response must be in range (0,1)", false); + } +#endif + + commandValues[nbCommandValues] = commandValue; + nbSpeedRenponsesPerCommandValue[nbCommandValues] = nb; + speedResponsesPerCommandValue[nbCommandValues] = nbSpeedResponses; + PxMemCopy(speedResponses + 2 * nbSpeedResponses, speeds, sizeof(PxReal)*nb); + PxMemCopy(speedResponses + 2 * nbSpeedResponses + nb, responses, sizeof(PxReal)*nb); + nbCommandValues++; + nbSpeedResponses += nb; + return true; + } + +public: + + /** + \brief A ragged array of speeds and normalized responses. + */ + PxReal speedResponses[PxVehicleCommandValueResponseTable::eMAX_NB_SPEED_RESPONSES * 2]; + + /** + \brief The number of speeds and normalized responses. + */ + PxU16 nbSpeedResponses; + + /** + \brief The table of speed responses for the ith command value begins at speedResponses[2*speedResponsesPerCommandValue[i]] + */ + PxU16 speedResponsesPerCommandValue[eMAX_NB_COMMAND_VALUES]; + + /** + \brief The ith command value has N speed responses with N = nbSpeedRenponsesPerCommandValue[i]. + */ + PxU16 nbSpeedRenponsesPerCommandValue[eMAX_NB_COMMAND_VALUES]; + + /** + \brief The command values. + */ + PxReal commandValues[eMAX_NB_COMMAND_VALUES]; + + /** + \brief The number of command values. + */ + PxU16 nbCommandValues; +}; + +/** +\brief A description of the per wheel response to an input command. +*/ +struct PxVehicleCommandResponseParams +{ + /** + \brief A nonlinear response to command value expressed as a lookup table of normalized response as a function of command value and longitudinal speed. + \note The effect of the default state of nonlinearResponse is a linear response to command value that is independent of longitudinal speed. + */ + PxVehicleCommandNonLinearResponseParams nonlinearResponse; + + /** + \brief A description of the per wheel response multiplier to an input command. + */ + PxReal wheelResponseMultipliers[PxVehicleLimits::eMAX_NB_WHEELS]; + + /** + \brief The maximum response that occurs when the wheel response multiplier has value 1.0 and nonlinearResponse is in the default state of linear response. + */ + PxF32 maxResponse; +}; + + + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/commands/PxVehicleCommandStates.h b/Source/ThirdParty/PhysX/vehicle2/commands/PxVehicleCommandStates.h new file mode 100644 index 000000000..6dec45eb3 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/commands/PxVehicleCommandStates.h @@ -0,0 +1,140 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "foundation/PxPreprocessor.h" +#include "foundation/PxSimpleTypes.h" +#include "foundation/PxMemory.h" +#include "vehicle2/PxVehicleLimits.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + + +/** +\brief A description of the state of commands that are applied to the vehicle +\note brakes[0] and brakes[1] may be used to distinguish brake and handbrake controls. +*/ +struct PxVehicleCommandState +{ + PxReal brakes[2]; //!< The instantaneous state of the brake controllers in range [0,1] with 1 denoting fully pressed and 0 fully depressed. + PxU32 nbBrakes; //|< The number of brake commands. + PxReal throttle; //!< The instantaneous state of the throttle controller in range [0,1] with 1 denoting fully pressed and 0 fully depressed. + PxReal steer; //!< The instantaneous state of the steer controller in range [-1,1]. + + PX_FORCE_INLINE void setToDefault() + { + PxMemZero(this, sizeof(PxVehicleCommandState)); + } +}; + +/** +\brief A description of the state of transmission-related commands that are applied to a vehicle with direct drive. +*/ +struct PxVehicleDirectDriveTransmissionCommandState +{ + /** + \brief Direct drive vehicles only have reverse, neutral or forward gear. + */ + enum Enum + { + eREVERSE = 0, + eNEUTRAL, + eFORWARD + }; + + Enum gear; //!< The desired gear of the input gear controller. + + PX_FORCE_INLINE void setToDefault() + { + PxMemZero(this, sizeof(PxVehicleDirectDriveTransmissionCommandState)); + } +}; + +/** +\brief A description of the state of transmission-related commands that are applied to a vehicle with engine drive. +*/ +struct PxVehicleEngineDriveTransmissionCommandState +{ + enum Enum + { + /** + \brief Special gear value to denote the automatic shift mode (often referred to as DRIVE). + + When using automatic transmission, setting this value as target gear will enable automatic + gear shifts between first and highest gear. If the current gear is a reverse gear or + the neutral gear, then this value will trigger a shift to first gear. If this value is + used even though there is no automatic transmission available, the gear state will remain + unchanged. + */ + eAUTOMATIC_GEAR = 0xff + }; + + PxReal clutch; //!< The instantaneous state of the clutch controller in range [0,1] with 1 denoting fully pressed and 0 fully depressed. + PxU32 targetGear; //!< The desired gear of the input gear controller. + + PX_FORCE_INLINE void setToDefault() + { + PxMemZero(this, sizeof(PxVehicleEngineDriveTransmissionCommandState)); + } +}; + +/** +\brief A description of the state of transmission-related commands that are applied to a vehicle with tank drive. +*/ +struct PxVehicleTankDriveTransmissionCommandState : public PxVehicleEngineDriveTransmissionCommandState +{ + /** + \brief The wheels of each tank track are either all connected to thrusts[0] or all connected to thrusts[1]. + \note The thrust commands are used to divert torque from the engine to the wheels of the tank tracks controlled by each thrust. + \note thrusts[0] and thrusts[1] are in range [-1,1] with the sign dictating whether the thrust will be applied positively or negatively with respect to the gearing ratio. + */ + PxReal thrusts[2]; + + PX_FORCE_INLINE void setToDefault() + { + PxMemZero(this, sizeof(PxVehicleTankDriveTransmissionCommandState)); + } +}; + + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/drivetrain/PxVehicleDrivetrainComponents.h b/Source/ThirdParty/PhysX/vehicle2/drivetrain/PxVehicleDrivetrainComponents.h new file mode 100644 index 000000000..75050de7b --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/drivetrain/PxVehicleDrivetrainComponents.h @@ -0,0 +1,802 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "vehicle2/PxVehicleFunctions.h" +#include "vehicle2/PxVehicleParams.h" +#include "vehicle2/PxVehicleComponent.h" + +#include "vehicle2/braking/PxVehicleBrakingFunctions.h" +#include "vehicle2/commands/PxVehicleCommandHelpers.h" +#include "vehicle2/rigidBody/PxVehicleRigidBodyStates.h" +#include "vehicle2/steering/PxVehicleSteeringFunctions.h" +#include "vehicle2/steering/PxVehicleSteeringParams.h" +#include "vehicle2/wheel/PxVehicleWheelStates.h" +#include "vehicle2/wheel/PxVehicleWheelParams.h" +#include "vehicle2/tire/PxVehicleTireStates.h" + +#include "PxVehicleDrivetrainStates.h" +#include "PxVehicleDrivetrainFunctions.h" + +#include "common/PxProfileZone.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +struct PxVehicleBrakeCommandResponseParams; +struct PxVehicleDirectDriveThrottleCommandResponseParams; + +/** +\brief Forward the applicable set of control values for a direct drive vehicle to a command response state for each +applicable control value. +\note The applicable control values are brake, handbrake, throttle and steer. +@see PxVehicleDirectDriveActuationStateComponent +@see PxVehicleDirectDrivetrainComponent +@see PxVehicleBrakeCommandLinearUpdate +@see PxVehicleDirectDriveThrottleLinearCommandUpdate +@see PxVehicleSteerCommandLinearUpdate +@see PxVehicleAckermannSteerUpdate +*/ +class PxVehicleDirectDriveCommandResponseComponent : public PxVehicleComponent +{ +public: + + PxVehicleDirectDriveCommandResponseComponent() : PxVehicleComponent() {} + virtual ~PxVehicleDirectDriveCommandResponseComponent() {} + + /** + \brief Provide vehicle data items for this component. + + \param[out] axleDescription identifies the wheels on each axle. + \param[out] brakeResponseParams An array of brake response parameters with a brake response for each brake command. + \param[out] throttleResponseParams The throttle response parameters. + \param[out] steerResponseParams The steer response parameters. + \param[out] ackermannParams The parameters defining Ackermann steering. NULL if no Ackermann steering is desired. + \param[out] commands The throttle, brake, steer etc. command states. + \param[out] transmissionCommands The transmission command state describing the current gear. + \param[out] rigidBodyState The state of the vehicle's rigid body. + \param[out] brakeResponseStates The resulting brake response states given the command input and brake response parameters. + \param[out] throttleResponseStates The resulting throttle response states given the command input and throttle response parameters. + \param[out] steerResponseStates The resulting steer response states given the command input, steer response and (optionally) Ackermann parameters. + */ + virtual void getDataForDirectDriveCommandResponseComponent( + const PxVehicleAxleDescription*& axleDescription, + PxVehicleSizedArrayData& brakeResponseParams, + const PxVehicleDirectDriveThrottleCommandResponseParams*& throttleResponseParams, + const PxVehicleSteerCommandResponseParams*& steerResponseParams, + PxVehicleSizedArrayData& ackermannParams, + const PxVehicleCommandState*& commands, const PxVehicleDirectDriveTransmissionCommandState*& transmissionCommands, + const PxVehicleRigidBodyState*& rigidBodyState, + PxVehicleArrayData& brakeResponseStates, + PxVehicleArrayData& throttleResponseStates, + PxVehicleArrayData& steerResponseStates) = 0; + + /** + \brief Compute a per wheel response to the input brake/handbrake/throttle/steer commands + and determine if there is an intention to accelerate the vehicle. + */ + virtual bool update(const PxReal dt, const PxVehicleSimulationContext& context) + { + PX_UNUSED(dt); + PX_UNUSED(context); + + PX_PROFILE_ZONE("PxVehicleDirectDriveCommandResponseComponent::update", 0); + + const PxVehicleAxleDescription* axleDescription; + PxVehicleSizedArrayData brakeResponseParams; + const PxVehicleDirectDriveThrottleCommandResponseParams* throttleResponseParams; + const PxVehicleSteerCommandResponseParams* steerResponseParams; + PxVehicleSizedArrayData ackermannParams; + const PxVehicleCommandState* commands; + const PxVehicleDirectDriveTransmissionCommandState* transmissionCommands; + const PxVehicleRigidBodyState* rigidBodyState; + PxVehicleArrayData brakeResponseStates; + PxVehicleArrayData throttleResponseStates; + PxVehicleArrayData steerResponseStates; + + getDataForDirectDriveCommandResponseComponent(axleDescription, + brakeResponseParams, throttleResponseParams, steerResponseParams, ackermannParams, + commands, transmissionCommands, + rigidBodyState, + brakeResponseStates, throttleResponseStates, steerResponseStates); + + const PxReal longitudinalSpeed = rigidBodyState->getLongitudinalSpeed(context.frame); + + for (PxU32 i = 0; i < axleDescription->nbWheels; i++) + { + const PxU32 wheelId = axleDescription->wheelIdsInAxleOrder[i]; + + PxVehicleBrakeCommandResponseUpdate( + commands->brakes, commands->nbBrakes, longitudinalSpeed, + wheelId, brakeResponseParams, + brakeResponseStates[wheelId]); + + PxVehicleDirectDriveThrottleCommandResponseUpdate( + commands->throttle, *transmissionCommands, longitudinalSpeed, + wheelId, *throttleResponseParams, + throttleResponseStates[wheelId]); + + PxVehicleSteerCommandResponseUpdate( + commands->steer, longitudinalSpeed, + wheelId, *steerResponseParams, + steerResponseStates[wheelId]); + } + if (ackermannParams.size > 0) + PxVehicleAckermannSteerUpdate( + commands->steer, + *steerResponseParams, ackermannParams, + steerResponseStates); + + return true; + } +}; + + +/** +\brief Determine the actuation state for each wheel of a direct drive vehicle. +\note The actuation state for each wheel contains a binary record of whether brake and drive torque are to be applied to the wheel. +@see PxVehicleDirectDriveCommandResponseComponent +@see PxVehicleDirectDrivetrainComponent +@see PxVehicleDirectDriveActuationStateUpdate +*/ +class PxVehicleDirectDriveActuationStateComponent : public PxVehicleComponent +{ +public: + + PxVehicleDirectDriveActuationStateComponent() : PxVehicleComponent() {} + virtual ~PxVehicleDirectDriveActuationStateComponent() {} + + + /** + \brief Provide vehicle data items for this component. + + \param[out] axleDescription identifies the wheels on each axle. + \param[out] brakeResponseStates The brake response states. + \param[out] throttleResponseStates The throttle response states. + \param[out] actuationStates The actuation states. + */ + virtual void getDataForDirectDriveActuationStateComponent( + const PxVehicleAxleDescription*& axleDescription, + PxVehicleArrayData& brakeResponseStates, + PxVehicleArrayData& throttleResponseStates, + PxVehicleArrayData& actuationStates) = 0; + + /** + \brief Compute the actuation state for each wheel given the brake, handbrake and throttle states. + \*/ + virtual bool update(const PxReal dt, const PxVehicleSimulationContext& context) + { + PX_UNUSED(dt); + PX_UNUSED(context); + + PX_PROFILE_ZONE("PxVehicleDirectDriveActuationStateComponent::update", 0); + + const PxVehicleAxleDescription* axleDescription; + PxVehicleArrayData brakeResponseStates; + PxVehicleArrayData throttleResponseStates; + PxVehicleArrayData actuationStates; + + getDataForDirectDriveActuationStateComponent( + axleDescription, + brakeResponseStates, throttleResponseStates, + actuationStates); + + for (PxU32 i = 0; i < axleDescription->nbWheels; i++) + { + const PxU32 wheelId = axleDescription->wheelIdsInAxleOrder[i]; + PxVehicleDirectDriveActuationStateUpdate( + brakeResponseStates[wheelId], throttleResponseStates[wheelId], + actuationStates[wheelId]); + } + + return true; + } +}; + +/** +\brief Forward integrate the angular speed of each wheel on a vehicle by integrating the +brake and drive torque applied to each wheel and the torque that develops on the tire as a response +to the longitudinal tire force. +@see PxVehicleDirectDriveUpdate +*/ +class PxVehicleDirectDrivetrainComponent : public PxVehicleComponent +{ +public: + + PxVehicleDirectDrivetrainComponent() : PxVehicleComponent() {} + virtual ~PxVehicleDirectDrivetrainComponent() {} + + virtual void getDataForDirectDrivetrainComponent( + const PxVehicleAxleDescription*& axleDescription, + PxVehicleArrayData& brakeResponseStates, + PxVehicleArrayData& throttleResponseStates, + PxVehicleArrayData& wheelParams, + PxVehicleArrayData& actuationStates, + PxVehicleArrayData& tireForces, + PxVehicleArrayData& wheelRigidBody1dStates) = 0; + + virtual bool update(const PxReal dt, const PxVehicleSimulationContext& context) + { + PX_UNUSED(context); + + PX_PROFILE_ZONE("PxVehicleDirectDrivetrainComponent::update", 0); + + const PxVehicleAxleDescription* axleDescription; + PxVehicleArrayData brakeResponseStates; + PxVehicleArrayData throttleResponseStates; + PxVehicleArrayData wheelParams; + PxVehicleArrayData actuationStates; + PxVehicleArrayData tireForces; + PxVehicleArrayData wheelRigidBody1dStates; + + getDataForDirectDrivetrainComponent(axleDescription, + brakeResponseStates, throttleResponseStates, + wheelParams, actuationStates, tireForces, + wheelRigidBody1dStates); + + for (PxU32 i = 0; i < axleDescription->nbWheels; i++) + { + const PxU32 wheelId = axleDescription->wheelIdsInAxleOrder[i]; + + PxVehicleDirectDriveUpdate( + wheelParams[wheelId], actuationStates[wheelId], + brakeResponseStates[wheelId], throttleResponseStates[wheelId], + tireForces[wheelId], + dt, + wheelRigidBody1dStates[wheelId]); + } + + return true; + } +}; + +/** +\brief Forward the applicable set of control values for a vehicle driven by an engine to a command response state for each +applicable control value. + +If parameters for an autobox are provided, the autobox will determine if a gear change should begin in order to +maintain a desired engine revs. + +@see PxVehicleBrakeCommandLinearUpdate +@see PxVehicleClutchCommandResponseLinearUpdate +@see PxVehicleEngineDriveThrottleCommandResponseUpdate +@see PxVehicleSteerCommandLinearUpdate +@see PxVehicleAckermannSteerUpdate +@see PxVehicleAutoBoxUpdate +@see PxVehicleGearCommandResponseUpdate +*/ +class PxVehicleEngineDriveCommandResponseComponent : public PxVehicleComponent +{ +public: + + PxVehicleEngineDriveCommandResponseComponent() : PxVehicleComponent() {} + virtual ~PxVehicleEngineDriveCommandResponseComponent() {} + + /** + \brief Provide vehicle data items for this component. + \param[out] axleDescription identifies the wheels on each axle. + \param[out] brakeResponseParams An array of brake response parameters with a brake response for each brake command. + \param[out] steerResponseParams The steer response parameters. + \param[out] ackermannParams The parameters defining Ackermann steering. NULL if no Ackermann steering is desired. + \param[out] gearboxParams The gearbox parameters. + \param[out] clutchResponseParams The clutch response parameters. + \param[out] engineParams The engine parameters. Only needed if an autobox is provided (see autoboxParams), else it can be set to NULL. + \param[out] engineState The engine state. Only needed if an autobox is provided (see autoboxParams), else it can be set to NULL. + \param[out] autoboxParams The autobox parameters. If not NULL, the autobox will determine the target gear. Requires the parameters + engineParams, engineState and autoboxState to be available. If no autobox is desired, NULL can be used in which case + the aforementioned additional parameters can be set to NULL too. + \param[out] rigidBodyState The state of the vehicle's rigid body. + \param[out] commands The throttle, brake, steer etc. command states. + \param[out] transmissionCommands The clutch, target gear etc. command states. If an autobox is provided (see autoboxParams) + and the target gear is set to PxVehicleEngineDriveTransmissionCommandState::eAUTOMATIC_GEAR, then the autobox will trigger + gear shifts. + \param[out] brakeResponseStates The resulting brake response states given the command input and brake response parameters. + \param[out] throttleResponseState The resulting throttle response to the input throttle command. + \param[out] steerResponseStates The resulting steer response states given the command input, steer response and (optionally) Ackermann parameters. + \param[out] gearboxResponseState The resulting gearbox response state given the command input and gearbox parameters. + \param[out] clutchResponseState The resulting clutch state given the command input and clutch response parameters. + \param[out] autoboxState The resulting autobox state given the autobox/engine/gear params and engine state. Only needed if an autobox is + provided (see autoboxParams), else it can be set to NULL. + */ + virtual void getDataForEngineDriveCommandResponseComponent( + const PxVehicleAxleDescription*& axleDescription, + PxVehicleSizedArrayData& brakeResponseParams, + const PxVehicleSteerCommandResponseParams*& steerResponseParams, + PxVehicleSizedArrayData& ackermannParams, + const PxVehicleGearboxParams*& gearboxParams, + const PxVehicleClutchCommandResponseParams*& clutchResponseParams, + const PxVehicleEngineParams*& engineParams, + const PxVehicleRigidBodyState*& rigidBodyState, + const PxVehicleEngineState*& engineState, + const PxVehicleAutoboxParams*& autoboxParams, + const PxVehicleCommandState*& commands, + const PxVehicleEngineDriveTransmissionCommandState*& transmissionCommands, + PxVehicleArrayData& brakeResponseStates, + PxVehicleEngineDriveThrottleCommandResponseState*& throttleResponseState, + PxVehicleArrayData& steerResponseStates, + PxVehicleGearboxState*& gearboxResponseState, + PxVehicleClutchCommandResponseState*& clutchResponseState, + PxVehicleAutoboxState*& autoboxState) = 0; + + virtual bool update(const PxReal dt, const PxVehicleSimulationContext& context) + { + PX_UNUSED(dt); + PX_UNUSED(context); + + PX_PROFILE_ZONE("PxVehicleEngineDriveCommandResponseComponent::update", 0); + + const PxVehicleAxleDescription* axleDescription; + PxVehicleSizedArrayData brakeResponseParams; + const PxVehicleSteerCommandResponseParams* steerResponseParams; + PxVehicleSizedArrayData ackermannParams; + const PxVehicleGearboxParams* gearboxParams; + const PxVehicleClutchCommandResponseParams* clutchResponseParams; + const PxVehicleEngineParams* engineParams; + const PxVehicleRigidBodyState* rigidBodyState; + const PxVehicleEngineState* engineState; + const PxVehicleAutoboxParams* autoboxParams; + const PxVehicleCommandState* commands; + const PxVehicleEngineDriveTransmissionCommandState* transmissionCommands; + PxVehicleArrayData brakeResponseStates; + PxVehicleEngineDriveThrottleCommandResponseState* throttleResponseState; + PxVehicleArrayData steerResponseStates; + PxVehicleGearboxState* gearboxResponseState; + PxVehicleClutchCommandResponseState* clutchResponseState; + PxVehicleAutoboxState* autoboxState; + + getDataForEngineDriveCommandResponseComponent(axleDescription, + brakeResponseParams, steerResponseParams, ackermannParams, + gearboxParams, clutchResponseParams, engineParams, rigidBodyState, + engineState, autoboxParams, + commands, transmissionCommands, + brakeResponseStates, throttleResponseState, + steerResponseStates, + gearboxResponseState, clutchResponseState, autoboxState); + + //The autobox can modify commands like throttle and target gear. Since the user defined + //values should not be overwritten, a copy is used to compute the response. + PxVehicleCommandState commandsTmp = *commands; + PxVehicleEngineDriveTransmissionCommandState transmissionCommandsTmp = *transmissionCommands; + + const PxReal longitudinalSpeed = rigidBodyState->getLongitudinalSpeed(context.frame); + + //Let the autobox set the target gear, unless the user defined target gear requests + //a shift already + if (autoboxParams) + { + PX_ASSERT(engineParams); + PX_ASSERT(engineState); + PX_ASSERT(autoboxState); + + PxVehicleAutoBoxUpdate( + *engineParams, *gearboxParams, *autoboxParams, + *engineState, *gearboxResponseState, dt, + transmissionCommandsTmp.targetGear, *autoboxState, commandsTmp.throttle); + } + else if (transmissionCommandsTmp.targetGear == PxVehicleEngineDriveTransmissionCommandState::eAUTOMATIC_GEAR) + { + //If there is no autobox but eAUTOMATIC_GEAR was specified, use the current target gear + transmissionCommandsTmp.targetGear = gearboxResponseState->targetGear; + } + + //Distribute brake torque to the wheels across each axle. + for (PxU32 i = 0; i < axleDescription->nbWheels; i++) + { + const PxU32 wheelId = axleDescription->wheelIdsInAxleOrder[i]; + PxVehicleBrakeCommandResponseUpdate( + commandsTmp.brakes, commandsTmp.nbBrakes, longitudinalSpeed, + wheelId, brakeResponseParams, + brakeResponseStates[i]); + } + + //Update target gear as required. + PxVehicleGearCommandResponseUpdate( + transmissionCommandsTmp.targetGear, + *gearboxParams, + *gearboxResponseState); + + //Compute the response to the clutch command. + PxVehicleClutchCommandResponseLinearUpdate( + transmissionCommandsTmp.clutch, + *clutchResponseParams, + *clutchResponseState); + + //Compute the response to the throttle command. + PxVehicleEngineDriveThrottleCommandResponseLinearUpdate( + commandsTmp, + *throttleResponseState); + + //Update the steer angles and Ackermann correction. + for (PxU32 i = 0; i < axleDescription->nbWheels; i++) + { + const PxU32 wheelId = axleDescription->wheelIdsInAxleOrder[i]; + PxVehicleSteerCommandResponseUpdate(commandsTmp.steer, longitudinalSpeed, wheelId, *steerResponseParams, steerResponseStates[i]); + } + if (ackermannParams.size > 0) + PxVehicleAckermannSteerUpdate(commandsTmp.steer, *steerResponseParams, ackermannParams, steerResponseStates); + + return true; + } +}; + +/** +\brief Compute the per wheel drive torque split of a multi-wheel drive differential. +@see PxVehicleDifferentialStateUpdate +*/ +class PxVehicleMultiWheelDriveDifferentialStateComponent : public PxVehicleComponent +{ +public: + + PxVehicleMultiWheelDriveDifferentialStateComponent() : PxVehicleComponent() {} + virtual ~PxVehicleMultiWheelDriveDifferentialStateComponent() {} + + virtual void getDataForMultiWheelDriveDifferentialStateComponent( + const PxVehicleAxleDescription*& axleDescription, + const PxVehicleMultiWheelDriveDifferentialParams*& differentialParams, + PxVehicleDifferentialState*& differentialState) = 0; + + virtual bool update(const PxReal dt, const PxVehicleSimulationContext& context) + { + PX_UNUSED(dt); + PX_UNUSED(context); + + PX_PROFILE_ZONE("PxVehicleMultiWheelDriveDifferentialStateComponent::update", 0); + + const PxVehicleAxleDescription* axleDescription; + const PxVehicleMultiWheelDriveDifferentialParams* differentialParams; + PxVehicleDifferentialState* differentialState; + + getDataForMultiWheelDriveDifferentialStateComponent(axleDescription, + differentialParams, differentialState); + + PxVehicleDifferentialStateUpdate( + *axleDescription, + *differentialParams, + *differentialState); + + return true; + } +}; + +/** +\brief Compute the per wheel drive torque split of a differential delivering torque to multiple wheels +with limited slip applied to specified wheel pairs. +@see PxVehicleDifferentialStateUpdate +*/ +class PxVehicleFourWheelDriveDifferentialStateComponent : public PxVehicleComponent +{ +public: + + PxVehicleFourWheelDriveDifferentialStateComponent() : PxVehicleComponent() {} + virtual ~PxVehicleFourWheelDriveDifferentialStateComponent() {} + + virtual void getDataForFourWheelDriveDifferentialStateComponent( + const PxVehicleAxleDescription*& axleDescription, + const PxVehicleFourWheelDriveDifferentialParams*& differentialParams, + PxVehicleArrayData& wheelRigidbody1dStates, + PxVehicleDifferentialState*& differentialState, + PxVehicleWheelConstraintGroupState*& wheelConstraintGroupState) = 0; + + virtual bool update(const PxReal dt, const PxVehicleSimulationContext& context) + { + PX_UNUSED(dt); + PX_UNUSED(context); + + PX_PROFILE_ZONE("PxVehicleFourWheelDriveDifferentialStateComponent::update", 0); + + const PxVehicleAxleDescription* axleDescription; + const PxVehicleFourWheelDriveDifferentialParams* differentialParams; + PxVehicleArrayData wheelRigidbody1dStates; + PxVehicleDifferentialState* differentialState; + PxVehicleWheelConstraintGroupState* wheelConstraintGroupState; + + getDataForFourWheelDriveDifferentialStateComponent(axleDescription, differentialParams, + wheelRigidbody1dStates, + differentialState, wheelConstraintGroupState); + + PxVehicleDifferentialStateUpdate( + *axleDescription, *differentialParams, + wheelRigidbody1dStates, dt, + *differentialState, *wheelConstraintGroupState); + + return true; + } +}; + +/** +\brief Compute the per wheel drive torque split of a tank drive differential. +@see PxVehicleDifferentialStateUpdate +*/ +class PxVehicleTankDriveDifferentialStateComponent : public PxVehicleComponent +{ +public: + + PxVehicleTankDriveDifferentialStateComponent() : PxVehicleComponent() {} + virtual ~PxVehicleTankDriveDifferentialStateComponent() {} + + /** + \brief Provide vehicle data items for this component. + + \param[out] axleDescription identifies the wheels on each axle. + \param[out] transmissionCommands specifies the values of the thrust controllers that divert torque to the tank tracks. + \param[out] wheelParams is an array describing the radius of each wheel. + \param[out] differentialParams describes the operation of the tank differential by + specifying the default torque split between all wheels connected to the differential and by + specifying the wheels coupled to each tank track. + \param[out] differentialState stores the instantaneous torque split between all wheels arising from the difference between the thrust controllers. + \param[out] constraintGroupState stores the groups of wheels that are connected by sharing a tank track. + */ + virtual void getDataForTankDriveDifferentialStateComponent( + const PxVehicleAxleDescription*& axleDescription, + const PxVehicleTankDriveTransmissionCommandState*& transmissionCommands, + PxVehicleArrayData& wheelParams, + const PxVehicleTankDriveDifferentialParams*& differentialParams, + PxVehicleDifferentialState*& differentialState, + PxVehicleWheelConstraintGroupState*& constraintGroupState) = 0; + + virtual bool update(const PxReal dt, const PxVehicleSimulationContext& context) + { + PX_UNUSED(dt); + PX_UNUSED(context); + + PX_PROFILE_ZONE("PxVehicleTankDriveDifferentialStateComponent::update", 0); + + const PxVehicleAxleDescription* axleDescription; + const PxVehicleTankDriveTransmissionCommandState* transmissionCommands; + PxVehicleArrayData wheelParams; + const PxVehicleTankDriveDifferentialParams* differentialParams; + PxVehicleDifferentialState* differentialState; + PxVehicleWheelConstraintGroupState* constraintGroupState; + + getDataForTankDriveDifferentialStateComponent( + axleDescription, + transmissionCommands, + wheelParams, + differentialParams, + differentialState, constraintGroupState); + + PxVehicleDifferentialStateUpdate( + *axleDescription, + wheelParams, *differentialParams, + transmissionCommands->thrusts[0], transmissionCommands->thrusts[1], + *differentialState, *constraintGroupState); + + return true; + } +}; + +/** +@deprecated + +\brief Compute the per wheel drive torque split of a four wheel drive differential. +@see PxVehicleDifferentialStateUpdate +*/ +class PX_DEPRECATED PxVehicleLegacyFourWheelDriveDifferentialStateComponent : public PxVehicleComponent +{ +public: + + PxVehicleLegacyFourWheelDriveDifferentialStateComponent() : PxVehicleComponent() {} + virtual ~PxVehicleLegacyFourWheelDriveDifferentialStateComponent() {} + + virtual void getDataForLegacyFourWheelDriveDifferentialStateComponent( + const PxVehicleAxleDescription*& axleDescription, + const PxVehicleFourWheelDriveDifferentialLegacyParams*& differentialParams, + PxVehicleArrayData& wheelRigidbody1dStates, + PxVehicleDifferentialState*& differentialState) = 0; + + virtual bool update(const PxReal dt, const PxVehicleSimulationContext& context) + { + PX_UNUSED(dt); + PX_UNUSED(context); + + PX_PROFILE_ZONE("PxVehicleLegacyFourWheelDriveDifferentialStateComponent::update", 0); + + const PxVehicleAxleDescription* axleDescription; + const PxVehicleFourWheelDriveDifferentialLegacyParams* differentialParams; + PxVehicleArrayData wheelRigidbody1dStates; + PxVehicleDifferentialState* differentialState; + + getDataForLegacyFourWheelDriveDifferentialStateComponent(axleDescription, differentialParams, + wheelRigidbody1dStates, + differentialState); + + PxVehicleDifferentialStateUpdate( + *differentialParams, wheelRigidbody1dStates, + *differentialState); + + return true; + } +}; + +/** +\brief Determine the actuation state for each wheel for a vehicle propelled by engine torque. +\note The actuation state for each wheel contains a binary record of whether brake and drive torque are to be applied to the wheel. +@see PxVehicleEngineDriveActuationStateUpdate +*/ +class PxVehicleEngineDriveActuationStateComponent : public PxVehicleComponent +{ +public: + + PxVehicleEngineDriveActuationStateComponent() : PxVehicleComponent() {} + virtual ~PxVehicleEngineDriveActuationStateComponent() {} + + virtual void getDataForEngineDriveActuationStateComponent( + const PxVehicleAxleDescription*& axleDescription, + const PxVehicleGearboxParams*& gearboxParams, + PxVehicleArrayData& brakeResponseStates, + const PxVehicleEngineDriveThrottleCommandResponseState*& throttleResponseState, + const PxVehicleGearboxState*& gearboxState, + const PxVehicleDifferentialState*& differentialState, + const PxVehicleClutchCommandResponseState*& clutchResponseState, + PxVehicleArrayData& actuationStates) = 0; + + virtual bool update(const PxReal dt, const PxVehicleSimulationContext& context) + { + PX_UNUSED(dt); + PX_UNUSED(context); + + PX_PROFILE_ZONE("PxVehicleEngineDriveActuationStateComponent::update", 0); + + const PxVehicleAxleDescription* axleDescription; + const PxVehicleGearboxParams* gearboxParams; + PxVehicleArrayData brakeResponseStates; + const PxVehicleEngineDriveThrottleCommandResponseState* throttleResponseState; + const PxVehicleGearboxState* gearboxState; + const PxVehicleDifferentialState* differentialState; + const PxVehicleClutchCommandResponseState* clutchResponseState; + PxVehicleArrayData actuationStates; + + getDataForEngineDriveActuationStateComponent(axleDescription, gearboxParams, + brakeResponseStates, throttleResponseState, + gearboxState, differentialState, clutchResponseState, + actuationStates); + + PxVehicleEngineDriveActuationStateUpdate( + *axleDescription, + *gearboxParams, + brakeResponseStates, + *throttleResponseState, + *gearboxState, *differentialState, *clutchResponseState, + actuationStates); + + return true; + } +}; + +/** +\brief Forward integrate the angular speed of each wheel and of the engine, accounting for the +state of the clutch, gearbox and differential. +@see PxVehicleGearboxUpdate +@see PxVehicleEngineDrivetrainUpdate +*/ +class PxVehicleEngineDrivetrainComponent : public PxVehicleComponent +{ +public: + + PxVehicleEngineDrivetrainComponent() : PxVehicleComponent() {} + virtual ~PxVehicleEngineDrivetrainComponent() {} + + /** + \brief Provide vehicle data items for this component. + + \param[out] axleDescription identifies the wheels on each axle. + \param[out] wheelParams specifies the radius of each wheel. + \param[out] engineParams specifies the engine's torque curve, idle revs and max revs. + \param[out] clutchParams specifies the maximum strength of the clutch. + \param[out] gearboxParams specifies the gear ratio of each gear. + \param[out] brakeResponseStates stores the instantaneous brake brake torque to apply to each wheel. + \param[out] actuationStates stores whether a brake and/or drive torque are to be applied to each wheel. + \param[out] tireForces stores the lateral and longitudinal tire force that has developed on each tire. + \param[out] throttleResponseState stores the response of the throttle to the input throttle command. + \param[out] clutchResponseState stores the instantaneous clutch strength that arises from the input clutch command. + \param[out] differentialState stores the instantaneous torque split between the wheels. + \param[out] constraintGroupState stores the groups of wheels that are subject to constraints that require them to have the same angular or linear velocity. + \param[out] wheelRigidBody1dStates stores the per wheel angular speed to be computed by the component. + \param[out] engineState stores the engine rotation speed to be computed by the component. + \param[out] gearboxState stores the state of the gearbox to be computed by the component. + \param[out] clutchState stores the clutch slip to be computed by the component. + \note If constraintGroupState is set to NULL it is assumed that there are no requirements for any wheels to have the same angular or linear velocity. + */ + virtual void getDataForEngineDrivetrainComponent( + const PxVehicleAxleDescription*& axleDescription, + PxVehicleArrayData& wheelParams, + const PxVehicleEngineParams*& engineParams, + const PxVehicleClutchParams*& clutchParams, + const PxVehicleGearboxParams*& gearboxParams, + PxVehicleArrayData& brakeResponseStates, + PxVehicleArrayData& actuationStates, + PxVehicleArrayData& tireForces, + const PxVehicleEngineDriveThrottleCommandResponseState*& throttleResponseState, + const PxVehicleClutchCommandResponseState*& clutchResponseState, + const PxVehicleDifferentialState*& differentialState, + const PxVehicleWheelConstraintGroupState*& constraintGroupState, + PxVehicleArrayData& wheelRigidBody1dStates, + PxVehicleEngineState*& engineState, + PxVehicleGearboxState*& gearboxState, + PxVehicleClutchSlipState*& clutchState) = 0; + + virtual bool update(const PxReal dt, const PxVehicleSimulationContext& context) + { + PX_UNUSED(context); + + PX_PROFILE_ZONE("PxVehicleEngineDrivetrainComponent::update", 0); + + const PxVehicleAxleDescription* axleDescription; + PxVehicleArrayData wheelParams; + const PxVehicleEngineParams* engineParams; + const PxVehicleClutchParams* clutchParams; + const PxVehicleGearboxParams* gearboxParams; + PxVehicleArrayData brakeResponseStates; + PxVehicleArrayData actuationStates; + PxVehicleArrayData tireForces; + const PxVehicleEngineDriveThrottleCommandResponseState* throttleResponseState; + const PxVehicleClutchCommandResponseState* clutchResponseState; + const PxVehicleDifferentialState* differentialState; + const PxVehicleWheelConstraintGroupState* constraintGroupState; + PxVehicleArrayData wheelRigidBody1dStates; + PxVehicleEngineState* engineState; + PxVehicleGearboxState* gearboxState; + PxVehicleClutchSlipState* clutchState; + + getDataForEngineDrivetrainComponent(axleDescription, wheelParams, + engineParams, clutchParams, gearboxParams, + brakeResponseStates, actuationStates, tireForces, + throttleResponseState, clutchResponseState, differentialState, constraintGroupState, + wheelRigidBody1dStates, engineState, gearboxState, clutchState); + + PxVehicleGearboxUpdate(*gearboxParams, dt, *gearboxState); + + PxVehicleEngineDrivetrainUpdate( + *axleDescription, + wheelParams, + *engineParams, *clutchParams, *gearboxParams, + brakeResponseStates, actuationStates, + tireForces, + *gearboxState, *throttleResponseState, *clutchResponseState, *differentialState, constraintGroupState, + dt, + wheelRigidBody1dStates, *engineState, *clutchState); + + return true; + } +}; + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/drivetrain/PxVehicleDrivetrainFunctions.h b/Source/ThirdParty/PhysX/vehicle2/drivetrain/PxVehicleDrivetrainFunctions.h new file mode 100644 index 000000000..33bef117f --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/drivetrain/PxVehicleDrivetrainFunctions.h @@ -0,0 +1,318 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "foundation/PxSimpleTypes.h" +#include "vehicle2/PxVehicleParams.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +struct PxVehicleCommandState; +struct PxVehicleDirectDriveTransmissionCommandState; +struct PxVehicleEngineDriveTransmissionCommandState; +struct PxVehicleDirectDriveThrottleCommandResponseParams; +struct PxVehicleWheelActuationState; +struct PxVehicleWheelParams; +struct PxVehicleTireForce; +struct PxVehicleWheelRigidBody1dState; +struct PxVehicleEngineParams; +struct PxVehicleGearboxParams; +struct PxVehicleAutoboxParams; +struct PxVehicleEngineState; +struct PxVehicleGearboxState; +struct PxVehicleAutoboxState; +struct PxVehicleClutchCommandResponseParams; +struct PxVehicleClutchCommandResponseState; +struct PxVehicleEngineDriveThrottleCommandResponseState; +struct PxVehicleDifferentialState; +struct PxVehicleMultiWheelDriveDifferentialParams; +struct PxVehicleFourWheelDriveDifferentialParams; +struct PxVehicleTankDriveDifferentialParams; +struct PxVehicleFourWheelDriveDifferentialLegacyParams; +struct PxVehicleClutchParams; +struct PxVehicleWheelConstraintGroupState; +struct PxVehicleClutchSlipState; + +/** +\brief Compute the drive torque response to a throttle command. +\param[in] throttle is the throttle command. +\param[in] transmissionCommands is the gearing command to apply to the direct drive tranmission. +\param[in] longitudinalSpeed is the longitudinal speed of the vehicle's rigid body. +\param[in] wheelId specifies the wheel that is to have its throttle response computed. +\param[in] throttleResponseParams specifies the per wheel drive torque response to the throttle command as a nonlinear function of throttle command and longitudinal speed. +\param[out] throttleResponseState is the drive torque response to the input throttle command. +*/ +void PxVehicleDirectDriveThrottleCommandResponseUpdate +(const PxReal throttle, const PxVehicleDirectDriveTransmissionCommandState& transmissionCommands, const PxReal longitudinalSpeed, + const PxU32 wheelId, const PxVehicleDirectDriveThrottleCommandResponseParams& throttleResponseParams, + PxReal& throttleResponseState); + +/** +\brief Determine the actuation state of a wheel given the brake torque, handbrake torque and drive torque applied to it. +\param[in] brakeTorque is the brake torque to be applied to the wheel. +\param[in] driveTorque is the drive torque to be applied to the wheel. +\param[out] actuationState contains a binary record of whether brake or drive torque is applied to the wheel. +*/ +void PxVehicleDirectDriveActuationStateUpdate +(const PxReal brakeTorque, const PxReal driveTorque, + PxVehicleWheelActuationState& actuationState); + +/** +\brief Forward integrate the angular speed of a wheel given the brake and drive torque applied to it +\param[in] wheelParams specifies the moment of inertia of the wheel. +\param[in] actuationState is a binary record of whether brake and drive torque are to be applied to the wheel. +\param[in] brakeTorque is the brake torque to be applied to the wheel. +\param[in] driveTorque is the drive torque to be applied to the wheel. +\param[in] tireForce specifies the torque to apply to the wheel as a response to the longitudinal tire force. +\param[in] dt is the timestep of the forward integration. +\param[out] wheelRigidBody1dState describes the angular speed of the wheel. +*/ +void PxVehicleDirectDriveUpdate +(const PxVehicleWheelParams& wheelParams, + const PxVehicleWheelActuationState& actuationState, + const PxReal brakeTorque, const PxReal driveTorque, const PxVehicleTireForce& tireForce, + const PxF32 dt, + PxVehicleWheelRigidBody1dState& wheelRigidBody1dState); + +/** +\param[in] engineParams specifies the engine configuration. +\param[in] gearboxParams specifies the gear ratios and the time required to complete a gear change. +\param[in] autoboxParams specifies the conditions for switching gear. +\param[in] engineState contains the current angular speed of the engine. +\param[in] gearboxState describes the current and target gear. +\param[in] dt is the time that has lapsed since the last call to PxVehicleAutoBoxUpdate. +\param[in,out] targetGearCommand specifies the desired target gear for the gearbox. If set to + PxVehicleEngineDriveTransmissionCommandState::eAUTOMATIC_GEAR, the value will get overwritten + with a target gear chosen by the autobox. +\param[out] autoboxState specifies the time that has lapsed since the last automated gear change and contains a record of +any ongoing automated gear change. +\param[out] throttle A throttle command value in [0, 1] that will be set to 0 if a gear change is initiated or is ongoing. + +\note The autobox will not begin a gear change if a gear change is already ongoing. +\note The autobox will not begin a gear change until a threshold time has lapsed since the last automated gear change. +\note A gear change is considered as ongoing for as long as PxVehicleGearboxState::currentGear is different from + PxVehicleGearboxState::targetGear. +\note The autobox will not shift down from 1st gear or up from reverse gear. +\note The autobox shifts in single gear increments or decrements. +\note The autobox instantiates a gear change by setting PxVehicleCommandState::targetGear to be different from +from PxVehicleGearboxState::currentGear +*/ +void PxVehicleAutoBoxUpdate +(const PxVehicleEngineParams& engineParams, const PxVehicleGearboxParams& gearboxParams, const PxVehicleAutoboxParams& autoboxParams, + const PxVehicleEngineState& engineState, const PxVehicleGearboxState& gearboxState, + const PxReal dt, + PxU32& targetGearCommand, PxVehicleAutoboxState& autoboxState, + PxReal& throttle); + +/** +\brief Propagate input gear commands to the gearbox state. +\param[in] targetGearCommand specifies the target gear for the gearbox. +\param[in] gearboxParams specifies the number of gears and the index of neutral gear. +\param[out] gearboxState contains a record of the current and target gear. +\note Any ongoing gear change must complete before starting another. +\note A gear change is considered as ongoing for as long as PxVehicleGearboxState::currentGear is different from + PxVehicleGearboxState::targetGear. + \note The gearbox remains in neutral for the duration of the gear change. + \note A gear change begins if PxVehicleCommandState::targetGear is different from PxVehicleGearboxState::currentGear. +*/ +void PxVehicleGearCommandResponseUpdate +(const PxU32 targetGearCommand, + const PxVehicleGearboxParams& gearboxParams, + PxVehicleGearboxState& gearboxState); + +/** +\brief Propagate the input clutch command to the clutch response state. +\param[in] clutchCommand specifies the state of the clutch pedal. +\param[in] clutchResponseParams specifies how the clutch responds to the input clutch command. +\param[out] clutchResponse specifies the response of the clutch to the input clutch command. +*/ +void PxVehicleClutchCommandResponseLinearUpdate +(const PxReal clutchCommand, + const PxVehicleClutchCommandResponseParams& clutchResponseParams, + PxVehicleClutchCommandResponseState& clutchResponse); + +/** +\brief Propagate the input throttle command to the throttle response state. +\param[in] commands specifies the state of the throttle pedal. +\param[out] throttleResponse specifies how the clutch responds to the input throttle command. +*/ +void PxVehicleEngineDriveThrottleCommandResponseLinearUpdate +(const PxVehicleCommandState& commands, + PxVehicleEngineDriveThrottleCommandResponseState& throttleResponse); + +/** +\brief Determine the actuation state of all wheels on a vehicle. +\param[in] axleDescription is a decription of the axles of the vehicle and the wheels on each axle. +\param[in] gearboxParams specifies the index of the neutral gear of the gearbox. +\param[in] brakeResponseStates specifies the response of each wheel to the input brake command. +\param[in] throttleResponseState specifies the response of the engine to the input throttle command. +\param[in] gearboxState specifies the current gear. +\param[in] diffState specifies the fraction of available drive torque to be delivered to each wheel. +\param[in] clutchResponseState specifies the response of the clutch to the input throttle command. +\param[out] actuationStates is an array of binary records determining whether brake and drive torque are to be applied to each wheel. +\note Drive torque is not applied to a wheel if + a) the gearbox is in neutral + b) the differential delivers no torque to the wheel + c) no throttle is applied to the engine + c) the clutch is fully disengaged. +*/ +void PxVehicleEngineDriveActuationStateUpdate +(const PxVehicleAxleDescription& axleDescription, + const PxVehicleGearboxParams& gearboxParams, + const PxVehicleArrayData& brakeResponseStates, + const PxVehicleEngineDriveThrottleCommandResponseState& throttleResponseState, + const PxVehicleGearboxState& gearboxState, const PxVehicleDifferentialState& diffState, const PxVehicleClutchCommandResponseState& clutchResponseState, + PxVehicleArrayData& actuationStates); + +/** +@deprecated + +\brief Compute the fraction of available torque to be delivered to each wheel and gather a list of all +wheels connected to the differential. +\param[in] diffParams specifies the operation of a differential that can be connected to up to four wheels. +\param[in] wheelStates describes the angular speed of each wheel +\param[out] diffState contains the fraction of available drive torque to be delivered to each wheel. +\note If the handbrake is on then torque is only delivered to the wheels specified as the front wheels of the differential. +*/ +void PX_DEPRECATED PxVehicleDifferentialStateUpdate +(const PxVehicleFourWheelDriveDifferentialLegacyParams& diffParams, + const PxVehicleArrayData& wheelStates, + PxVehicleDifferentialState& diffState); + +/** +\brief Compute the fraction of available torque to be delivered to each wheel and gather a list of all +wheels connected to the differential. Additionally, add wheel constraints for wheel pairs whose +rotational speed ratio exceeds the corresponding differential bias. +\param[in] axleDescription is a decription of the axles of the vehicle and the wheels on each axle. +\param[in] diffParams describe the division of available drive torque and the biases of the limited +slip differential. +\param[in] wheelStates describes the rotational speeds of each wheel. +\param[in] dt is the simulation time that has passes since the last call to PxVehicleDifferentialStateUpdate() +\param[out] diffState contains the fraction of available drive torque to be delivered to each wheel. +\param[out] wheelConstraintGroupState describes the groups of wheels that have exceeded their corresponding +differential biases. +*/ +void PxVehicleDifferentialStateUpdate +(const PxVehicleAxleDescription& axleDescription, const PxVehicleFourWheelDriveDifferentialParams& diffParams, + const PxVehicleArrayData& wheelStates, + const PxReal dt, + PxVehicleDifferentialState& diffState, PxVehicleWheelConstraintGroupState& wheelConstraintGroupState); + +/** +\brief Compute the fraction of available torque to be delivered to each wheel and gather a list of all +wheels connected to the differential. +\param[in] axleDescription is a decription of the axles of the vehicle and the wheels on each axle. +\param[in] diffParams specifies the operation of a differential that can be connected to any combination of wheels. +\param[out] diffState contains the fraction of available drive torque to be delivered to each wheel connected to the differential. +*/ +void PxVehicleDifferentialStateUpdate +(const PxVehicleAxleDescription& axleDescription, const PxVehicleMultiWheelDriveDifferentialParams& diffParams, + PxVehicleDifferentialState& diffState); + +/** +\brief Compute the fraction of available torque to be delivered to each wheel and gather a list of all +wheels connected to the differential. +\param[in] axleDescription is a decription of the axles of the vehicle and the wheels on each axle. +\param[in] wheelParams is an array that describes the wheel radius of each wheel. +\param[in] diffParams specifies the operation of a tank differential. +\param[in] thrustCommand0 is the state of one of the two thrust controllers. +\param[in] thrustCommand1 is the state of one of the two thrust controllers. +\param[out] diffState contains the fraction of available drive torque to be delivered to each wheel connected to the differential. +\param[out] wheelConstraintGroupState describes the groups of wheels connected by sharing a tank track. +*/ +void PxVehicleDifferentialStateUpdate +(const PxVehicleAxleDescription& axleDescription, + const PxVehicleArrayData& wheelParams, const PxVehicleTankDriveDifferentialParams& diffParams, + const PxReal thrustCommand0, PxReal thrustCommand1, + PxVehicleDifferentialState& diffState, PxVehicleWheelConstraintGroupState& wheelConstraintGroupState); + + +/** +\brief Update the current gear of the gearbox. If a gear change is ongoing then complete the gear change if a threshold +time has passed since the beginning of the gear change. +\param[in] gearboxParams describes the time required to complete a gear change. +\param[in] dt is the time that has lapsed since the last call to PxVehicleGearboxUpdate. +\param[out] gearboxState is the gearbox state to be updated. +\note A gear change is considered as ongoing for as long as PxVehicleGearboxState::currentGear is different from + PxVehicleGearboxState::targetGear. +*/ +void PxVehicleGearboxUpdate +(const PxVehicleGearboxParams& gearboxParams, + const PxF32 dt, + PxVehicleGearboxState& gearboxState); + +/** +\brief Forward integrate the angular speed of the vehicle's wheels and engine, given the state of clutch, differential and gearbox. +\param[in] axleDescription is a decription of the axles of the vehicle and the wheels on each axle. +\param[in] wheelParams specifies the moment of inertia of each wheel. +\param[in] engineParams specifies the torque curve of the engine and its moment of inertia. +\param[in] clutchParams specifies the maximum clutch strength that happens when the clutch is fully engaged. +\param[in] gearboxParams specifies the gearing ratios of the gearbox. +\param[in] brakeResponseStates describes the per wheel response to the input brake command. +\param[in] actuationStates is a binary record of whether brake or drive torque is applied to each wheel. +\param[in] tireForces describes the torque to apply to each wheel as a response to the longitudinal tire force. +\param[in] gearboxState describes the current gear. +\param[in] throttleResponse describes the engine response to the input throttle pedal. +\param[in] clutchResponse describes the clutch response to the input clutch pedal. +\param[in] diffState describes the fraction of available drive torque to be delivered to each wheel. +\param[in] constraintGroupState describes groups of wheels with rotational speed constrained to the same value. +\param[in] dt is the time that has lapsed since the last call to PxVehicleEngineDrivetrainUpdate +\param[out] wheelRigidbody1dStates describes the angular speed of each wheel. +\param[out] engineState describes the angular speed of the engine. +\param[out] clutchState describes the clutch slip. +\note If constraintGroupState is NULL then it is assumed that there are no wheels subject to rotational speed constraints. +*/ +void PxVehicleEngineDrivetrainUpdate +(const PxVehicleAxleDescription& axleDescription, + const PxVehicleArrayData& wheelParams, + const PxVehicleEngineParams& engineParams, const PxVehicleClutchParams& clutchParams, const PxVehicleGearboxParams& gearboxParams, + const PxVehicleArrayData& brakeResponseStates, + const PxVehicleArrayData& actuationStates, + const PxVehicleArrayData& tireForces, + const PxVehicleGearboxState& gearboxState, const PxVehicleEngineDriveThrottleCommandResponseState& throttleResponse, const PxVehicleClutchCommandResponseState& clutchResponse, + const PxVehicleDifferentialState& diffState, const PxVehicleWheelConstraintGroupState* constraintGroupState, + const PxReal dt, + PxVehicleArrayData& wheelRigidbody1dStates, + PxVehicleEngineState& engineState, PxVehicleClutchSlipState& clutchState); + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/drivetrain/PxVehicleDrivetrainHelpers.h b/Source/ThirdParty/PhysX/vehicle2/drivetrain/PxVehicleDrivetrainHelpers.h new file mode 100644 index 000000000..908e5a922 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/drivetrain/PxVehicleDrivetrainHelpers.h @@ -0,0 +1,160 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "vehicle2/drivetrain/PxVehicleDrivetrainParams.h" +#include "vehicle2/drivetrain/PxVehicleDrivetrainStates.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +struct PxVehicleWheelRigidBody1dState; + +/** +\brief Compute the coupling strength of the clutch. +\param[in] clutchResponseState describes the response of the clutch to the input clutch command. +\param[in] gearboxParams holds the index of neutral gear. +\param[in] gearboxState describes the current gear. +\note If the gear is in neutral the clutch is fully disengaged and the clutch strength is 0. +\note A clutch response state of 0.0 denotes a fully engaged clutch with maximum strength. +\note A clutch response state of 1.0 denotes a fully disengaged clutch with a strength of 0.0. +*/ +PX_FORCE_INLINE PxReal PxVehicleClutchStrengthCompute(const PxVehicleClutchCommandResponseState& clutchResponseState, const PxVehicleGearboxParams& gearboxParams, const PxVehicleGearboxState& gearboxState) +{ + return (gearboxParams.neutralGear != gearboxState.currentGear) ? clutchResponseState.commandResponse : 0.0f; +} + +/** +\brief Compute the damping rate of the engine. +\param[in] engineParams describes various damping rates of the engine in different operational states. +\param[in] gearboxParams holds the index of neutral gear. +\param[in] gearboxState describes the current gear. +\param[in] clutchResponseState is the response of the clutch to the clutch command. +\param[in] throttleResponseState is the response of the throttle to the throttle command. +\note Engines typically have different damping rates with clutch engaged and disengaged. +\note Engines typically have different damping rates at different throttle pedal values. +@see PxVehicleClutchStrengthCompute() +\note In neutral gear the clutch is considered to be fully disengaged. +*/ +PX_FORCE_INLINE PxReal PxVehicleEngineDampingRateCompute +(const PxVehicleEngineParams& engineParams, + const PxVehicleGearboxParams& gearboxParams, const PxVehicleGearboxState& gearboxState, + const PxVehicleClutchCommandResponseState& clutchResponseState, + const PxVehicleEngineDriveThrottleCommandResponseState& throttleResponseState) +{ + const PxReal K = (gearboxParams.neutralGear != gearboxState.currentGear) ? clutchResponseState.normalisedCommandResponse : 0.0f; + const PxReal zeroThrottleDamping = engineParams.dampingRateZeroThrottleClutchEngaged + + (1.0f - K)* (engineParams.dampingRateZeroThrottleClutchDisengaged - engineParams.dampingRateZeroThrottleClutchEngaged); + const PxReal appliedThrottle = throttleResponseState.commandResponse; + const PxReal fullThrottleDamping = engineParams.dampingRateFullThrottle; + const PxReal engineDamping = zeroThrottleDamping + (fullThrottleDamping - zeroThrottleDamping)*appliedThrottle; + return engineDamping; +} + +/** +\brief Compute the gear ratio delivered by the gearbox in the current gear. +\param[in] gearboxParams describes the gear ratio of each gear and the final ratio. +\param[in] gearboxState describes the current gear. +\note The gear ratio is the product of the gear ratio of the current gear and the final gear ratio of the gearbox. +*/ +PX_FORCE_INLINE PxReal PxVehicleGearRatioCompute +(const PxVehicleGearboxParams& gearboxParams, const PxVehicleGearboxState& gearboxState) +{ + const PxReal gearRatio = gearboxParams.ratios[gearboxState.currentGear] * gearboxParams.finalRatio; + return gearRatio; +} + +/** +\brief Compute the drive torque to deliver to the engine. +\param[in] engineParams describes the profile of maximum available torque across the full range of engine rotational speed. +\param[in] engineState describes the engine rotational speed. +\param[in] throttleCommandResponseState describes the engine's response to input throttle command. +*/ +PX_FORCE_INLINE PxReal PxVehicleEngineDriveTorqueCompute +(const PxVehicleEngineParams& engineParams, const PxVehicleEngineState& engineState, const PxVehicleEngineDriveThrottleCommandResponseState& throttleCommandResponseState) +{ + const PxReal appliedThrottle = throttleCommandResponseState.commandResponse; + const PxReal peakTorque = engineParams.peakTorque; + const PxVehicleFixedSizeLookupTable& torqueCurve = engineParams.torqueCurve; + const PxReal normalisedRotSpeed = engineState.rotationSpeed/engineParams.maxOmega; + const PxReal engineDriveTorque = appliedThrottle*peakTorque*torqueCurve.interpolate(normalisedRotSpeed); + return engineDriveTorque; +} + +/** +@deprecated + +\brief Compute the contribution that each wheel makes to the averaged wheel speed at the clutch plate connected to the wheels driven by +the differential. +\param[in] diffParams describes the wheels coupled to the differential and the operation of the torque split at the differential. +\param[in] nbWheels The number of wheels. Can be larger than the number of wheels connected to the differential. +\param[out] diffAveWheelSpeedContributions describes the contribution that each wheel makes to the averaged wheel speed at the clutch. + The buffer needs to be sized to be able to hold at least nbWheels entries. +\note Any wheel on an axle connected to the differential could have a non-zero value, depending on the way the differential couples to the wheels. +\note Any wheel on an axle not connected to the differential will have a zero contribution to the averaged wheel speed. +*/ +void PX_DEPRECATED PxVehicleLegacyDifferentialWheelSpeedContributionsCompute +(const PxVehicleFourWheelDriveDifferentialLegacyParams& diffParams, + const PxU32 nbWheels, PxReal* diffAveWheelSpeedContributions); + +/** +@deprecated + +\brief Compute the fraction of available torque that is delivered to each wheel through the differential. +\param[in] diffParams describes the wheels coupled to the differential and the operation of the torque split at the differential. +\param[in] wheelOmegas describes the rotational speeds of the wheels. Is expected to have nbWheels entries. +\param[in] nbWheels The number of wheels. Can be larger than the number of wheels connected to the differential. +\param[out] diffTorqueRatios describes the fraction of available torque delivered to each wheel. + The buffer needs to be sized to be able to hold at least nbWheels entries. +\note Any wheel on an axle connected to the diff could receive a non-zero ratio, depending on the way the differential couples to the wheels. +\note Any wheel not on an axle connected to the diff will have a zero value. +\note The sum of all the ratios adds to 1.0. +\note Slipping wheels driven by the differential will typically receive less torque than non-slipping wheels in the event that the +differential has a limited slip configuration. +*/ +void PX_DEPRECATED PxVehicleLegacyDifferentialTorqueRatiosCompute +(const PxVehicleFourWheelDriveDifferentialLegacyParams& diffParams, + const PxVehicleArrayData& wheelOmegas, + const PxU32 nbWheels, PxReal* diffTorqueRatios); + + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/drivetrain/PxVehicleDrivetrainParams.h b/Source/ThirdParty/PhysX/vehicle2/drivetrain/PxVehicleDrivetrainParams.h new file mode 100644 index 000000000..cb2bdc871 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/drivetrain/PxVehicleDrivetrainParams.h @@ -0,0 +1,991 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "foundation/PxFoundation.h" +#include "common/PxCoreUtilityTypes.h" + +#include "vehicle2/PxVehicleParams.h" + +#include "vehicle2/commands/PxVehicleCommandParams.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +/** +\brief Distribute a throttle response to the wheels of a direct drive vehicle. +\note The drive torque applied to each wheel on the ith axle is throttleCommand * maxResponse * wheelResponseMultipliers[i]. +\note A typical use case is to set maxResponse to be the vehicle's maximum achievable drive torque +that occurs when the steer command is equal to 1.0. The array wheelResponseMultipliers[i] would then be used +to specify the maximum achievable drive torque per wheel as a fractional multiplier of the vehicle's maximum achievable steer angle. +*/ +struct PxVehicleDirectDriveThrottleCommandResponseParams : public PxVehicleCommandResponseParams +{ + PX_FORCE_INLINE PxVehicleDirectDriveThrottleCommandResponseParams transformAndScale( + const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const + { + PX_UNUSED(srcFrame); + PX_UNUSED(trgFrame); + PxVehicleDirectDriveThrottleCommandResponseParams r = *this; + const PxReal scale = trgScale.scale/srcScale.scale; + r.maxResponse *= (scale*scale); //Max response is a torque! + return r; + } + + PX_FORCE_INLINE bool isValid(const PxVehicleAxleDescription& axleDesc) const + { + PX_CHECK_AND_RETURN_VAL(PxIsFinite(maxResponse), "PxVehicleDirectDriveThrottleCommandResponseParams.maxResponse must be a finite value", false); + for (PxU32 i = 0; i < axleDesc.nbWheels; i++) + { + PX_CHECK_AND_RETURN_VAL(PxIsFinite(wheelResponseMultipliers[axleDesc.wheelIdsInAxleOrder[i]]), "PxVehicleDirectDriveThrottleCommandResponseParams.wheelResponseMultipliers[i] must be a finite value", false); + } + return true; + } +}; + +/** +\brief Specifies the maximum clutch strength that occurs when the clutch pedal is fully disengaged and the clutch is fully engaged. +*/ +struct PxVehicleClutchCommandResponseParams +{ + /** + \brief Strength of clutch. + + \note The clutch is the mechanism that couples the engine to the wheels. + A stronger clutch more strongly couples the engine to the wheels, while a + clutch of strength zero completely decouples the engine from the wheels. + Stronger clutches more quickly bring the wheels and engine into equilibrium, while weaker + clutches take longer, resulting in periods of clutch slip and delays in power transmission + from the engine to the wheels. + The torque generated by the clutch is proportional to the clutch strength and + the velocity difference between the engine's rotational speed and the rotational speed of the + driven wheels after accounting for the gear ratio. + The torque at the clutch is applied negatively to the engine and positively to the driven wheels. + + Range: [0,inf)
+ Unit: torque * time = mass * (length^2) / time + */ + PxReal maxResponse; + + PX_FORCE_INLINE PxVehicleClutchCommandResponseParams transformAndScale( + const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const + { + PX_UNUSED(srcFrame); + PX_UNUSED(trgFrame); + const PxReal scale = trgScale.scale/srcScale.scale; + PxVehicleClutchCommandResponseParams r = *this; + r.maxResponse *= (scale*scale); + return r; + } + + PX_FORCE_INLINE bool isValid() const + { + PX_CHECK_AND_RETURN_VAL(maxResponse >= 0.0f, "PxVehicleClutchCommandResponseParams.maxResponse must be greater than or equal to zero", false); + return true; + } +}; + +/** +\brief Choose between a potentially more expensive but more accurate solution to the clutch model or a potentially cheaper but less accurate solution. +@see PxVehicleClutchParams +*/ +struct PxVehicleClutchAccuracyMode +{ + enum Enum + { + eESTIMATE = 0, + eBEST_POSSIBLE + }; +}; + +/** +\brief The clutch connects two plates together. One plate rotates with the speed of the engine. The second plate rotates with a weighted average of all +wheels connected to the differential after accounting for the gear ratio. The difference in rotation speeds generates a restoring torque applied to engine and wheels +that aims to reduce the difference in rotational speed. The restoring torque is proportional to the clutch strength and the clutch pedal position. +*/ +struct PxVehicleClutchParams +{ +public: + + /** + \brief The engine and wheel rotation speeds that are coupled through the clutch can be updated by choosing + one of two modes: eESTIMATE and eBEST_POSSIBLE. + + \note If eESTIMATE is chosen the vehicle sdk will update the wheel and engine rotation speeds + with estimated values to the implemented clutch model. + + \note If eBEST_POSSIBLE is chosen the vehicle sdk will compute the best possible + solution (within floating point tolerance) to the implemented clutch model. + This is the recommended mode. + + \note The clutch model remains the same if either eESTIMATE or eBEST_POSSIBLE is chosen but the accuracy and + computational cost of the solution to the model can be tuned as required. + */ + PxVehicleClutchAccuracyMode::Enum accuracyMode; + + /** + \brief Tune the mathematical accuracy and computational cost of the computed estimate to the wheel and + engine rotation speeds if eESTIMATE is chosen. + + \note As estimateIterations increases the computational cost of the clutch also increases and the solution + approaches the solution that would be computed if eBEST_POSSIBLE was chosen instead. + + \note This has no effect if eBEST_POSSIBLE is chosen as the accuracy mode. + + \note A value of zero is not allowed if eESTIMATE is chosen as the accuracy mode. + */ + PxU32 estimateIterations; + + PX_FORCE_INLINE PxVehicleClutchParams transformAndScale( + const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const + { + PX_UNUSED(srcFrame); + PX_UNUSED(trgFrame); + PX_UNUSED(srcScale); + PX_UNUSED(trgScale); + return *this; + } + + PX_FORCE_INLINE bool isValid() const + { + PX_CHECK_AND_RETURN_VAL((PxVehicleClutchAccuracyMode::eBEST_POSSIBLE == accuracyMode) || ((PxVehicleClutchAccuracyMode::eESTIMATE == accuracyMode) && (estimateIterations > 0)), "PxVehicleClutchParams.estimateIterations must be greater than zero if PxVehicleClutchAccuracyMode::eESTIMATE is selected", false); + return true; + } +}; + + +struct PxVehicleEngineParams +{ + /** + \brief Maximum supported number of points in the #torqueCurve graph. + */ + enum + { + eMAX_NB_ENGINE_TORQUE_CURVE_ENTRIES = 8 + }; + + /** + \brief Graph of normalized torque (torque/#peakTorque) against normalized engine speed ( engineRotationSpeed / #maxOmega ). + + \note The normalized engine speed is the x-axis of the graph, while the normalized torque is the y-axis of the graph. + */ + PxVehicleFixedSizeLookupTable torqueCurve; + + /** + \brief Moment of inertia of the engine around the axis of rotation. + + Range: (0, inf)
+ Unit: mass * (length^2) + */ + PxReal moi; + + /** + \brief Maximum torque available to apply to the engine when the accelerator pedal is at maximum. + + \note The torque available is the value of the accelerator pedal (in range [0, 1]) multiplied by the normalized torque as computed from #torqueCurve multiplied by #peakTorque. + + Range: [0, inf)
+ Unit: mass * (length^2) / (time^2) + */ + PxReal peakTorque; + + /** + \brief Minimum rotation speed of the engine. + + Range: [0, inf)
+ Unit: radians / time + */ + PxReal idleOmega; + + /** + \brief Maximum rotation speed of the engine. + + Range: [0, inf)
+ Unit: radians / time + */ + PxReal maxOmega; + + /** + \brief Damping rate of engine when full throttle is applied. + + \note If the clutch is engaged (any gear except neutral) then the damping rate applied at run-time is an interpolation + between #dampingRateZeroThrottleClutchEngaged and #dampingRateFullThrottle: + #dampingRateZeroThrottleClutchEngaged + (#dampingRateFullThrottle-#dampingRateZeroThrottleClutchEngaged)*acceleratorPedal; + + \note If the clutch is disengaged (in neutral gear) the damping rate applied at run-time is an interpolation + between #dampingRateZeroThrottleClutchDisengaged and #dampingRateFullThrottle: + #dampingRateZeroThrottleClutchDisengaged + (#dampingRateFullThrottle-#dampingRateZeroThrottleClutchDisengaged)*acceleratorPedal; + + Range: [0, inf)
+ Unit: torque * time = mass * (length^2) / time + */ + PxReal dampingRateFullThrottle; + + /** + \brief Damping rate of engine when no throttle is applied and with engaged clutch. + + \note If the clutch is engaged (any gear except neutral) then the damping rate applied at run-time is an interpolation + between #dampingRateZeroThrottleClutchEngaged and #dampingRateFullThrottle: + #dampingRateZeroThrottleClutchEngaged + (#dampingRateFullThrottle-#dampingRateZeroThrottleClutchEngaged)*acceleratorPedal; + + \note If the clutch is disengaged (in neutral gear) the damping rate applied at run-time is an interpolation + between #dampingRateZeroThrottleClutchDisengaged and #dampingRateFullThrottle: + #dampingRateZeroThrottleClutchDisengaged + (#dampingRateFullThrottle-#dampingRateZeroThrottleClutchDisengaged)*acceleratorPedal; + + Range: [0, inf)
+ Unit: torque * time = mass * (length^2) / time + */ + PxReal dampingRateZeroThrottleClutchEngaged; + + /** + \brief Damping rate of engine when no throttle is applied and with disengaged clutch. + + \note If the clutch is engaged (any gear except neutral) then the damping rate applied at run-time is an interpolation + between #dampingRateZeroThrottleClutchEngaged and #dampingRateFullThrottle: + #dampingRateZeroThrottleClutchEngaged + (#dampingRateFullThrottle-#dampingRateZeroThrottleClutchEngaged)*acceleratorPedal; + + \note If the clutch is disengaged (in neutral gear) the damping rate applied at run-time is an interpolation + between #dampingRateZeroThrottleClutchDisengaged and #dampingRateFullThrottle: + #dampingRateZeroThrottleClutchDisengaged + (#dampingRateFullThrottle-#dampingRateZeroThrottleClutchDisengaged)*acceleratorPedal; + + Range: [0, inf)
+ Unit: torque * time = mass * (length^2) / time + */ + PxReal dampingRateZeroThrottleClutchDisengaged; + + PX_FORCE_INLINE PxVehicleEngineParams transformAndScale( + const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const + { + PX_UNUSED(srcFrame); + PX_UNUSED(trgFrame); + PxVehicleEngineParams r = *this; + const PxReal scale = trgScale.scale/srcScale.scale; + r.moi *= (scale*scale); + r.peakTorque *= (scale*scale); + r.dampingRateFullThrottle *= (scale*scale); + r.dampingRateZeroThrottleClutchDisengaged *= (scale*scale); + r.dampingRateZeroThrottleClutchEngaged *= (scale*scale); + return r; + } + + PX_FORCE_INLINE bool isValid() const + { + PX_CHECK_AND_RETURN_VAL(moi > 0.0f, "PxVehicleEngineParams.moi must be greater than zero", false); + PX_CHECK_AND_RETURN_VAL(peakTorque >= 0.0f, "PxVehicleEngineParams.peakTorque must be greater than or equal to zero", false); + PX_CHECK_AND_RETURN_VAL(torqueCurve.isValid(), "PxVehicleEngineParams.torqueCurve is invalid", false); + PX_CHECK_AND_RETURN_VAL(maxOmega >= 0.0f, "PxVehicleEngineParams.maxOmega must be greater than or equal to zero", false); + PX_CHECK_AND_RETURN_VAL(idleOmega >= 0.0f, "PxVehicleEngineParams.idleOmega must be greater or equal to zero", false); + PX_CHECK_AND_RETURN_VAL(dampingRateFullThrottle >= 0.0f, "PxVehicleEngineParams.dampingRateFullThrottle must be greater than or equal to zero", false); + PX_CHECK_AND_RETURN_VAL(dampingRateZeroThrottleClutchEngaged >= 0.0f, "PxVehicleEngineParams.dampingRateZeroThrottleClutchEngaged must be greater than or equal to zero", false); + PX_CHECK_AND_RETURN_VAL(dampingRateZeroThrottleClutchDisengaged >= 0.0f, "PxVehicleEngineParams.dampingRateZeroThrottleClutchDisengaged must be greater than or equal to zero", false) + return true; + } +}; + +struct PxVehicleGearboxParams +{ +public: + + /** + \brief The gear that denotes neutral gear + */ + PxU32 neutralGear; + + /** + \brief Maximum supported number of gears, including reverse and neutral. + */ + enum Enum + { + eMAX_NB_GEARS = 32 + }; + + /** + \brief Gear ratios + + The ratio for reverse gears must be negative, the ratio for the neutral gear + has to be 0 and the ratio for forward gears must be positive. + */ + PxReal ratios[eMAX_NB_GEARS]; + + /** + \brief Gear ratio applied is #ratios[currentGear]*#finalRatio + + Range: (0, inf)
+ */ + PxReal finalRatio; + + /** + \brief Number of gears (including reverse and neutral). + + Range: [1, eMAX_NB_GEARS]
+ */ + PxU32 nbRatios; + + /** + \brief Time it takes to switch gear. + + Range: [0, inf)
+ Unit: time + */ + PxReal switchTime; + + PX_FORCE_INLINE PxVehicleGearboxParams transformAndScale( + const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const + { + PX_UNUSED(srcFrame); + PX_UNUSED(trgFrame); + PX_UNUSED(srcScale); + PX_UNUSED(trgScale); + return *this; + } + + PX_FORCE_INLINE bool isValid() const + { + PX_CHECK_AND_RETURN_VAL(finalRatio > 0, "PxVehicleGearboxParams.finalRatio must be greater than zero", false); + PX_CHECK_AND_RETURN_VAL(nbRatios >= 1, "PxVehicleGearboxParams.nbRatios must be greater than zero", false); + PX_CHECK_AND_RETURN_VAL(nbRatios <= eMAX_NB_GEARS, "PxVehicleGearboxParams.nbRatios must be less than or equal to eMAX_NB_GEARS", false); + PX_CHECK_AND_RETURN_VAL(neutralGear < nbRatios, "PxVehicleGearboxParams.neutralGear must be less than PxVehicleGearboxParams.nbRatios", false); + PX_CHECK_AND_RETURN_VAL(switchTime >= 0.0f, "PxVehicleGearboxParams.switchTime must be greater than or equal to zero", false); + for(PxU32 i = 0; i < neutralGear; i++) + { + PX_CHECK_AND_RETURN_VAL(ratios[i] < 0.0f, "Reverse gear ratios must be less than zero", false); + } + { + PX_CHECK_AND_RETURN_VAL(ratios[neutralGear] == 0.0f, "Neutral gear ratio must be equal to zero", false); + } + for (PxU32 i = neutralGear + 1; i < nbRatios; i++) + { + PX_CHECK_AND_RETURN_VAL(ratios[i] > 0.0f, "Forward gear ratios must be greater than zero", false); + } + for (PxU32 i = neutralGear + 2; i < nbRatios; i++) + { + PX_CHECK_AND_RETURN_VAL(ratios[i] < ratios[i - 1], "Forward gear ratios must be a descending sequence of gear ratios", false); + } + return true; + } +}; + + +struct PxVehicleAutoboxParams +{ +public: + + /** + \brief Value of ( engineRotationSpeed /maxEngineRevs ) that is high enough to increment gear. + + \note When ( engineRotationSpeed / #PxVehicleEngineParams::maxOmega ) > upRatios[currentGear] the autobox will begin + a transition to currentGear+1 unless currentGear is the highest possible gear or neutral or reverse. + + Range: [0, 1]
+ */ + PxReal upRatios[PxVehicleGearboxParams::eMAX_NB_GEARS]; + + /** + \brief Value of engineRevs/maxEngineRevs that is low enough to decrement gear. + + \note When ( engineRotationSpeed / #PxVehicleEngineParams::maxOmega) < downRatios[currentGear] the autobox will begin + a transition to currentGear-1 unless currentGear is first gear or neutral or reverse. + + Range: [0, 1]
+ */ + PxReal downRatios[PxVehicleGearboxParams::eMAX_NB_GEARS]; + + /** + \brief Set the latency time of the autobox. + + \note Latency time is the minimum time that must pass between each gear change that is initiated by the autobox. + The auto-box will only attempt to initiate another gear change up or down if the simulation time that has passed since the most recent + automated gear change is greater than the specified latency. + + Range: [0, inf)
+ Unit: time + */ + PxReal latency; + + PX_FORCE_INLINE PxVehicleAutoboxParams transformAndScale( + const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const + { + PX_UNUSED(srcFrame); + PX_UNUSED(trgFrame); + PX_UNUSED(srcScale); + PX_UNUSED(trgScale); + return *this; + } + + PX_FORCE_INLINE bool isValid(const PxVehicleGearboxParams& gearboxParams) const + { + if (!gearboxParams.isValid()) + return false; + + for (PxU32 i = gearboxParams.neutralGear + 1; i < gearboxParams.nbRatios-1; i++) + { + PX_CHECK_AND_RETURN_VAL(upRatios[i] >= 0.0f, "PxVehicleAutoboxParams.upRatios must be greater than or equal to zero", false); + } + for (PxU32 i = gearboxParams.neutralGear + 2; i < gearboxParams.nbRatios; i++) + { + PX_CHECK_AND_RETURN_VAL(downRatios[i] >= 0.0f, "PxVehicleAutoboxParams.downRatios must be greater than or equal to zero", false); + } + PX_CHECK_AND_RETURN_VAL(latency >= 0.0f, "PxVehicleAutoboxParams.latency must be greater than or equal to zero", false); + return true; + } +}; + +/** +@deprecated +*/ +struct PX_DEPRECATED PxVehicleFourWheelDriveDifferentialLegacyParams +{ +public: + + enum Enum + { + eDIFF_TYPE_LS_4WD, //limited slip differential for car with 4 driven wheels + eDIFF_TYPE_LS_FRONTWD, //limited slip differential for car with front-wheel drive + eDIFF_TYPE_LS_REARWD, //limited slip differential for car with rear-wheel drive + eMAX_NB_DIFF_TYPES + }; + + /** + \brief The two front wheels are specified by the array frontWheelIds. + \note The states eDIFF_TYPE_LS_4WD, eDIFF_TYPE_LS_FRONTWD require knowledge of the front wheels + to allow torque splits between front and rear axles as well as torque splits across the front axle. + \note frontWheelIds[0] should specify the wheel on the front axle that is negatively placed on the lateral axis. + \note frontWheelIds[1] should specify the wheel on the front axle that is positively placed on the lateral axis. + \note If #frontNegPosSplit > 0.5, more torque will be delivered to the wheel specified by frontWheelIds[0] than to the wheel + specified by frontWheelIds[1]. The converse is true if #frontNegPosSplit < 0.5. + */ + PxU32 frontWheelIds[2]; + + + /** + \brief The two rear wheels are specified by the array rearWheelIds. + \note The states eDIFF_TYPE_LS_4WD, eDIFF_TYPE_LS_REARWD require knowledge of the rear wheels + to allow torque splits between front and rear axles as well as torque splits across the rear axle. + \note rearWheelIds[0] should specify the wheel on the rear axle that is negatively placed on the lateral axis. + \note rearWheelIds[1] should specify the wheel on the rear axle that is positively placed on the lateral axis. + \note If #rearNegPosSplit > 0.5, more torque will be delivered to the wheel specified by rearWheelIds[0] than to the wheel + specified by rearWheelIds[1]. The converse is true if #rearNegPosSplit < 0.5. + */ + PxU32 rearWheelIds[2]; + + /** + \brief Ratio of torque split between front and rear wheels (>0.5 means more front, <0.5 means more to rear). + + \note Only applied to DIFF_TYPE_LS_4WD + + Range: [0, 1]
+ */ + PxReal frontRearSplit; + + /** + \brief Ratio of torque split between front-negative and front-positive wheels (>0.5 means more to #frontWheelIds[0], <0.5 means more to #frontWheelIds[1]). + + \note Only applied to DIFF_TYPE_LS_4WD and DIFF_TYPE_LS_FRONTWD + + Range: [0, 1]
+ */ + PxReal frontNegPosSplit; + + /** + \brief Ratio of torque split between rear-negative wheel and rear-positive wheels (>0.5 means more to #rearWheelIds[0], <0.5 means more to #rearWheelIds[1]). + + \note Only applied to DIFF_TYPE_LS_4WD and eDIFF_TYPE_LS_REARWD + + Range: [0, 1]
+ */ + PxReal rearNegPosSplit; + + /** + \brief Maximum allowed ratio of average front wheel rotation speed and rear wheel rotation speeds. + The differential will divert more torque to the slower wheels when the bias is exceeded. + + \note Only applied to DIFF_TYPE_LS_4WD + + Range: [1, inf)
+ */ + PxReal centerBias; + + /** + \brief Maximum allowed ratio of front-left and front-right wheel rotation speeds. + The differential will divert more torque to the slower wheel when the bias is exceeded. + + \note Only applied to DIFF_TYPE_LS_4WD and DIFF_TYPE_LS_FRONTWD + + Range: [1, inf)
+ */ + PxReal frontBias; + + /** + \brief Maximum allowed ratio of rear-left and rear-right wheel rotation speeds. + The differential will divert more torque to the slower wheel when the bias is exceeded. + + \note Only applied to DIFF_TYPE_LS_4WD and DIFF_TYPE_LS_REARWD + + Range: [1, inf)
+ */ + PxReal rearBias; + + /** + \brief Type of differential. + + Range: [DIFF_TYPE_LS_4WD, eDIFF_TYPE_LS_REARWD]
+ */ + Enum type; + + PX_FORCE_INLINE PxVehicleFourWheelDriveDifferentialLegacyParams transformAndScale( + const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const + { + PX_UNUSED(srcFrame); + PX_UNUSED(trgFrame); + PX_UNUSED(srcScale); + PX_UNUSED(trgScale); + return *this; + } + + PX_FORCE_INLINE bool isValid(const PxVehicleAxleDescription& axleDesc) const + { + PX_UNUSED(axleDesc); + PX_CHECK_AND_RETURN_VAL((axleDesc.getAxle(frontWheelIds[0]) != 0xffffffff) && (axleDesc.getAxle(frontWheelIds[0])== axleDesc.getAxle(frontWheelIds[1])), "frontWheelIds[0] and frontWheelIds[1] must reference wheels on the same axle", false); + PX_CHECK_AND_RETURN_VAL((axleDesc.getAxle(rearWheelIds[0]) != 0xffffffff) && (axleDesc.getAxle(rearWheelIds[0]) == axleDesc.getAxle(rearWheelIds[1])), "rearWheelIds[0] and rearWheelIds[1] must reference wheels on the same axle", false); + PX_CHECK_AND_RETURN_VAL(frontRearSplit <= 1.0f && frontRearSplit >= 0.0f, "PxVehicleLegacyFourWheelDriveDifferentialParams.frontRearSplit must be in range [0,1]", false); + PX_CHECK_AND_RETURN_VAL(frontNegPosSplit <= 1.0f && frontNegPosSplit >= 0.0f, "PxVehicleLegacyFourWheelDriveDifferentialParams.frontNegPosSplit must be in range [0,1]", false); + PX_CHECK_AND_RETURN_VAL(rearNegPosSplit <= 1.0f && rearNegPosSplit >= 0.0f, "PxVehicleLegacyFourWheelDriveDifferentialParams.rearNegPosSplit must be in range [0,1]", false); + PX_CHECK_AND_RETURN_VAL(centerBias >= 1.0f, "PxVehicleLegacyFourWheelDriveDifferentialParams.centerBias must be greater than or equal to 1.0f", false); + PX_CHECK_AND_RETURN_VAL(frontBias >= 1.0f, "PxVehicleLegacyFourWheelDriveDifferentialParams.frontBias must be greater than or equal to 1.0f", false); + PX_CHECK_AND_RETURN_VAL(rearBias >= 1.0f, "PxVehicleLegacyFourWheelDriveDifferentialParams.rearBias must be greater than or equal to 1.0f", false); + PX_CHECK_AND_RETURN_VAL(type < PxVehicleFourWheelDriveDifferentialLegacyParams::eMAX_NB_DIFF_TYPES, "PxVehicleLegacyFourWheelDriveDifferentialParams.type has illegal value", false); + return true; + } +}; + +/** +\brief PxVehicleMultiWheelDriveDifferentialParams specifies the wheels that are to receive drive torque from the differential +and the division of torque between the wheels that are connected to the differential. +*/ +struct PxVehicleMultiWheelDriveDifferentialParams +{ + /** + \brief torqueRatios describes the fraction of torque delivered to each wheel through the differential. + \note Wheels not connected to the differential must receive zero torque. + \note Wheels connected to the differential may receive a non-zero torque. + \note The sum of the absolute of the ratios of all wheels must equal to 1.0. + \note A negative torque ratio simulates a wheel with negative gearing applied. + + Range: [1, -1]
+ */ + PxReal torqueRatios[PxVehicleLimits::eMAX_NB_WHEELS]; + + /** + \brief aveWheelSpeedRatios describes the contribution of each wheel to the average wheel speed measured at the clutch. + \note Wheels not connected to the differential do not contribute to the average wheel speed measured at the clutch. + \note Wheels connected to the differential may delivere a non-zero contribution to the average wheel speed measured at the clutch. + \note The sum of all ratios of all wheels must equal to 1.0. + + Range: [0, 1]
+ */ + PxReal aveWheelSpeedRatios[PxVehicleLimits::eMAX_NB_WHEELS]; + + + PX_FORCE_INLINE void setToDefault() + { + PxMemZero(this, sizeof(PxVehicleMultiWheelDriveDifferentialParams)); + } + + PX_FORCE_INLINE PxVehicleMultiWheelDriveDifferentialParams transformAndScale( + const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const + { + PX_UNUSED(srcFrame); + PX_UNUSED(trgFrame); + PX_UNUSED(srcScale); + PX_UNUSED(trgScale); + return *this; + } + + PX_FORCE_INLINE bool isValid(const PxVehicleAxleDescription& axleDesc) const + { + if (!axleDesc.isValid()) + return false; + PxReal aveWheelSpeedSum = 0.0f; + PxReal torqueRatioSum = 0.0f; + for (PxU32 i = 0; i < axleDesc.nbWheels; i++) + { + const PxU32 wheelId = axleDesc.wheelIdsInAxleOrder[i]; + PX_CHECK_AND_RETURN_VAL(PxAbs(torqueRatios[wheelId]) <= 1.0f, "PxVehicleMultiWheelDriveDifferentialParams.torqueRatios[i] must be in range [-1, 1] for all wheels connected to the differential", false); + PX_CHECK_AND_RETURN_VAL(aveWheelSpeedRatios[wheelId] >= 0.0f && aveWheelSpeedRatios[wheelId] <= 1.0f, "PxVehicleMultiWheelDriveDifferentialParams.aveWheelSpeedRatios[i] must be in range [0, 1] for all wheels connected to the differential", false); + aveWheelSpeedSum += aveWheelSpeedRatios[wheelId]; + torqueRatioSum += PxAbs(torqueRatios[wheelId]); + } + PX_CHECK_AND_RETURN_VAL(aveWheelSpeedSum >= 0.99f && aveWheelSpeedSum <= 1.01f, "Sum of PxVehicleMultiWheelDriveDifferentialParams.aveWheelSpeedRatios[i] must be 1.0.", false); + PX_CHECK_AND_RETURN_VAL(torqueRatioSum >= 0.99f && torqueRatioSum <= 1.01f, "Sum of PxVehicleMultiWheelDriveDifferentialParams.torqueRatios[i] must be 1.0.", false); + PX_UNUSED(aveWheelSpeedSum); + PX_UNUSED(torqueRatioSum); + return true; + } +}; + +/** +\brief A special value that indicates instantaneous resolution of a slip that exceeds a differential bias. +*/ +#define PX_VEHICLE_FOUR_WHEEL_DIFFERENTIAL_MAXIMUM_STRENGTH PX_MAX_F32 + +/** +\brief PxVehicleFourWheelDriveDifferentialParams specifies the wheels that are to receive drive torque from the differential +and the division of torque between the wheels that are connected to the differential. Additionally, it specifies the biases +and strength of a limited slip differential that operates on two wheels specified as front wheels and two wheels specified +as rear wheels. +*/ +struct PxVehicleFourWheelDriveDifferentialParams : public PxVehicleMultiWheelDriveDifferentialParams +{ + /** + \brief The ids of the two wheels considered by the differential to be the front pair. + \note When the ratio of the rotational speeds of the front wheels exceeds frontBias, drive torque is diverted so + that the ratio approaches the value specified by frontTarget. When the bias is not breached, the drive torque + is specified by the corresponding entries in PxVehicleMultiWheelDriveDifferentialParams::torqueRatios. + */ + PxU32 frontWheelIds[2]; + + /** + \brief The ids of the two wheels considered by the differential to be the rear pair. + \note When the ratio of the rotational speeds of the rear wheels exceeds rearBias, drive torque is diverted so + that the ratio approaches the value specified by rearTarget. When the bias is not breached, the drive torque + is specified by the corresponding entries in PxVehicleMultiWheelDriveDifferentialParams::torqueRatios. + */ + PxU32 rearWheelIds[2]; + + /** + \brief The parameter frontBias specifies the maximum angular speed ratio of the two front wheels specified by frontWheelIds[2]. + \note If frontBias has value 0.0, the differential will not try to enforce any relationship between the rotational speeds of the two front wheels. + \note If frontBias has value 0.0, the torque split between the front wheels is specified by the array torqueRatios. + \note frontBias must have value 0.0 (deactivated limited slip) or be greater than 1.0 (activated limited slip) or be equal to 1.0 (locked axle). + \note If frontBias has value greater than or equal to 1.0 then the array frontWheelIds must be specified and the corresponding entries of + the isConnected[] array must be set true. + \note If frontBias has value greater than or equal to 1.0 then frontTarget must also be specified. + \note A locked axle may be achieved by setting frontBias and frontTarget to 1.0. + \note A limited slip differential may be achieved by setting frontBias > 1.0 and frontBias > frontTarget > 1.0. + */ + PxReal frontBias; + + /** + \brief The parameter frontTarget specifies the target rotational speed ratio of the two front wheels in the event that the ratio exceeds frontBias and frontBias + is configured for an activated limited slip or locked axle. + \note frontTarget must be less than frontBias and greater than 1.0 to implement a limited slip differential. + \note Set frontTarget and frontBias to 1.0 to implement a locked axle. + */ + PxReal frontTarget; + + /** + \brief The parameter rearBias specifies the maximum angular speed ratio of the two rear wheels specified by rearWheelIds[2]. + \note If rearBias has value 0.0, the differential will not try to enforce any relationship between the rotational speeds of the two rear wheels. + \note If rearBias has value 0.0, the torque split between the rear wheels is specified by the array torqueRatios. + \note rearBias must have value 0.0 (deactivated limited slip) or be greater than 1.0 (activated limited slip) or be equal to 1.0 (locked axle). + \note If rearBias has value greater than or equal to 1.0 then the array rearWheelIds must be specified and the corresponding entries of + the isConnected[] array must be set true. + \note If rearBias has value greater than or equal to 1.0 then rearTarget must also be specified. + \note A locked axle may be achieved by setting rearBias and rearTarget to 1.0. + \note A limited slip differential may be achieved by setting rearBias > 1.0 and rearBias > rearTarget > 1.0 + */ + PxReal rearBias; + + /** + \brief The parameter rearTarget specifies the target rotational speed ratio of the two rear wheels in the event that the ratio exceeds rearBias and rearBias + is configured for an activated limited slip or locked axle. + \note rearTarget must be less than rearBias and greater than 1.0 to implement a limited slip differential. + \note Set rearTarget and rearBias to 1.0 to implement a locked axle. + */ + PxReal rearTarget; + + /** + \brief The parameter centerBias specifies the maximum angular speed ratio of the sum of the two front wheels and the sum of the two rear wheels, + as specified by frontWheelIds[2] and rearWheelIds[2]. + \note If centerBias has value 0.0, the differential will not try to enforce any relationship between the rotational speeds of the front and rear wheels. + \note If centerBias has value 0.0, the torque split between the front and rear rear wheels is specified by the array torqueRatios. + \note centerBias must have value 0.0 (deactivated limited slip) or be greater than 1.0 (activated limited slip) or be equal to 1.0 (locked). + \note If centerBias has value greater than or equal to 1.0 then the arrays frontWheelIds and rearWheelIds must be specified and the corresponding entries of + the isConnected[] array must be set true. + \note If centerBias has value greater than or equal to 1.0 then centerTarget must also be specified. + \note A locked front/rear differential may be achieved by setting centerBias and centerTarget to 1.0. + \note A limited slip differential may be achieved by setting centerBias > 1.0 and centerBias > centerTarget > 1.0 + */ + PxReal centerBias; + + /** + \brief The parameter centerTarget specifies the target rotational speed ratio of the sum of the two front wheels and the sum of the two rear wheels + in the event that the ratio exceeds centerBias and centerBias is configured for an activated limited slip. + \note centerTarget must be less than centerBias and greater than 1.0 to implement a limited slip differential. + \note Set centerTarget and centerBias to 1.0 to implement a locked differential. + */ + PxReal centerTarget; + + /** + \brief The parameter rate specifies how quickly the ratio of rotational speeds approaches the target rotational speed ratio. + \note strength must be in range [0,PX_VEHICLE_FOUR_WHEEL_DIFF_MAXIMUM_STRENGTH]. + \note The ratio of rotational speeds is decremented each update by rate*dt until the ratio is equal to the target ratio. + \note A value of 0 will result in a deactivated limited slip. + \note A value of PX_VEHICLE_FOUR_WHEEL_DIFF_MAXIMUM_STRENGTH will result in instantaneous correction of the rotational speed ratios. + */ + PxReal rate; + + + PX_FORCE_INLINE void setToDefault() + { + PxVehicleMultiWheelDriveDifferentialParams::setToDefault(); + frontBias = 0.0f; + rearBias = 0.0f; + centerBias = 0.0f; + } + + PX_FORCE_INLINE bool isValid(const PxVehicleAxleDescription& axleDesc) const + { + if (!PxVehicleMultiWheelDriveDifferentialParams::isValid(axleDesc)) + return false; + + PX_CHECK_AND_RETURN_VAL((0.0f == centerBias) || + (centerBias > 1.0f && + frontWheelIds[0] < axleDesc.nbWheels && frontWheelIds[1] < axleDesc.nbWheels && + rearWheelIds[0] < axleDesc.nbWheels && rearWheelIds[1] < axleDesc.nbWheels), + "PxVehicleFourWheelDriveDifferentialParams:: centreBias is enabled but the frontWheelIds and rearWheelIds are not configured correctly.", false); + PX_CHECK_AND_RETURN_VAL((0.0f == centerBias) || + (centerBias > 1.0f && + frontWheelIds[0] != frontWheelIds[1] && frontWheelIds[0] != rearWheelIds[0] && frontWheelIds[0] != rearWheelIds[1] && + frontWheelIds[1] != rearWheelIds[0] && frontWheelIds[1] != rearWheelIds[1] && + rearWheelIds[0] != rearWheelIds[1]), + "PxVehicleFourWheelDriveDifferentialParams:: centreBias is enabled but the frontWheelIds and rearWheelIds are not configured correctly.", false); + PX_CHECK_AND_RETURN_VAL((0.0f == centerBias) || + (centerBias > 1.0f && + torqueRatios[frontWheelIds[0]] != 0.0f && torqueRatios[frontWheelIds[1]] != 0.0f && torqueRatios[rearWheelIds[0]] != 0.0f && torqueRatios[rearWheelIds[1]] != 0.0f), + "PxVehicleFourWheelDriveDifferentialParams:: centreBias is enabled but the front and rear wheels are not connected.", false); + + PX_CHECK_AND_RETURN_VAL((0.0f == rearBias) || + (rearBias > 1.0f && rearWheelIds[0] < axleDesc.nbWheels && rearWheelIds[1] < axleDesc.nbWheels), + "PxVehicleFourWheelDriveDifferentialParams:: rearBias is enabled but the rearWheelIds are not configured correctly.", false); + PX_CHECK_AND_RETURN_VAL((0.0f == rearBias) || + (rearBias > 1.0f && rearWheelIds[0] != rearWheelIds[1]), + "PxVehicleFourWheelDriveDifferentialParams:: rearBias is enabled but the rearWheelIds are not configured correctly.", false); + PX_CHECK_AND_RETURN_VAL((0.0f == centerBias) || + (rearBias > 1.0f && torqueRatios[rearWheelIds[0]] != 0.0f && torqueRatios[rearWheelIds[1]] != 0.0f), + "PxVehicleFourWheelDriveDifferentialParams:: rearBias is enabled but the rear wheels are not connected.", false); + + PX_CHECK_AND_RETURN_VAL((0.0f == frontBias) || + (frontBias > 1.0f && frontWheelIds[0] < axleDesc.nbWheels && frontWheelIds[1] < axleDesc.nbWheels), + "PxVehicleFourWheelDriveDifferentialParams:: frontBias is enabled but the frontWheelIds are not configured correctly.", false); + PX_CHECK_AND_RETURN_VAL((0.0f == frontBias) || + (frontBias > 1.0f && frontWheelIds[0] != frontWheelIds[1]), + "PxVehicleFourWheelDriveDifferentialParams:: frontBias is enabled but the frontWheelIds are not configured correctly.", false); + PX_CHECK_AND_RETURN_VAL((0.0f == frontBias) || + (frontBias > 1.0f && torqueRatios[frontWheelIds[0]] != 0.0f && frontWheelIds[frontWheelIds[1]]), + "PxVehicleFourWheelDriveDifferentialParams:: frontBias is enabled but the front wheels are not connected.", false); + + PX_CHECK_AND_RETURN_VAL(((0.0f == frontBias) && (0.0f == rearBias) && (0.0f == centerBias)) || (rate >= 0.0f), + "PxVehicleFourWheelDriveDifferentialParams:: strength must be greater than or equal to zero", false); + + PX_CHECK_AND_RETURN_VAL((0.0f == frontBias) || ((1.0f == frontTarget && 1.0f == rearTarget) || (frontTarget > 1.0f && frontTarget < frontBias)), + "PxVehicleFourWheelDriveDifferentialParams: frontBias is enabled but frontTarget not in range (1.0f, frontBias)", false); + PX_CHECK_AND_RETURN_VAL((0.0f == rearBias) || ((1.0f == rearTarget && 1.0f == rearBias) || (rearTarget > 1.0f && rearTarget < rearBias)), + "PxVehicleFourWheelDriveDifferentialParams: rearBias is enabled but rearTarget not in range (1.0f, rearBias)", false); + PX_CHECK_AND_RETURN_VAL((0.0f == centerBias) || ((1.0f == centerTarget && 1.0f == centerBias) || (centerTarget > 1.0f && centerTarget < centerBias)), + "PxVehicleFourWheelDriveDifferentialParams: centerBias is enabled but centerTarget not in range (1.0f, centerBias)", false); + + return true; + } + + PX_FORCE_INLINE PxVehicleFourWheelDriveDifferentialParams transformAndScale( + const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const + { + PX_UNUSED(srcFrame); + PX_UNUSED(trgFrame); + PX_UNUSED(srcScale); + PX_UNUSED(trgScale); + PxVehicleFourWheelDriveDifferentialParams r = *this; + static_cast(r) = PxVehicleMultiWheelDriveDifferentialParams::transformAndScale(srcFrame, trgFrame, srcScale, trgScale); + return r; + } +}; + +/** +\brief A description of a tank differential. +\note The wheels on a tank may be connected to the differential or not connected to the differential. +\note The wheels on a tank track may be connected to a tank track or not connected to a tank track. +\note Wheels connected to the differential but not to a tank track receive the torque split specified by the +corresponding elements of PxVehicleMultiWheelDriveDifferentialParams::torqueRatios[]. +\note Wheels connected to a tank track but not to the differential receive no torque from the engine. +\note Wheels connected to a tank track and to the differential receive the torque split specified by the +corresponding elements of PxVehicleMultiWheelDriveDifferentialParams::torqueRatios[] multiplied by the corresponding +thrust controller value. If the thrust controller has a negative value, the wheels will receive a torque that is negative +with respect to the gearing ratio. +\note The wheels in each tank track have a constraint applied to them to enforce the rule that they all have the same longitudinal speed +at the contact point between the wheel and the tank track. +*/ +struct PxVehicleTankDriveDifferentialParams : public PxVehicleMultiWheelDriveDifferentialParams +{ + PX_FORCE_INLINE void setToDefault() + { + PxVehicleMultiWheelDriveDifferentialParams::setToDefault(); + nbTracks = 0; + nbWheelsInTracks = 0; + } + + /** + \brief Add a tank track by specifying the number of wheels along the track track and an array of wheel ids specifying each wheel in the tank track. + \param[in] nbWheelsInTrackToAdd is the number of wheels in the track to be added. + \param[in] wheelIdsInTrackToAdd is an array of wheel ids specifying all the wheels in the track to be added. + \param[in] thrustControllerIndex specifies the index of the thrust controller that will be used to control the tank track. + */ + void addTankTrack(const PxU32 nbWheelsInTrackToAdd, const PxU32* const wheelIdsInTrackToAdd, const PxU32 thrustControllerIndex) + { + PX_ASSERT((nbWheelsInTracks + nbWheelsInTrackToAdd) < PxVehicleLimits::eMAX_NB_WHEELS); + PX_ASSERT(nbTracks < PxVehicleLimits::eMAX_NB_WHEELS); + PX_ASSERT(thrustControllerIndex < 2); + nbWheelsPerTrack[nbTracks] = nbWheelsInTrackToAdd; + thrustIdPerTrack[nbTracks] = thrustControllerIndex; + trackToWheelIds[nbTracks] = nbWheelsInTracks; + for (PxU32 i = 0; i < nbWheelsInTrackToAdd; i++) + { + wheelIdsInTrackOrder[nbWheelsInTracks + i] = wheelIdsInTrackToAdd[i]; + } + nbWheelsInTracks += nbWheelsInTrackToAdd; + nbTracks++; + } + + /** + \brief Return the number of tracks. + \return The number of tracks. + @see getNbWheelsInTrack() + */ + PX_FORCE_INLINE PxU32 getNbTracks() const + { + return nbTracks; + } + + /** + \brief Return the number of wheels in the ith track. + \param[in] i specifies the track to be queried for its wheel count. + \return The number of wheels in the specified track. + @see getWheelInTrack() + */ + PX_FORCE_INLINE PxU32 getNbWheelsInTrack(const PxU32 i) const + { + return nbWheelsPerTrack[i]; + } + + /** + \brief Return the array of all wheels in the ith track. + \param[in] i specifies the track to be queried for its wheels. + \return The array of wheels in the specified track. + */ + PX_FORCE_INLINE const PxU32* getWheelsInTrack(const PxU32 i) const + { + return (wheelIdsInTrackOrder + trackToWheelIds[i]); + } + + /** + \brief Return the wheel id of the jth wheel in the ith track. + \param[in] j specifies that the wheel id to be returned is the jth wheel in the list of wheels on the specified track. + \param[in] i specifies the track to be queried. + \return The wheel id of the jth wheel in the ith track. + @see getNbWheelsInTrack() + */ + PX_FORCE_INLINE PxU32 getWheelInTrack(const PxU32 j, const PxU32 i) const + { + return wheelIdsInTrackOrder[trackToWheelIds[i] + j]; + } + + /** + \brief Return the index of the thrust controller that will control a specified track. + \param[in] i specifies the track to be queried for its thrust controller index + \return The index of the thrust controller that will control the ith track. + */ + PX_FORCE_INLINE PxU32 getThrustControllerIndex(const PxU32 i) const + { + return thrustIdPerTrack[i]; + } + + PX_FORCE_INLINE PxVehicleTankDriveDifferentialParams transformAndScale( + const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const + { + PX_UNUSED(srcFrame); + PX_UNUSED(trgFrame); + PX_UNUSED(srcScale); + PX_UNUSED(trgScale); + PxVehicleTankDriveDifferentialParams r = *this; + static_cast(r) = PxVehicleMultiWheelDriveDifferentialParams::transformAndScale(srcFrame, trgFrame, srcScale, trgScale); + return r; + } + + PX_FORCE_INLINE bool isValid(const PxVehicleAxleDescription& axleDesc) const + { + if (!PxVehicleMultiWheelDriveDifferentialParams::isValid(axleDesc)) + return false; + + PX_CHECK_AND_RETURN_VAL(nbTracks <= PxVehicleLimits::eMAX_NB_WHEELS, "PxVehicleTankDriveDifferentialParams.nbTracks must not exceed PxVehicleLimits::eMAX_NB_WHEELS", false); + PX_CHECK_AND_RETURN_VAL(nbWheelsInTracks <= PxVehicleLimits::eMAX_NB_WHEELS, "PxVehicleTankDriveDifferentialParams.nbWheelsInTracks must not exceed PxVehicleLimits::eMAX_NB_WHEELS", false); + for (PxU32 i = 0; i < nbTracks; i++) + { + PX_CHECK_AND_RETURN_VAL(thrustIdPerTrack[i] < 2, "PxVehicleTankDriveDifferentialParams.thrustId must be less than 2", false); + PX_CHECK_AND_RETURN_VAL(getNbWheelsInTrack(i) >= 2, "PxVehicleTankDriveDifferentialParams.nbWheelsPerTrack must be greater than or equal to 2", false); + } + + for (PxU32 i = 0; i < axleDesc.nbWheels; i++) + { + const PxU32 wheelId = axleDesc.wheelIdsInAxleOrder[i]; + PxU32 count = 0; + for (PxU32 j = 0; j < nbWheelsInTracks; j++) + { + if (wheelIdsInTrackOrder[j] == wheelId) + count++; + } + PX_CHECK_AND_RETURN_VAL(count <= 1, "PxVehicleTankDriveDifferentialParams - a wheel cannot be in more than one tank track", false); + } + return true; + } + + PxU32 nbTracks; //!< The number of tracks + PxU32 thrustIdPerTrack[PxVehicleLimits::eMAX_NB_WHEELS]; //!< The id of the thrust that will control the track. Must have value 0 or 1. + PxU32 nbWheelsPerTrack[PxVehicleLimits::eMAX_NB_WHEELS]; //!< The number of wheels in each track + PxU32 trackToWheelIds[PxVehicleLimits::eMAX_NB_WHEELS]; //!< The list of wheel ids for the ith tank track begins at wheelIdsInTrackOrder[trackToWheelIds[i]] + + PxU32 wheelIdsInTrackOrder[PxVehicleLimits::eMAX_NB_WHEELS];//!< The list of all wheel ids in all tracks + PxU32 nbWheelsInTracks; //!< The number of wheels in all tracks. +}; + + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ + diff --git a/Source/ThirdParty/PhysX/vehicle2/drivetrain/PxVehicleDrivetrainStates.h b/Source/ThirdParty/PhysX/vehicle2/drivetrain/PxVehicleDrivetrainStates.h new file mode 100644 index 000000000..aacfc75e9 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/drivetrain/PxVehicleDrivetrainStates.h @@ -0,0 +1,288 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "vehicle2/commands/PxVehicleCommandStates.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + + +struct PxVehicleClutchCommandResponseState +{ + PxReal normalisedCommandResponse; + PxReal commandResponse; + + PX_FORCE_INLINE void setToDefault() + { + PxMemZero(this, sizeof(PxVehicleClutchCommandResponseState)); + } +}; + +struct PxVehicleEngineDriveThrottleCommandResponseState +{ + PxReal commandResponse; + + PX_FORCE_INLINE void setToDefault() + { + PxMemZero(this, sizeof(PxVehicleEngineDriveThrottleCommandResponseState)); + } +}; + +struct PxVehicleEngineState +{ + /** + \brief The rotation speed of the engine (radians per second). + + Unit: radians / time + */ + PxReal rotationSpeed; + + PX_FORCE_INLINE void setToDefault() + { + PxMemZero(this, sizeof(PxVehicleEngineState)); + } +}; + +#define PX_VEHICLE_NO_GEAR_SWITCH_PENDING -1.0f +#define PX_VEHICLE_GEAR_SWITCH_INITIATED -2.0f + +struct PxVehicleGearboxState +{ + /** + \brief Current gear + */ + PxU32 currentGear; + + /** + \brief Target gear (different from current gear if a gear change is underway) + */ + PxU32 targetGear; + + /** + \brief Reported time that has passed since gear change started. + + The special value PX_VEHICLE_NO_GEAR_SWITCH_PENDING denotes that there is currently + no gear change underway. + + If a gear switch was initiated, the special value PX_VEHICLE_GEAR_SWITCH_INITIATED + will be used temporarily but get translated to 0 in the gearbox update immediately. + This state might only get encountered, if the vehicle component update is split into + multiple sequences that do not run in one go. + + Unit: time + */ + PxReal gearSwitchTime; + + PX_FORCE_INLINE void setToDefault() + { + currentGear = 0; + targetGear = 0; + gearSwitchTime = PX_VEHICLE_NO_GEAR_SWITCH_PENDING; + } +}; + +#define PX_VEHICLE_UNSPECIFIED_TIME_SINCE_LAST_SHIFT PX_MAX_F32 + +struct PxVehicleAutoboxState +{ + /** + \brief Time that has lapsed since the last autobox gear shift. + + Unit: time + */ + PxReal timeSinceLastShift; + + /** + \brief Describes whether a gear shift triggered by the autobox is still in flight. + */ + bool activeAutoboxGearShift; + + PX_FORCE_INLINE void setToDefault() + { + timeSinceLastShift = PX_VEHICLE_UNSPECIFIED_TIME_SINCE_LAST_SHIFT; + activeAutoboxGearShift = false; + } +}; + +struct PxVehicleDifferentialState +{ + /** + \brief A list of wheel indices that are connected to the differential. + */ + PxU32 connectedWheels[PxVehicleLimits::eMAX_NB_WHEELS]; + + /** + \brief The number of wheels that are connected to the differential. + */ + PxU32 nbConnectedWheels; + + /** + \brief The fraction of available torque that is delivered to each wheel through the differential. + \note If a wheel is not connected to the differential then the fraction of available torque delivered to that wheel will be zero. + \note A negative torque ratio for a wheel indicates a negative gearing is to be applied to that wheel. + \note The sum of the absolute value of each fraction must equal 1.0. + */ + PxReal torqueRatiosAllWheels[PxVehicleLimits::eMAX_NB_WHEELS]; + + /** + \brief The contribution of each wheel to the average wheel rotation speed measured at the clutch. + \note If a wheel is not connected to the differential then the contribution to the average rotation speed measured at the clutch must be zero. + \note The sum of all contributions must equal 1.0. + */ + PxReal aveWheelSpeedContributionAllWheels[PxVehicleLimits::eMAX_NB_WHEELS]; + + PX_FORCE_INLINE void setToDefault() + { + PxMemZero(this, sizeof(PxVehicleDifferentialState)); + } +}; + +/** +\brief Specify groups of wheels that are to be constrained to have pre-determined angular velocity relationship. +*/ +struct PxVehicleWheelConstraintGroupState +{ + PX_FORCE_INLINE void setToDefault() + { + PxMemZero(this, sizeof(PxVehicleWheelConstraintGroupState)); + } + + /** + \brief Add a wheel constraint group by specifying the number of wheels in the group, an array of wheel ids specifying each wheel in the group + and a desired rotational speed relationship. + \param[in] nbWheelsInGroupToAdd is the number of wheels in the group to be added. + \param[in] wheelIdsInGroupToAdd is an array of wheel ids specifying all the wheels in the group to be added. + \param[in] constraintMultipliers is an array of constraint multipliers describing the desired relationship of the wheel rotational speeds. + \note constraintMultipliers[j] specifies the target rotational speed of the jth wheel in the constraint group as a multiplier of the rotational + speed of the zeroth wheel in the group. + */ + void addConstraintGroup(const PxU32 nbWheelsInGroupToAdd, const PxU32* const wheelIdsInGroupToAdd, const PxF32* constraintMultipliers) + { + PX_ASSERT((nbWheelsInGroups + nbWheelsInGroupToAdd) < PxVehicleLimits::eMAX_NB_WHEELS); + PX_ASSERT(nbGroups < PxVehicleLimits::eMAX_NB_WHEELS); + nbWheelsPerGroup[nbGroups] = nbWheelsInGroupToAdd; + groupToWheelIds[nbGroups] = nbWheelsInGroups; + for (PxU32 i = 0; i < nbWheelsInGroupToAdd; i++) + { + wheelIdsInGroupOrder[nbWheelsInGroups + i] = wheelIdsInGroupToAdd[i]; + wheelMultipliersInGroupOrder[nbWheelsInGroups + i] = constraintMultipliers[i]; + } + nbWheelsInGroups += nbWheelsInGroupToAdd; + nbGroups++; + } + + /** + \brief Return the number of wheel constraint groups in the vehicle. + \return The number of wheel constraint groups. + @see getNbWheelsInConstraintGroup() + */ + PX_FORCE_INLINE PxU32 getNbConstraintGroups() const + { + return nbGroups; + } + + /** + \brief Return the number of wheels in the ith constraint group. + \param[in] i specifies the constraint group to be queried for its wheel count. + \return The number of wheels in the specified constraint group. + @see getWheelInConstraintGroup() + */ + PX_FORCE_INLINE PxU32 getNbWheelsInConstraintGroup(const PxU32 i) const + { + return nbWheelsPerGroup[i]; + } + + /** + \brief Return the wheel id of the jth wheel in the ith constraint group. + \param[in] j specifies that the wheel id to be returned is the jth wheel in the list of wheels on the specified constraint group. + \param[in] i specifies the constraint group to be queried. + \return The wheel id of the jth wheel in the ith constraint group. + @see getNbWheelsInConstraintGroup() + */ + PX_FORCE_INLINE PxU32 getWheelInConstraintGroup(const PxU32 j, const PxU32 i) const + { + return wheelIdsInGroupOrder[groupToWheelIds[i] + j]; + } + + /** + \brief Return the constraint multiplier of the jth wheel in the ith constraint group + \param[in] j specifies that the wheel id to be returned is the jth wheel in the list of wheels on the specified constraint group. + \param[in] i specifies the constraint group to be queried. + \return The constraint multiplier of the jth wheel in the ith constraint group. + */ + PX_FORCE_INLINE PxReal getMultiplierInConstraintGroup(const PxU32 j, const PxU32 i) const + { + return wheelMultipliersInGroupOrder[groupToWheelIds[i] + j]; + } + + PxU32 nbGroups; //!< The number of constraint groups in the vehicle + PxU32 nbWheelsPerGroup[PxVehicleLimits::eMAX_NB_AXLES]; //!< The number of wheels in each group + PxU32 groupToWheelIds[PxVehicleLimits::eMAX_NB_AXLES]; //!< The list of wheel ids for the ith group begins at wheelIdsInGroupOrder[groupToWheelIds[i]] + + PxU32 wheelIdsInGroupOrder[PxVehicleLimits::eMAX_NB_WHEELS]; //!< The list of all wheel ids in constraint groups + PxF32 wheelMultipliersInGroupOrder[PxVehicleLimits::eMAX_NB_WHEELS];//!< The constraint multipliers for each constraint group. + PxU32 nbWheelsInGroups; //!< The number of wheels in a constraint group. +}; + +/** +\brief The clutch is modelled as two spinning plates with one connected to the wheels through the gearing and the other connected to the engine. The clutch slip is angular speed difference of the two plates. +*/ +struct PxVehicleClutchSlipState +{ + /** + \brief The slip at the clutch. + + Unit: radians / time + */ + PxReal clutchSlip; + + PX_FORCE_INLINE void setToDefault() + { + PxMemZero(this, sizeof(PxVehicleClutchSlipState)); + } +}; + + + + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/physxActor/PxVehiclePhysXActorComponents.h b/Source/ThirdParty/PhysX/vehicle2/physxActor/PxVehiclePhysXActorComponents.h new file mode 100644 index 000000000..f97c8f5b7 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/physxActor/PxVehiclePhysXActorComponents.h @@ -0,0 +1,238 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once +/** \addtogroup vehicle2 + @{ +*/ + +#include "vehicle2/PxVehicleParams.h" +#include "vehicle2/PxVehicleComponent.h" + +#include "vehicle2/wheel/PxVehicleWheelStates.h" + +#include "PxVehiclePhysXActorFunctions.h" +#include "PxVehiclePhysXActorStates.h" + +#include "common/PxProfileZone.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +/** +\brief Work items at the beginning of an update step for a PhysX actor based vehicle. + +Includes: + - Waking the actor up if it is sleeping and a throttle or steer command is issued. + - Clearing certain states if the actor is sleeping. + - Reading the state from the PhysX actor and copy to the vehicle internal state. + +@see PxVehiclePhysxActorWakeup PxVehiclePhysxActorSleepCheck PxVehicleReadRigidBodyStateFromPhysXActor +*/ +class PxVehiclePhysXActorBeginComponent : public PxVehicleComponent +{ +public: + + PxVehiclePhysXActorBeginComponent() : PxVehicleComponent() {} + virtual ~PxVehiclePhysXActorBeginComponent() {} + + /** + \brief Provide vehicle data items for this component. + + \param[out] axleDescription identifies the wheels on each axle. + \param[out] commands are the brake, throttle and steer values that will drive the vehicle. + \param[out] transmissionCommands are the target gear and clutch values that will control + the transmission. Can be set to NULL if the vehicle does not have a gearbox. If + specified, then gearParams and gearState has to be specifed too. + \param[out] gearParams The gearbox parameters. Can be set to NULL if the vehicle does + not have a gearbox and transmissionCommands is NULL. + \param[out] gearState The state of the gearbox. Can be set to NULL if the vehicle does + not have a gearbox and transmissionCommands is NULL. + \param[out] engineParams The engine parameters. Can be set to NULL if the vehicle does + not have an engine. Must be specified, if engineState is specified. + \param[out] physxActor is the PxRigidBody instance associated with the vehicle. + \param[out] physxSteerState is the previous state of the steer and is used to determine if the + steering wheel has changed by comparing with PxVehicleCommandState::steer. + \param[out] physxConstraints The state of the suspension limit and low speed tire constraints. + If the vehicle actor is sleeping and constraints are active, they will be + deactivated and marked as dirty. + \param[out] rigidBodyState is the state of the rigid body used by the Vehicle SDK. + \param[out] wheelRigidBody1dStates describes the angular speed of each wheel. + \param[out] engineState The engine state. Can be set to NULL if the vehicle does + not have an engine. If specified, then engineParams has to be specifed too. + */ + virtual void getDataForPhysXActorBeginComponent( + const PxVehicleAxleDescription*& axleDescription, + const PxVehicleCommandState*& commands, + const PxVehicleEngineDriveTransmissionCommandState*& transmissionCommands, + const PxVehicleGearboxParams*& gearParams, + const PxVehicleGearboxState*& gearState, + const PxVehicleEngineParams*& engineParams, + PxVehiclePhysXActor*& physxActor, + PxVehiclePhysXSteerState*& physxSteerState, + PxVehiclePhysXConstraints*& physxConstraints, + PxVehicleRigidBodyState*& rigidBodyState, + PxVehicleArrayData& wheelRigidBody1dStates, + PxVehicleEngineState*& engineState) = 0; + + virtual bool update(const PxReal dt, const PxVehicleSimulationContext& context) + { + PX_UNUSED(dt); + PX_UNUSED(context); + + PX_PROFILE_ZONE("PxVehiclePhysXActorBeginComponent::update", 0); + + const PxVehicleAxleDescription* axleDescription; + const PxVehicleCommandState* commands; + const PxVehicleEngineDriveTransmissionCommandState* transmissionCommands; + const PxVehicleGearboxParams* gearParams; + const PxVehicleGearboxState* gearState; + const PxVehicleEngineParams* engineParams; + PxVehiclePhysXActor* physxActor; + PxVehiclePhysXSteerState* physxSteerState; + PxVehiclePhysXConstraints* physxConstraints; + PxVehicleRigidBodyState* rigidBodyState; + PxVehicleArrayData wheelRigidBody1dStates; + PxVehicleEngineState* engineState; + + getDataForPhysXActorBeginComponent(axleDescription, commands, transmissionCommands, + gearParams, gearState, engineParams, + physxActor, physxSteerState, physxConstraints, + rigidBodyState, wheelRigidBody1dStates, engineState); + + if (physxActor->rigidBody->getScene()) // Considering case where actor is not in a scene and constraints get solved via immediate mode + { + PxVehiclePhysxActorWakeup(*commands, transmissionCommands, gearParams, gearState, + *physxActor->rigidBody, *physxSteerState); + + if (PxVehiclePhysxActorSleepCheck(*axleDescription, *physxActor->rigidBody, engineParams, + *rigidBodyState, *physxConstraints, wheelRigidBody1dStates, engineState)) + { + return false; + } + } + + PxVehicleReadRigidBodyStateFromPhysXActor(*physxActor->rigidBody, *rigidBodyState); + + return true; + } +}; + +/** +\brief Work items at the end of an update step for a PhysX actor based vehicle. + +Includes: + - Writing vehicle internal state to the PhysX actor. + - Keeping the vehicle awake if certain criteria are met. +*/ +class PxVehiclePhysXActorEndComponent : public PxVehicleComponent +{ +public: + + PxVehiclePhysXActorEndComponent() : PxVehicleComponent() {} + virtual ~PxVehiclePhysXActorEndComponent() {} + + /** + \brief Provide vehicle data items for this component. + + \param[out] axleDescription identifies the wheels on each axle. + \param[out] rigidBodyState is the state of the rigid body used by the Vehicle SDK. + \param[out] wheelParams describes the radius, mass etc. of the wheels. + \param[out] wheelShapeLocalPoses are the local poses in the wheel's frame to apply to the PxShape instances that represent the wheel + \param[out] wheelRigidBody1dStates describes the angular speed of the wheels. + \param[out] wheelLocalPoses describes the local poses of the wheels in the rigid body frame. + \param[out] gearState The gear state. Can be set to NULL if the vehicle does + not have gears. + \param[out] physxActor is the PxRigidBody instance associated with the vehicle. + */ + virtual void getDataForPhysXActorEndComponent( + const PxVehicleAxleDescription*& axleDescription, + const PxVehicleRigidBodyState*& rigidBodyState, + PxVehicleArrayData& wheelParams, + PxVehicleArrayData& wheelShapeLocalPoses, + PxVehicleArrayData& wheelRigidBody1dStates, + PxVehicleArrayData& wheelLocalPoses, + const PxVehicleGearboxState*& gearState, + PxVehiclePhysXActor*& physxActor) = 0; + + virtual bool update(const PxReal dt, const PxVehicleSimulationContext& context) + { + PX_UNUSED(dt); + + PX_PROFILE_ZONE("PxVehiclePhysXActorEndComponent::update", 0); + + const PxVehicleAxleDescription* axleDescription; + const PxVehicleRigidBodyState* rigidBodyState; + PxVehicleArrayData wheelParams; + PxVehicleArrayData wheelShapeLocalPoses; + PxVehicleArrayData wheelRigidBody1dStates; + PxVehicleArrayData wheelLocalPoses; + const PxVehicleGearboxState* gearState; + PxVehiclePhysXActor* physxActor; + + getDataForPhysXActorEndComponent(axleDescription, rigidBodyState, + wheelParams, wheelShapeLocalPoses, wheelRigidBody1dStates, wheelLocalPoses, gearState, + physxActor); + + for (PxU32 i = 0; i < axleDescription->nbWheels; i++) + { + const PxU32 wheelId = axleDescription->wheelIdsInAxleOrder[i]; + + PxVehicleWriteWheelLocalPoseToPhysXWheelShape(wheelLocalPoses[wheelId].localPose, wheelShapeLocalPoses[wheelId], + physxActor->wheelShapes[wheelId]); + } + + if (context.getType() == PxVehicleSimulationContextType::ePHYSX) + { + const PxVehiclePhysXSimulationContext& physxContext = static_cast(context); + + PxVehicleWriteRigidBodyStateToPhysXActor(physxContext.physxActorUpdateMode, *rigidBodyState, dt, *physxActor->rigidBody); + + PxVehiclePhysxActorKeepAwakeCheck(*axleDescription, wheelParams, wheelRigidBody1dStates, + physxContext.physxActorWakeCounterThreshold, physxContext.physxActorWakeCounterResetValue, gearState, + *physxActor->rigidBody); + } + else + { + PX_ALWAYS_ASSERT(); + } + + return true; + } +}; + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/physxActor/PxVehiclePhysXActorFunctions.h b/Source/ThirdParty/PhysX/vehicle2/physxActor/PxVehiclePhysXActorFunctions.h new file mode 100644 index 000000000..cd7072ef6 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/physxActor/PxVehiclePhysXActorFunctions.h @@ -0,0 +1,195 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "foundation/PxSimpleTypes.h" + +#include "vehicle2/PxVehicleParams.h" + +#if !PX_DOXYGEN +namespace physx +{ + +class PxRigidBody; +class PxShape; + +namespace vehicle2 +{ +#endif + +struct PxVehicleCommandState; +struct PxVehicleEngineDriveTransmissionCommandState; +struct PxVehicleEngineParams; +struct PxVehicleEngineState; +struct PxVehicleGearboxParams; +struct PxVehicleGearboxState; +struct PxVehicleRigidBodyState; +struct PxVehiclePhysXConstraints; +struct PxVehicleWheelLocalPose; +struct PxVehicleWheelParams; +struct PxVehicleWheelRigidBody1dState; +struct PxVehiclePhysXSteerState; + +/** +\brief Wake up the physx actor if the actor is asleep and the commands signal an intent to +change the state of the vehicle. +\param[in] commands are the brake, throttle and steer values that will drive the vehicle. +\param[in] transmissionCommands are the target gear and clutch values that will control + the transmission. If the target gear is different from the current gearbox + target gear, then the physx actor will get woken up. Can be set to NULL if the + vehicle does not have a gearbox or if this is not a desired behavior. If + specified, then gearParams and gearState has to be specifed too. +\param[in] gearParams The gearbox parameters. Can be set to NULL if the vehicle does + not have a gearbox and transmissionCommands is NULL. +\param[in] gearState The state of the gearbox. Can be set to NULL if the vehicle does + not have a gearbox and transmissionCommands is NULL. +\param[in] physxActor is the PxRigidBody instance associated with the vehicle. +\param[in,out] physxSteerState and commands are compared to +determine if the steering state has changed since the last call to PxVehiclePhysxActorWakeup(). +\note If the steering has changed, the actor will be woken up. +\note On exit from PxVehiclePhysxActorWakeup, physxSteerState.previousSteerCommand is assigned to the value +of commands.steer so that the steer state may be propagated to the subsequent call to PxVehiclePhysxActorWakeup(). +\note If physxSteerState.previousSteerCommand has value PX_VEHICLE_UNSPECIFIED_STEER_STATE, the steering state +is treated as though it has not changed. +*/ +void PxVehiclePhysxActorWakeup( + const PxVehicleCommandState& commands, + const PxVehicleEngineDriveTransmissionCommandState* transmissionCommands, + const PxVehicleGearboxParams* gearParams, + const PxVehicleGearboxState* gearState, + PxRigidBody& physxActor, + PxVehiclePhysXSteerState& physxSteerState); + +/** +\brief Check if the physx actor is sleeping and clear certain vehicle states if it is. + +\param[in] axleDescription identifies the wheels on each axle. +\param[in] physxActor is the PxRigidBody instance associated with the vehicle. +\param[in] engineParams The engine parameters. Can be set to NULL if the vehicle does + not have an engine. Must be specified, if engineState is specified. +\param[in,out] rigidBodyState is the state of the rigid body used by the Vehicle SDK. +\param[in,out] physxConstraints The state of the suspension limit and low speed tire constraints. + If the vehicle actor is sleeping and constraints are active, they will be + deactivated and marked as dirty. +\param[in,out] wheelRigidBody1dStates describes the angular speed of the wheels. +\param[out] engineState The engine state. Can be set to NULL if the vehicle does + not have an engine. If specified, then engineParams has to be specifed too. + The engine rotation speed will get set to the idle rotation speed if + the actor is sleeping. +\return True if the actor was sleeping, else false. +*/ +bool PxVehiclePhysxActorSleepCheck +(const PxVehicleAxleDescription& axleDescription, + const PxRigidBody& physxActor, + const PxVehicleEngineParams* engineParams, + PxVehicleRigidBodyState& rigidBodyState, + PxVehiclePhysXConstraints& physxConstraints, + PxVehicleArrayData& wheelRigidBody1dStates, + PxVehicleEngineState* engineState); + +/** +\brief Check if the physx actor has to be kept awake. + +Certain criteria should keep the vehicle physx actor awake, for example, if the +(mass normalized) rotational kinetic energy of the wheels is above a certain +threshold or if a gear change is pending. This method will reset the wake +counter of the physx actor to a specified value, if any of the mentioned +criterias are met. + +\note The physx actor's sleep threshold will be used as threshold to test against + for the energy criteria. + +\param[in] axleDescription identifies the wheels on each axle. +\param[in] wheelParams describes the radius, mass etc. of the wheels. +\param[in] wheelRigidBody1dStates describes the angular speed of the wheels. +\param[in] wakeCounterThreshold Once the wake counter of the physx actor falls + below this threshold, the method will start testing if the wake + counter needs to be reset. +\param[in] wakeCounterResetValue The value to set the physx actor wake counter + to, if any of the criteria to do so are met. +\param[in] gearState The gear state. Can be set to NULL if the vehicle does + not have gears or if the mentioned behavior is not desired. +\param[in] physxActor is the PxRigidBody instance associated with the vehicle. +*/ +void PxVehiclePhysxActorKeepAwakeCheck +(const PxVehicleAxleDescription& axleDescription, + const PxVehicleArrayData& wheelParams, + const PxVehicleArrayData& wheelRigidBody1dStates, + const PxReal wakeCounterThreshold, + const PxReal wakeCounterResetValue, + const PxVehicleGearboxState* gearState, + PxRigidBody& physxActor); + + +/** +\brief Read the rigid body state from a PhysX actor. +\param[in] physxActor is a reference to a PhysX actor. +\param[out] rigidBodyState is the state of the rigid body used by the Vehicle SDK. +*/ +void PxVehicleReadRigidBodyStateFromPhysXActor +(const PxRigidBody& physxActor, + PxVehicleRigidBodyState& rigidBodyState); + +/** +\brief Update the local pose of a PxShape that is associated with a wheel. +\param[in] wheelLocalPose describes the local pose of each wheel in the rigid body frame. +\param[in] wheelShapeLocalPose describes the local pose to apply to the PxShape instance in the wheel's frame. +\param[in] shape is the target PxShape. +*/ +void PxVehicleWriteWheelLocalPoseToPhysXWheelShape +(const PxTransform& wheelLocalPose, const PxTransform& wheelShapeLocalPose, PxShape* shape); + +/** +\brief Write the rigid body state to a PhysX actor. +\param[in] physxActorUpdateMode controls whether the PhysX actor is to be updated with +instantaneous velocity changes or with accumulated accelerations to be applied in +the next simulation step of the associated PxScene. +\param[in] rigidBodyState is the state of the rigid body. +\param[in] dt is the simulation time that has elapsed since the last call to +PxVehicleWriteRigidBodyStateToPhysXActor(). +\param[out] physXActor is a reference to the PhysX actor. +*/ +void PxVehicleWriteRigidBodyStateToPhysXActor +(const PxVehiclePhysXActorUpdateMode::Enum physxActorUpdateMode, + const PxVehicleRigidBodyState& rigidBodyState, + const PxReal dt, + PxRigidBody& physXActor); + + + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/physxActor/PxVehiclePhysXActorHelpers.h b/Source/ThirdParty/PhysX/vehicle2/physxActor/PxVehiclePhysXActorHelpers.h new file mode 100644 index 000000000..a4ee94df7 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/physxActor/PxVehiclePhysXActorHelpers.h @@ -0,0 +1,209 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "PxFiltering.h" +#include "PxShape.h" + +#if !PX_DOXYGEN +namespace physx +{ + +class PxGeometry; +class PxMaterial; +struct PxCookingParams; + +namespace vehicle2 +{ +#endif + +struct PxVehicleRigidBodyParams; +struct PxVehicleAxleDescription; +struct PxVehicleWheelParams; +struct PxVehiclePhysXActor; +struct PxVehicleFrame; +struct PxVehicleSuspensionParams; + +class PxVehiclePhysXRigidActorParams +{ + PX_NOCOPY(PxVehiclePhysXRigidActorParams) + +public: + + PxVehiclePhysXRigidActorParams(const PxVehicleRigidBodyParams& _physxActorRigidBodyParams, const char* _physxActorName) + : rigidBodyParams(_physxActorRigidBodyParams), + physxActorName(_physxActorName) + { + } + + const PxVehicleRigidBodyParams& rigidBodyParams; + const char* physxActorName; +}; + +class PxVehiclePhysXRigidActorShapeParams +{ + PX_NOCOPY(PxVehiclePhysXRigidActorShapeParams) + +public: + + PxVehiclePhysXRigidActorShapeParams + (const PxGeometry& _geometry, const PxTransform& _localPose, const PxMaterial& _material, + const PxShapeFlags _flags, const PxFilterData& _simulationFilterData, const PxFilterData& _queryFilterData) + : geometry(_geometry), + localPose(_localPose), + material(_material), + flags(_flags), + simulationFilterData(_simulationFilterData), + queryFilterData(_queryFilterData) + { + } + + const PxGeometry& geometry; + const PxTransform& localPose; + const PxMaterial& material; + PxShapeFlags flags; + PxFilterData simulationFilterData; + PxFilterData queryFilterData; +}; + +class PxVehiclePhysXWheelParams +{ + PX_NOCOPY(PxVehiclePhysXWheelParams) + +public: + + PxVehiclePhysXWheelParams(const PxVehicleAxleDescription& _axleDescription, const PxVehicleWheelParams* _wheelParams) + : axleDescription(_axleDescription), + wheelParams(_wheelParams) + { + } + + const PxVehicleAxleDescription& axleDescription; + const PxVehicleWheelParams* wheelParams; +}; + +class PxVehiclePhysXWheelShapeParams +{ + PX_NOCOPY(PxVehiclePhysXWheelShapeParams) + +public: + + PxVehiclePhysXWheelShapeParams(const PxMaterial& _material, const PxShapeFlags _flags, const PxFilterData _simulationFilterData, const PxFilterData _queryFilterData) + : material(_material), + flags(_flags), + simulationFilterData(_simulationFilterData), + queryFilterData(_queryFilterData) + { + } + + const PxMaterial& material; + PxShapeFlags flags; + PxFilterData simulationFilterData; + PxFilterData queryFilterData; +}; + +/** +\brief Create a PxRigidDynamic instance, instantiate it with desired properties and populate it with PxShape instances. +\param[in] vehicleFrame describes the frame of the vehicle. +\param[in] rigidActorParams describes the mass and moment of inertia of the rigid body. +\param[in] rigidActorCmassLocalPose specifies the mapping between actor and rigid body frame. +\param[in] rigidActorShapeParams describes the collision geometry associated with the rigid body. +\param[in] wheelParams describes the radius and half-width of the wheels. +\param[in] wheelShapeParams describes the PxMaterial and PxShapeFlags to apply to the wheel shapes. +\param[in] physics is a PxPhysics instance. +\param[in] params is a PxCookingParams instance +\param[in] vehiclePhysXActor is a record of the PxRigidDynamic and PxShape instances instantiated. +\note This is an alternative to PxVehiclePhysXArticulationLinkCreate. +\note PxVehiclePhysXActorCreate primarily serves as an illustration of the instantiation of the PhysX class instances +required to simulate a vehicle with a PxRigidDynamic. +@see PxVehiclePhysXActorDestroy +*/ +void PxVehiclePhysXActorCreate +(const PxVehicleFrame& vehicleFrame, + const PxVehiclePhysXRigidActorParams& rigidActorParams, const PxTransform& rigidActorCmassLocalPose, + const PxVehiclePhysXRigidActorShapeParams& rigidActorShapeParams, + const PxVehiclePhysXWheelParams& wheelParams, const PxVehiclePhysXWheelShapeParams& wheelShapeParams, + PxPhysics& physics, const PxCookingParams& params, + PxVehiclePhysXActor& vehiclePhysXActor); + + +/** +\brief Configure an actor so that it is ready for vehicle simulation. +\param[in] rigidActorParams describes the mass and moment of inertia of the rigid body. +\param[in] rigidActorCmassLocalPose specifies the mapping between actor and rigid body frame. +\param[out] rigidBody is the body to be prepared for simulation. +*/ +void PxVehiclePhysXActorConfigure +(const PxVehiclePhysXRigidActorParams& rigidActorParams, const PxTransform& rigidActorCmassLocalPose, + PxRigidBody& rigidBody); + +/** +\brief Create a PxArticulationReducedCoordinate and a single PxArticulationLink, +instantiate the PxArticulationLink with desired properties and populate it with PxShape instances. +\param[in] vehicleFrame describes the frame of the vehicle. +\param[in] rigidActorParams describes the mass and moment of inertia of the rigid body. +\param[in] rigidActorCmassLocalPose specifies the mapping between actor and rigid body frame. +\param[in] rigidActorShapeParams describes the collision geometry associated with the rigid body. +\param[in] wheelParams describes the radius and half-width of the wheels. +\param[in] wheelShapeParams describes the PxMaterial and PxShapeFlags to apply to the wheel shapes. +\param[in] physics is a PxPhysics instance. +\param[in] params is a PxCookingParams instance +\param[in] vehiclePhysXActor is a record of the PxArticulationReducedCoordinate, PxArticulationLink and PxShape instances instantiated. +\note This is an alternative to PxVehiclePhysXActorCreate. +\note PxVehiclePhysXArticulationLinkCreate primarily serves as an illustration of the instantiation of the PhysX class instances +required to simulate a vehicle as part of an articulated ensemble. +@see PxVehiclePhysXActorDestroy +*/ +void PxVehiclePhysXArticulationLinkCreate +(const PxVehicleFrame& vehicleFrame, + const PxVehiclePhysXRigidActorParams& rigidActorParams, const PxTransform& rigidActorCmassLocalPose, + const PxVehiclePhysXRigidActorShapeParams& rigidActorShapeParams, + const PxVehiclePhysXWheelParams& wheelParams, const PxVehiclePhysXWheelShapeParams& wheelShapeParams, + PxPhysics& physics, const PxCookingParams& params, + PxVehiclePhysXActor& vehiclePhysXActor); + +/** +\brief Release the PxRigidDynamic, PxArticulationReducedCoordinate, PxArticulationLink and PxShape instances +instantiated by PxVehiclePhysXActorCreate or PxVehiclePhysXArticulationLinkCreate. +\param[in] vehiclePhysXActor is a description of the PhysX instances to be released. +*/ +void PxVehiclePhysXActorDestroy(PxVehiclePhysXActor& vehiclePhysXActor); + + + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/physxActor/PxVehiclePhysXActorStates.h b/Source/ThirdParty/PhysX/vehicle2/physxActor/PxVehiclePhysXActorStates.h new file mode 100644 index 000000000..617649c36 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/physxActor/PxVehiclePhysXActorStates.h @@ -0,0 +1,98 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once +/** \addtogroup vehicle2 + @{ +*/ + +#include "foundation/PxPreprocessor.h" +#include "foundation/PxMemory.h" + +#include "PxRigidBody.h" + +#include "vehicle2/PxVehicleLimits.h" + +#if !PX_DOXYGEN +namespace physx +{ + +class PxShape; + +namespace vehicle2 +{ +#endif + +/** +\brief A description of the PhysX actor and shapes that represent the vehicle in an associated PxScene. +*/ +struct PxVehiclePhysXActor +{ + /** + \brief The PhysX rigid body that represents the vehcle in the associated PhysX scene. + \note PxActorFlag::eDISABLE_GRAVITY must be set true on the PxRigidBody + */ + PxRigidBody* rigidBody; + + /** + \brief An array of shapes with one shape pointer (or NULL) for each wheel. + */ + PxShape* wheelShapes[PxVehicleLimits::eMAX_NB_WHEELS]; + + PX_FORCE_INLINE void setToDefault() + { + PxMemZero(this, sizeof(PxVehiclePhysXActor)); + } +}; + + +#define PX_VEHICLE_UNSPECIFIED_STEER_STATE PX_MAX_F32 + +/** +\brief A description of the previous steer command applied to the vehicle. +*/ +struct PxVehiclePhysXSteerState +{ + + /** + \brief The steer command that was most previously applied to the vehicle. + */ + PxReal previousSteerCommand; + + PX_FORCE_INLINE void setToDefault() + { + previousSteerCommand = PX_VEHICLE_UNSPECIFIED_STEER_STATE; + } +}; + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/physxConstraints/PxVehiclePhysXConstraintComponents.h b/Source/ThirdParty/PhysX/vehicle2/physxConstraints/PxVehiclePhysXConstraintComponents.h new file mode 100644 index 000000000..a362e0839 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/physxConstraints/PxVehiclePhysXConstraintComponents.h @@ -0,0 +1,123 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "vehicle2/PxVehicleParams.h" +#include "vehicle2/PxVehicleComponent.h" + +#include "vehicle2/roadGeometry/PxVehicleRoadGeometryState.h" +#include "vehicle2/suspension/PxVehicleSuspensionParams.h" +#include "vehicle2/suspension/PxVehicleSuspensionStates.h" + +#include "PxVehiclePhysXConstraintFunctions.h" +#include "PxVehiclePhysXConstraintHelpers.h" +#include "PxVehiclePhysXConstraintStates.h" +#include "PxVehiclePhysXConstraintParams.h" + +#include "common/PxProfileZone.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +class PxVehiclePhysXConstraintComponent : public PxVehicleComponent +{ +public: + PxVehiclePhysXConstraintComponent() : PxVehicleComponent() {} + virtual ~PxVehiclePhysXConstraintComponent() {} + + virtual void getDataForPhysXConstraintComponent( + const PxVehicleAxleDescription*& axleDescription, + const PxVehicleRigidBodyState*& rigidBodyState, + PxVehicleArrayData& suspensionParams, + PxVehicleArrayData& suspensionLimitParams, + PxVehicleArrayData& suspensionStates, + PxVehicleArrayData& suspensionComplianceStates, + PxVehicleArrayData& wheelRoadGeomStates, + PxVehicleArrayData& tireDirectionStates, + PxVehicleArrayData& tireStickyStates, + PxVehiclePhysXConstraints*& constraints) = 0; + + virtual bool update(const PxReal dt, const PxVehicleSimulationContext& context) + { + PX_UNUSED(dt); + PX_UNUSED(context); + + PX_PROFILE_ZONE("PxVehiclePhysXConstraintComponent::update", 0); + + const PxVehicleAxleDescription* axleDescription; + const PxVehicleRigidBodyState* rigidBodyState; + PxVehicleArrayData suspensionParams; + PxVehicleArrayData suspensionLimitParams; + PxVehicleArrayData suspensionStates; + PxVehicleArrayData suspensionComplianceStates; + PxVehicleArrayData wheelRoadGeomStates; + PxVehicleArrayData tireDirectionStates; + PxVehicleArrayData tireStickyStates; + PxVehiclePhysXConstraints* constraints; + + getDataForPhysXConstraintComponent(axleDescription, rigidBodyState, + suspensionParams, suspensionLimitParams, suspensionStates, suspensionComplianceStates, + wheelRoadGeomStates, tireDirectionStates, tireStickyStates, + constraints); + + PxVehicleConstraintsDirtyStateUpdate(*constraints); + + for (PxU32 i = 0; i < axleDescription->nbWheels; i++) + { + const PxU32 wheelId = axleDescription->wheelIdsInAxleOrder[i]; + + PxVehiclePhysXConstraintStatesUpdate( + suspensionParams[wheelId], suspensionLimitParams[wheelId], + suspensionStates[wheelId], suspensionComplianceStates[wheelId], + wheelRoadGeomStates[wheelId].plane.n, + context.tireStickyParams.stickyParams[PxVehicleTireDirectionModes::eLONGITUDINAL].damping, + context.tireStickyParams.stickyParams[PxVehicleTireDirectionModes::eLATERAL].damping, + tireDirectionStates[wheelId], tireStickyStates[wheelId], + *rigidBodyState, + constraints->constraintStates[wheelId]); + } + + return true; + } +}; + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/physxConstraints/PxVehiclePhysXConstraintFunctions.h b/Source/ThirdParty/PhysX/vehicle2/physxConstraints/PxVehiclePhysXConstraintFunctions.h new file mode 100644 index 000000000..d1993ccfa --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/physxConstraints/PxVehiclePhysXConstraintFunctions.h @@ -0,0 +1,92 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "foundation/PxVec3.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +struct PxVehicleSuspensionParams; +struct PxVehiclePhysXSuspensionLimitConstraintParams; +struct PxVehicleSuspensionState; +struct PxVehicleSuspensionComplianceState; +struct PxVehicleTireDirectionState; +struct PxVehicleTireStickyState; +struct PxVehicleRigidBodyState; +struct PxVehiclePhysXConstraintState; + +/** +\brief Read constraint data from the vehicle's internal state for a single wheel and write it to a +structure that will be read by the associated PxScene and used to impose the constraints during the next +PxScene::simulate() step. +\param[in] suspensionParams describes the suspension frame. +\param[in] suspensionLimitParams describes the restitution value applied to any constraint triggered by +the suspension travel limit. +\param[in] suspensionState describes the excess suspension compression beyond the suspension travel limit that will be +resolved with a constraint. +\param[in] suspensionComplianceState describes the effect of suspension compliance on the effective application point +of the suspension force. +\param[in] groundPlaneNormal The normal direction of the ground plane the wheel is driving on. A normalized vector is + expected. +\param[in] tireStickyDampingLong The damping coefficient to use in the constraint to approach a zero target velocity + along the longitudinal tire axis. +\param[in] tireStickyDampingLat Same concept as tireStickyDampingLong but for the lateral tire axis. +\param[in] tireDirectionState describes the longitudinal and lateral directions of the tire in the world frame. +\param[in] tireStickyState describes the low speed state of the tire in the longitudinal and lateral directions. +\param[in] rigidBodyState describes the pose of the rigid body. +\param[out] constraintState is the data structure that will be read by the associated PxScene in the next call to +PxScene::simulate(). +\note Constraints include suspension constraints to account for suspension travel limit and sticky +tire constraints that bring the vehicle to rest at low longitudinal and lateral speed. +*/ +void PxVehiclePhysXConstraintStatesUpdate +(const PxVehicleSuspensionParams& suspensionParams, + const PxVehiclePhysXSuspensionLimitConstraintParams& suspensionLimitParams, + const PxVehicleSuspensionState& suspensionState, const PxVehicleSuspensionComplianceState& suspensionComplianceState, + const PxVec3& groundPlaneNormal, + const PxReal tireStickyDampingLong, const PxReal tireStickyDampingLat, + const PxVehicleTireDirectionState& tireDirectionState, const PxVehicleTireStickyState& tireStickyState, + const PxVehicleRigidBodyState& rigidBodyState, + PxVehiclePhysXConstraintState& constraintState); + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/physxConstraints/PxVehiclePhysXConstraintHelpers.h b/Source/ThirdParty/PhysX/vehicle2/physxConstraints/PxVehiclePhysXConstraintHelpers.h new file mode 100644 index 000000000..a42f126ad --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/physxConstraints/PxVehiclePhysXConstraintHelpers.h @@ -0,0 +1,92 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +#include "foundation/PxPreprocessor.h" + +/** \addtogroup vehicle2 + @{ +*/ + +#if !PX_DOXYGEN +namespace physx +{ + +class PxPhysics; +class PxRigidBody; + +namespace vehicle2 +{ +#endif + +struct PxVehicleAxleDescription; +struct PxVehiclePhysXConstraints; + +/** +\brief Instantiate the PhysX custom constraints. + +Custom constraints will resolve excess suspension compression and velocity constraints that serve as +a replacement low speed tire model. + +\param[in] axleDescription describes the axles of the vehicle and the wheels on each axle. +\param[in] physics is a PxPhysics instance. +\param[in] physxActor is the vehicle's PhysX representation as a PxRigidBody +\param[in] vehicleConstraints is a wrapper class that holds pointers to PhysX objects required to implement the custom constraint. +*/ +void PxVehicleConstraintsCreate +(const PxVehicleAxleDescription& axleDescription, + PxPhysics& physics, PxRigidBody& physxActor, + PxVehiclePhysXConstraints& vehicleConstraints); + +/** +\brief To ensure the constraints are processed by the PhysX scene they are marked as dirty prior to each simulate step. + +\param[in] vehicleConstraints is a wrapper class that holds pointers to PhysX objects required to implement the custom constraint. + +@see PxVehicleConstraintsCreate +*/ +void PxVehicleConstraintsDirtyStateUpdate +(PxVehiclePhysXConstraints& vehicleConstraints); + +/** +\brief Destroy the PhysX custom constraints. + +\param[in,out] vehicleConstraints describes the PhysX custom constraints to be released. + +@see PxVehicleConstraintsCreate +*/ +void PxVehicleConstraintsDestroy +(PxVehiclePhysXConstraints& vehicleConstraints); + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/physxConstraints/PxVehiclePhysXConstraintParams.h b/Source/ThirdParty/PhysX/vehicle2/physxConstraints/PxVehiclePhysXConstraintParams.h new file mode 100644 index 000000000..9da860729 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/physxConstraints/PxVehiclePhysXConstraintParams.h @@ -0,0 +1,110 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "foundation/PxFoundation.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +struct PxVehicleFrame; +struct PxVehicleScale; + +/** +\brief A description of the PhysX models employed to resolve suspension limit constraints. +@see PxVehiclePhysXConstraintState +*/ +struct PxVehiclePhysXSuspensionLimitConstraintParams +{ + /** + \brief restitution is used by the restitution model used to generate a target velocity when resolving suspension limit + constraints. + \note A value of 0.0 means that the restitution model is not employed. + \note Restitution has no effect if directionForSuspensionLimitConstraint has value Enum::eNONE. + @see Px1DConstraintFlag::eRESTITUTION + @see Px1DConstraint::RestitutionModifiers::restitution + */ + PxReal restitution; + + /** + \brief Set the direction to apply a constraint impulse when the suspension cannot place the wheel on the ground + and simultaneously respect the limits of suspension travel. The choices are to push along the ground normal to resolve the + geometric error or to push along the suspension direction. The former choice can be thought of as mimicing a force applied + by the tire's contact with the ground, while the latter can be thought of as mimicing a force arising from a suspension limit spring. + When the ground normal and the suspension direction are approximately aligned, both do an equivalent job of maintaining the wheel above + the ground. When the vehicle is on its side, eSUSPENSION does a better job of keeping the wheels above + the ground but comes at the cost of an unnaturally strong torque that can lead to unwanted self-righting behaviour. + eROAD_GEOMETRY_NORMAL is a good choice to avoid self-righting behaviour and still do a reasonable job at maintaining + the wheel above the ground in the event that the vehicle is tending towards a roll onto its side. + eNONE should be chosen if it is desired that no extra impulse is applied when the suspension alone cannot keep the wheels above + the ground plane. + */ + enum DirectionSpecifier + { + eSUSPENSION, + eROAD_GEOMETRY_NORMAL, + eNONE + }; + DirectionSpecifier directionForSuspensionLimitConstraint; + + PX_FORCE_INLINE PxVehiclePhysXSuspensionLimitConstraintParams transformAndScale( + const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const + { + PX_UNUSED(srcFrame); + PX_UNUSED(trgFrame); + PX_UNUSED(srcScale); + PX_UNUSED(trgScale); + return *this; + } + + PX_FORCE_INLINE bool isValid() const + { + PX_CHECK_AND_RETURN_VAL( + PxVehiclePhysXSuspensionLimitConstraintParams::eSUSPENSION == directionForSuspensionLimitConstraint || + PxVehiclePhysXSuspensionLimitConstraintParams::eROAD_GEOMETRY_NORMAL == directionForSuspensionLimitConstraint || + PxVehiclePhysXSuspensionLimitConstraintParams::eNONE == directionForSuspensionLimitConstraint, "PxVehiclePhysXSuspensionLimitConstraintParams.directionForSuspensionLimitConstraint must have legal value", false); + PX_CHECK_AND_RETURN_VAL(restitution >= 0.0f && restitution <= 1.0f, "PxVehiclePhysXSuspensionLimitConstraintParams.restitution must be in range [0, 1]", false); + return true; + } +}; + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/physxConstraints/PxVehiclePhysXConstraintStates.h b/Source/ThirdParty/PhysX/vehicle2/physxConstraints/PxVehiclePhysXConstraintStates.h new file mode 100644 index 000000000..ae312341e --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/physxConstraints/PxVehiclePhysXConstraintStates.h @@ -0,0 +1,357 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once +/** \addtogroup vehicle2 + @{ +*/ + +#include "foundation/PxAssert.h" +#include "foundation/PxTransform.h" +#include "extensions/PxConstraintExt.h" + +#include "vehicle2/PxVehicleLimits.h" +#include "vehicle2/tire/PxVehicleTireStates.h" + +#include "PxConstraint.h" +#include "PxConstraintDesc.h" + +#if !PX_DOXYGEN +namespace physx +{ + +class PxConstraint; + +namespace vehicle2 +{ +#endif + + +/** +\brief A description of the number of PxConstraintConnector instances per vehicle required to maintain suspension limit +and sticky tire instances. +*/ +struct PxVehiclePhysXConstraintLimits +{ + enum Enum + { + eNB_DOFS_PER_PXCONSTRAINT = 12, + eNB_DOFS_PER_WHEEL = 3, + eNB_WHEELS_PER_PXCONSTRAINT = eNB_DOFS_PER_PXCONSTRAINT / eNB_DOFS_PER_WHEEL, + eNB_CONSTRAINTS_PER_VEHICLE = (PxVehicleLimits::eMAX_NB_WHEELS + (eNB_WHEELS_PER_PXCONSTRAINT - 1)) / (eNB_WHEELS_PER_PXCONSTRAINT) + }; +}; + +/** +\brief PxVehiclePhysXConstraintState is a data structure used to write +constraint data to the internal state of the associated PxScene. +@see Px1dConstraint +*/ +struct PxVehiclePhysXConstraintState +{ + /** + \brief a boolean describing whether to trigger a low speed constraint along the tire longitudinal and lateral directions. + */ + bool tireActiveStatus[PxVehicleTireDirectionModes::eMAX_NB_PLANAR_DIRECTIONS]; + /** + \brief linear component of velocity jacobian in world space for the tire's longitudinal and lateral directions. + */ + PxVec3 tireLinears[PxVehicleTireDirectionModes::eMAX_NB_PLANAR_DIRECTIONS]; + /** + \brief angular component of velocity jacobian in world space for the tire's longitudinal and lateral directions. + */ + PxVec3 tireAngulars[PxVehicleTireDirectionModes::eMAX_NB_PLANAR_DIRECTIONS]; + /** + \brief damping coefficient applied to the tire's longitudinal and lateral velocities. + + The constraint sets a target velocity of 0 and the damping coefficient will impact the size of the + impulse applied to reach the target. Since damping acts as a stiffness with respect to the velocity, + too large a value can cause instabilities. + */ + PxReal tireDamping[PxVehicleTireDirectionModes::eMAX_NB_PLANAR_DIRECTIONS]; + + + /** + \brief a boolean describing whether to trigger a suspension limit constraint. + */ + bool suspActiveStatus; + /** + \brief linear component of velocity jacobian in the world frame. + */ + PxVec3 suspLinear; + /** + \brief angular component of velocity jacobian in the world frame. + */ + PxVec3 suspAngular; + /** + \brief the excess suspension compression to be resolved by the constraint that cannot be resolved due to the travel limit + of the suspension spring. + + \note The expected error value is the excess suspension compression projected onto the ground plane normal and should have + a negative sign. + */ + PxReal suspGeometricError; + /** + \brief restitution value of the restitution model used to generate a target velocity that will resolve the geometric error. + \note A value of 0.0 means that the restitution model is not employed. + @see Px1DConstraintFlag::eRESTITUTION + @see Px1DConstraint::RestitutionModifiers::restitution + */ + PxReal restitution; + + PX_FORCE_INLINE void setToDefault() + { + PxMemZero(this, sizeof(PxVehiclePhysXConstraintState)); + } +}; + +//TAG:solverprepshader +PX_FORCE_INLINE PxU32 vehicleConstraintSolverPrep +(Px1DConstraint* constraints, + PxVec3p& body0WorldOffset, + PxU32 maxConstraints, + PxConstraintInvMassScale&, + const void* constantBlock, + const PxTransform& bodyAToWorld, + const PxTransform& bodyBToWorld, + bool, + PxVec3p& cA2w, PxVec3p& cB2w) +{ + PX_UNUSED(maxConstraints); + PX_UNUSED(body0WorldOffset); + PX_UNUSED(bodyBToWorld); + PX_ASSERT(bodyAToWorld.isValid()); PX_ASSERT(bodyBToWorld.isValid()); + + const PxVehiclePhysXConstraintState* data = static_cast(constantBlock); + PxU32 numActive = 0; + + //KS - the TGS solver will use raXn to try to add to the angular part of the linear constraints. + //We overcome this by setting the ra and rb offsets to be 0. + cA2w = bodyAToWorld.p; + cB2w = bodyBToWorld.p; + // note: this is only needed for PxSolverType::eTGS and even then it should not have an effect as + // long as a constraint raises Px1DConstraintFlag::eANGULAR_CONSTRAINT + + //Susp limit constraints. + for (PxU32 i = 0; i < PxVehiclePhysXConstraintLimits::eNB_WHEELS_PER_PXCONSTRAINT; i++) + { + if (data[i].suspActiveStatus) + { + // Going beyond max suspension compression should be treated similar to rigid body contacts. + // Thus setting up constraints that try to emulate such contacts. + // + // linear l = contact normal = n + // angular a = suspension force application offset x contact normal = cross(r, n) + // + // velocity at contact: + // vl: part from linear vehicle velocity v + // vl = dot(n, v) = dot(l, v) + // + // va: part from angular vehicle velocity w + // va = dot(n, cross(w, r)) = dot(w, cross(r, n)) = dot(w, a) + // + // ve: part from excess suspension compression + // ve = (geomError / dt) (note: geomError is expected to be negative here) + // + // velocity target vt = vl + va + ve + // => should become 0 by applying positive impulse along l. If vt is positive, + // nothing will happen as a negative impulse would have to be applied (but + // min impulse is set to 0). If vt is negative, a positive impulse will get + // applied to push vt towards 0. + // + + Px1DConstraint& p = constraints[numActive]; + p.linear0 = data[i].suspLinear; + p.angular0 = data[i].suspAngular; + p.geometricError = data[i].suspGeometricError; + p.linear1 = PxVec3(0); + p.angular1 = PxVec3(0); + p.minImpulse = 0; + p.maxImpulse = FLT_MAX; + p.velocityTarget = 0; + p.solveHint = PxConstraintSolveHint::eINEQUALITY; + + // note: this is only needed for PxSolverType::eTGS to not have the angular part + // be modified based on the linear part during substeps. Basically, it will + // disable the constraint re-projection etc. to emulate PxSolverType::ePGS. + p.flags |= Px1DConstraintFlag::eANGULAR_CONSTRAINT; + + if (data[i].restitution > 0.0f) + { + p.flags |= Px1DConstraintFlag::eRESTITUTION; + p.mods.bounce.restitution = data[i].restitution; + p.mods.bounce.velocityThreshold = -FLT_MAX; + } + numActive++; + } + } + + //Sticky tire friction constraints. + for (PxU32 i = 0; i < PxVehiclePhysXConstraintLimits::eNB_WHEELS_PER_PXCONSTRAINT; i++) + { + if (data[i].tireActiveStatus[PxVehicleTireDirectionModes::eLONGITUDINAL]) + { + Px1DConstraint& p = constraints[numActive]; + p.linear0 = data[i].tireLinears[PxVehicleTireDirectionModes::eLONGITUDINAL]; + p.angular0 = data[i].tireAngulars[PxVehicleTireDirectionModes::eLONGITUDINAL]; + p.geometricError = 0.0f; + p.linear1 = PxVec3(0); + p.angular1 = PxVec3(0); + p.minImpulse = -FLT_MAX; + p.maxImpulse = FLT_MAX; + p.velocityTarget = 0.0f; + p.mods.spring.damping = data[i].tireDamping[PxVehicleTireDirectionModes::eLONGITUDINAL]; + // note: no stiffness specified as this will have no effect with geometricError=0 + p.flags = Px1DConstraintFlag::eSPRING | Px1DConstraintFlag::eACCELERATION_SPRING; + p.flags |= Px1DConstraintFlag::eANGULAR_CONSTRAINT; // see explanation of same flag usage further above + numActive++; + } + } + + //Sticky tire friction constraints. + for (PxU32 i = 0; i < PxVehiclePhysXConstraintLimits::eNB_WHEELS_PER_PXCONSTRAINT; i++) + { + if (data[i].tireActiveStatus[PxVehicleTireDirectionModes::eLATERAL]) + { + Px1DConstraint& p = constraints[numActive]; + p.linear0 = data[i].tireLinears[PxVehicleTireDirectionModes::eLATERAL]; + p.angular0 = data[i].tireAngulars[PxVehicleTireDirectionModes::eLATERAL]; + p.geometricError = 0.0f; + p.linear1 = PxVec3(0); + p.angular1 = PxVec3(0); + p.minImpulse = -FLT_MAX; + p.maxImpulse = FLT_MAX; + p.velocityTarget = 0.0f; + p.mods.spring.damping = data[i].tireDamping[PxVehicleTireDirectionModes::eLATERAL]; + // note: no stiffness specified as this will have no effect with geometricError=0 + p.flags = Px1DConstraintFlag::eSPRING | Px1DConstraintFlag::eACCELERATION_SPRING; + p.flags |= Px1DConstraintFlag::eANGULAR_CONSTRAINT; // see explanation of same flag usage further above + numActive++; + } + } + + return numActive; +} + +PX_FORCE_INLINE void visualiseVehicleConstraint +(PxConstraintVisualizer &viz, + const void* constantBlock, + const PxTransform& body0Transform, + const PxTransform& body1Transform, + PxU32 flags) +{ + PX_UNUSED(&viz); + PX_UNUSED(constantBlock); + PX_UNUSED(body0Transform); + PX_UNUSED(body1Transform); + PX_UNUSED(flags); + PX_ASSERT(body0Transform.isValid()); + PX_ASSERT(body1Transform.isValid()); +} + +class PxVehicleConstraintConnector : public PxConstraintConnector +{ +public: + + PxVehicleConstraintConnector() : mVehicleConstraintState(NULL) {} + PxVehicleConstraintConnector(PxVehiclePhysXConstraintState* vehicleConstraintState) : mVehicleConstraintState(vehicleConstraintState) {} + ~PxVehicleConstraintConnector() {} + + void setConstraintState(PxVehiclePhysXConstraintState* constraintState) { mVehicleConstraintState = constraintState; } + + virtual void* prepareData() { return mVehicleConstraintState; } + virtual const void* getConstantBlock() const { return mVehicleConstraintState; } + virtual PxConstraintSolverPrep getPrep() const { return vehicleConstraintSolverPrep; } + + //Is this necessary if physx no longer supports double-buffering? + virtual void onConstraintRelease() { } + + //Can be empty functions. + virtual bool updatePvdProperties(physx::pvdsdk::PvdDataStream& pvdConnection, const PxConstraint* c, PxPvdUpdateType::Enum updateType) const + { + PX_UNUSED(pvdConnection); + PX_UNUSED(c); + PX_UNUSED(updateType); + return true; + } + virtual void updateOmniPvdProperties() const { } + virtual void onComShift(PxU32 actor) { PX_UNUSED(actor); } + virtual void onOriginShift(const PxVec3& shift) { PX_UNUSED(shift); } + virtual void* getExternalReference(PxU32& typeID) { typeID = PxConstraintExtIDs::eVEHICLE_JOINT; return this; } + virtual PxBase* getSerializable() { return NULL; } + +private: + + PxVehiclePhysXConstraintState* mVehicleConstraintState; +}; + +/** +\brief A mapping between constraint state data and the associated PxConstraint instances. +*/ +struct PxVehiclePhysXConstraints +{ + /** + \brief PxVehiclePhysXConstraintComponent writes to the constraintStates array and a + callback invoked by PxScene::simulate() reads a portion from it for a block of wheels + and writes that portion to an associated PxConstraint instance. + */ + PxVehiclePhysXConstraintState constraintStates[PxVehicleLimits::eMAX_NB_WHEELS]; + + /** + \brief PxVehiclePhysXConstraintComponent writes to the constraintStates array and a + callback invoked by PxScene::simulate() reads a portion from it for a block of wheels + and writes that portion to an associated PxConstraint instance. + */ + PxConstraint* constraints[PxVehiclePhysXConstraintLimits::eNB_CONSTRAINTS_PER_VEHICLE]; + + /** + \brief A constraint connector is necessary to connect each PxConstraint to a portion of the constraintStates array. + */ + PxVehicleConstraintConnector* constraintConnectors[PxVehiclePhysXConstraintLimits::eNB_CONSTRAINTS_PER_VEHICLE]; + + PX_FORCE_INLINE void setToDefault() + { + for (PxU32 i = 0; i < PxVehicleLimits::eMAX_NB_WHEELS; i++) + { + constraintStates[i].setToDefault(); + } + for(PxU32 i = 0; i < PxVehiclePhysXConstraintLimits::eNB_CONSTRAINTS_PER_VEHICLE; i++) + { + constraints[i] = NULL; + constraintConnectors[i] = NULL; + } + } +}; + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ + diff --git a/Source/ThirdParty/PhysX/vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryComponents.h b/Source/ThirdParty/PhysX/vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryComponents.h new file mode 100644 index 000000000..b422aea85 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryComponents.h @@ -0,0 +1,145 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once +/** \addtogroup vehicle2 + @{ +*/ + +#include "vehicle2/PxVehicleParams.h" +#include "vehicle2/PxVehicleComponent.h" + +#include "vehicle2/commands/PxVehicleCommandHelpers.h" +#include "vehicle2/roadGeometry/PxVehicleRoadGeometryState.h" +#include "vehicle2/suspension/PxVehicleSuspensionParams.h" +#include "vehicle2/wheel/PxVehicleWheelParams.h" + +#include "vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryFunctions.h" +#include "vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryParams.h" +#include "vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryState.h" + +#include "common/PxProfileZone.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +class PxVehiclePhysXRoadGeometrySceneQueryComponent : public PxVehicleComponent +{ +public: + PxVehiclePhysXRoadGeometrySceneQueryComponent() : PxVehicleComponent() {} + virtual ~PxVehiclePhysXRoadGeometrySceneQueryComponent() {} + + /** + \brief Provide vehicle data items for this component. + + \param[out] axleDescription identifies the wheels on each axle. + \param[out] roadGeomParams The road geometry parameters of the vehicle. + \param[out] steerResponseStates The steer response state of the wheels. + \param[out] rigidBodyState The pose, velocity etc. of the vehicle rigid body. + \param[out] wheelParams The wheel parameters for the wheels. + \param[out] suspensionParams The suspension parameters for the wheels. + \param[out] materialFrictionParams The tire friction tables for the wheels. + \param[out] roadGeometryStates The detected ground surface plane, friction value etc. for the wheels. + \param[out] physxRoadGeometryStates Optional buffer to store additional information about the query (like actor/shape that got hit etc.). + Set to empty if not desired. + */ + virtual void getDataForPhysXRoadGeometrySceneQueryComponent( + const PxVehicleAxleDescription*& axleDescription, + const PxVehiclePhysXRoadGeometryQueryParams*& roadGeomParams, + PxVehicleArrayData& steerResponseStates, + const PxVehicleRigidBodyState*& rigidBodyState, + PxVehicleArrayData& wheelParams, + PxVehicleArrayData& suspensionParams, + PxVehicleArrayData& materialFrictionParams, + PxVehicleArrayData& roadGeometryStates, + PxVehicleArrayData& physxRoadGeometryStates) = 0; + + virtual bool update(const PxReal dt, const PxVehicleSimulationContext& context) + { + PX_UNUSED(dt); + + PX_PROFILE_ZONE("PxVehiclePhysXRoadGeometrySceneQueryComponent::update", 0); + + const PxVehicleAxleDescription* axleDescription; + const PxVehiclePhysXRoadGeometryQueryParams* roadGeomParams; + PxVehicleArrayData steerResponseStates; + const PxVehicleRigidBodyState* rigidBodyState; + PxVehicleArrayData wheelParams; + PxVehicleArrayData suspensionParams; + PxVehicleArrayData materialFrictionParams; + PxVehicleArrayData roadGeometryStates; + PxVehicleArrayData physxRoadGeometryStates; + + getDataForPhysXRoadGeometrySceneQueryComponent(axleDescription, + roadGeomParams, steerResponseStates, rigidBodyState, + wheelParams, suspensionParams, materialFrictionParams, + roadGeometryStates, physxRoadGeometryStates); + + if (context.getType() == PxVehicleSimulationContextType::ePHYSX) + { + const PxVehiclePhysXSimulationContext& physxContext = static_cast(context); + + for(PxU32 i = 0; i < axleDescription->nbWheels; i++) + { + const PxU32 wheelId = axleDescription->wheelIdsInAxleOrder[i]; + + PxVehiclePhysXRoadGeometryQueryUpdate( + wheelParams[wheelId], suspensionParams[wheelId], + *roadGeomParams, materialFrictionParams[wheelId], + steerResponseStates[wheelId], *rigidBodyState, + *physxContext.physxScene, physxContext.physxUnitCylinderSweepMesh, context.frame, + roadGeometryStates[wheelId], + !physxRoadGeometryStates.isEmpty() ? &physxRoadGeometryStates[wheelId] : NULL); + } + } + else + { + PX_ALWAYS_ASSERT(); + + for(PxU32 i = 0; i < axleDescription->nbWheels; i++) + { + const PxU32 wheelId = axleDescription->wheelIdsInAxleOrder[i]; + + roadGeometryStates[wheelId].setToDefault(); + } + } + + return true; + } +}; + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryFunctions.h b/Source/ThirdParty/PhysX/vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryFunctions.h new file mode 100644 index 000000000..20ddaf685 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryFunctions.h @@ -0,0 +1,90 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "foundation/PxSimpleTypes.h" + +#if !PX_DOXYGEN +namespace physx +{ +class PxScene; +class PxConvexMesh; + +namespace vehicle2 +{ +#endif + +struct PxVehicleWheelParams; +struct PxVehicleSuspensionParams; +struct PxVehiclePhysXRoadGeometryQueryParams; +struct PxVehiclePhysXRoadGeometryQueryState; +struct PxVehiclePhysXMaterialFrictionParams; +struct PxVehicleRigidBodyState; +struct PxVehicleFrame; +struct PxVehicleRoadGeometryState; + +/** +\brief Compute the plane of the road geometry under a wheel and the tire friction of the contact. +\param[in] wheelParams describes the radius and halfwidth of the wheel. +\param[in] suspParams describes the frame of the suspension and wheel and the maximum suspension travel. +\param[in] roadGeomParams describes the operation of the PhysX scene query. +\param[in] materialFrictionParams describes a mapping between PxMaterial and friction in order to compute a tire friction value. +\param[in] wheelYawAngle is the yaw angle (in radians) of the wheel. +\param[in] rigidBodyState describes the pose of the rigid body. +\param[in] scene is the PhysX scene that will be queried by the scene query. +\param[in] unitCylinderSweepMesh is a convex cylindrical mesh of unit radius and half-width to be used in +the event that a sweep query is to be used. +\param[in] frame describes the lateral, longitudinal and vertical axes and is used to scale unitCylinderSweepMesh +by the wheel's radius and half-width. +\param[out] roadGeomState contains the plane and friction of the road geometry under the wheel. +\param[out] physxRoadGeometryState Optional buffer to store additional information about the query (like actor/shape that got hit etc.). + Set to NULL if not needed. +\note PxVehicleRoadGeometryState::hitState will have value false in the event that the there is no reachable road geometry under the wheel and +true if there is reachable road geometry under the wheel. Road geometry is considered reachable if the suspension can elongate from its +reference pose far enough to place wheel on the ground. +*/ +void PxVehiclePhysXRoadGeometryQueryUpdate +(const PxVehicleWheelParams& wheelParams, const PxVehicleSuspensionParams& suspParams, + const PxVehiclePhysXRoadGeometryQueryParams& roadGeomParams, const PxVehiclePhysXMaterialFrictionParams& materialFrictionParams, + const PxReal wheelYawAngle, const PxVehicleRigidBodyState& rigidBodyState, + const PxScene& scene, const PxConvexMesh* unitCylinderSweepMesh, + const PxVehicleFrame& frame, + PxVehicleRoadGeometryState& roadGeomState, + PxVehiclePhysXRoadGeometryQueryState* physxRoadGeometryState); + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryHelpers.h b/Source/ThirdParty/PhysX/vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryHelpers.h new file mode 100644 index 000000000..4dbe39d43 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryHelpers.h @@ -0,0 +1,73 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "foundation/PxPreprocessor.h" + +#if !PX_DOXYGEN +namespace physx +{ + +class PxConvexMesh; +class PxPhysics; +struct PxCookingParams; + +namespace vehicle2 +{ +#endif + +struct PxVehicleFrame; + +/** +\brief Create a cylindrical mesh with unit radius and half-width. +\param[in] vehicleFrame is a description of the lateral and longitudinal axes. +\param[in] physics is a PxPhysics instance. +\param[in] params is a PxCookingParams instance +\return Return a PxConvexMesh instance that represents a convex hull with unit radius and half-width. +@see PxVehicleUnitCylinderSweepMeshDestroy +*/ +PxConvexMesh* PxVehicleUnitCylinderSweepMeshCreate(const PxVehicleFrame& vehicleFrame, PxPhysics& physics, const PxCookingParams& params); + +/** +\brief Release the mesh created with PxVehicleUnitCylinderSweepMeshCreate. +\param[in] mesh is a PxConvexMesh instance. +@see PxVehicleUnitCylinderSweepMeshCreate +*/ +void PxVehicleUnitCylinderSweepMeshDestroy(PxConvexMesh* mesh); + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryParams.h b/Source/ThirdParty/PhysX/vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryParams.h new file mode 100644 index 000000000..896204c5d --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryParams.h @@ -0,0 +1,164 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "foundation/PxFoundation.h" + +#include "PxQueryFiltering.h" + +#if !PX_DOXYGEN +namespace physx +{ +class PxMaterial; + +namespace vehicle2 +{ +#endif + +struct PxVehicleFrame; +struct PxVehicleScale; + +/** +\brief PhysX scene queries may be raycasts or sweeps. +\note eNONE will result in no PhysX scene query. This option will not overwrite the associated PxVehicleRoadGeometryState. +*/ +struct PxVehiclePhysXRoadGeometryQueryType +{ + enum Enum + { + eNONE = 0, //!< Info about the road geometry below the wheel is provided by the user + eRAYCAST, //!< The road geometry below the wheel is analyzed using a raycast query + eSWEEP, //!< The road geometry below the wheel is analyzed using a sweep query + eMAX_NB + }; +}; + +/** +\brief A description of type of PhysX scene query and the filter data to apply to the query. +*/ +struct PxVehiclePhysXRoadGeometryQueryParams +{ + /** + \brief A description of the type of physx scene query to employ. + @see PxSceneQuerySystemBase::raycast + @see PxSceneQuerySystemBase::sweep + */ + PxVehiclePhysXRoadGeometryQueryType::Enum roadGeometryQueryType; + + /** + \brief The filter data to use for the physx scene query. + @see PxSceneQuerySystemBase::raycast + @see PxSceneQuerySystemBase::sweep + */ + PxQueryFilterData filterData; + + /** + \brief A filter callback to be used by the physx scene query + \note A null pointer is allowed. + @see PxSceneQuerySystemBase::raycast + @see PxSceneQuerySystemBase::sweep + */ + PxQueryFilterCallback* filterCallback; + + PX_FORCE_INLINE PxVehiclePhysXRoadGeometryQueryParams transformAndScale( + const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const + { + PX_UNUSED(srcFrame); + PX_UNUSED(trgFrame); + PX_UNUSED(srcScale); + PX_UNUSED(trgScale); + return *this; + } + + PX_FORCE_INLINE bool isValid() const + { + PX_CHECK_AND_RETURN_VAL(roadGeometryQueryType < PxVehiclePhysXRoadGeometryQueryType::eMAX_NB, "PxVehiclePhysXRoadGeometryQueryParams.roadGeometryQueryType has illegal value", false); + return true; + } +}; + +/** +A mapping between PxMaterial and a friction value to be used by the tire model. +@see PxVehiclePhysXMaterialFrictionParams +*/ +struct PxVehiclePhysXMaterialFriction +{ + /** + \brief A PxMaterial instance that is to be mapped to a friction value. + */ + const PxMaterial* material; + + /** + \brief A friction value that is to be mapped to a PxMaterial instance. + \note friction must have value greater than or equal to zero. + + Range: [0, inf)
+ + @see PxVehicleTireGripState::friction + */ + PxReal friction; + + PX_FORCE_INLINE bool isValid() const + { + PX_CHECK_AND_RETURN_VAL(friction >= 0.0f, "PxVehiclePhysXMaterialFriction.friction must be greater than or equal to zero", false); + return true; + } +}; + +/** +\brief A mappping between PxMaterial instance and friction for multiple PxMaterial intances. +*/ +struct PxVehiclePhysXMaterialFrictionParams +{ + PxVehiclePhysXMaterialFriction* materialFrictions; //!< An array of mappings between PxMaterial and friction. + PxU32 nbMaterialFrictions; //!< The number of mappings between PxMaterial and friction. + PxReal defaultFriction; //!< A default friction value to be used in the event that the PxMaterial under the tire is not found in the array #materialFrictions. + + PX_FORCE_INLINE bool isValid() const + { + for (PxU32 i = 0; i < nbMaterialFrictions; i++) + { + if (!materialFrictions[i].isValid()) + return false; + } + PX_CHECK_AND_RETURN_VAL(defaultFriction >= 0.0f, "PxVehiclePhysXMaterialFrictionParams.defaultFriction must be greater than or equal to zero", false); + return true; + } +}; + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryState.h b/Source/ThirdParty/PhysX/vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryState.h new file mode 100644 index 000000000..28ef45fbf --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryState.h @@ -0,0 +1,69 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "foundation/PxMemory.h" +#include "foundation/PxVec3.h" + +#if !PX_DOXYGEN +namespace physx +{ + +class PxRigidActor; +class PxShape; +class PxMaterial; + +namespace vehicle2 +{ +#endif + +struct PxVehiclePhysXRoadGeometryQueryState +{ + PxRigidActor* actor; //!< The actor that got hit by the query. + PxShape* shape; //!< The shape that got hit by the query. + PxMaterial* material; //!< The material at the hit point. + PxVec3 hitPosition; //!< The hit position in world space. + + PX_FORCE_INLINE void setToDefault() + { + PxMemZero(this, sizeof(PxVehiclePhysXRoadGeometryQueryState)); + } +}; + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ + diff --git a/Source/ThirdParty/PhysX/vehicle2/pvd/PxVehiclePvdComponents.h b/Source/ThirdParty/PhysX/vehicle2/pvd/PxVehiclePvdComponents.h new file mode 100644 index 000000000..676ff738f --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/pvd/PxVehiclePvdComponents.h @@ -0,0 +1,323 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "vehicle2/PxVehicleComponent.h" +#include "vehicle2/PxVehicleParams.h" +#include "PxVehiclePvdFunctions.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +#define VEHICLE_FLOAT_ARRAY_DATA(b) PxVehicleArrayData b; b.setEmpty(); +#define VEHICLE_ARRAY_DATA(a, b) PxVehicleArrayData b; b.setEmpty(); +#define VEHICLE_SIZED_ARRAY_DATA(a, b) PxVehicleSizedArrayData b; b.setEmpty(); + +class PxVehiclePVDComponent : public PxVehicleComponent +{ +public: + + PxVehiclePVDComponent() : PxVehicleComponent() , firstTime(true) {} + virtual ~PxVehiclePVDComponent() {} + + virtual void getDataForPVDComponent( + const PxVehicleAxleDescription*& axleDescription, + const PxVehicleRigidBodyParams*& rbodyParams, const PxVehicleRigidBodyState*& rbodyState, + const PxVehicleSuspensionStateCalculationParams*& suspStateCalcParams, + PxVehicleSizedArrayData& brakeResponseParams, + const PxVehicleSteerCommandResponseParams*& steerResponseParams, + PxVehicleArrayData& brakeResponseStates, + PxVehicleArrayData& steerResponseStates, + PxVehicleArrayData& wheelParams, + PxVehicleArrayData& wheelActuationStates, + PxVehicleArrayData& wheelRigidBody1dStates, + PxVehicleArrayData& wheelLocalPoses, + PxVehicleArrayData& roadGeomStates, + PxVehicleArrayData& suspParams, + PxVehicleArrayData& suspCompParams, + PxVehicleArrayData& suspForceParams, + PxVehicleArrayData& suspStates, + PxVehicleArrayData& suspCompStates, + PxVehicleArrayData& suspForces, + PxVehicleArrayData& tireForceParams, + PxVehicleArrayData& tireDirectionStates, + PxVehicleArrayData& tireSpeedStates, + PxVehicleArrayData& tireSlipStates, + PxVehicleArrayData& tireStickyStates, + PxVehicleArrayData& tireGripStates, + PxVehicleArrayData& tireCamberStates, + PxVehicleArrayData& tireForces, + PxVehicleSizedArrayData& antiRollForceParams, + const PxVehicleAntiRollTorque*& antiRollTorque, + const PxVehicleCommandState*& commandState, + const PxVehicleDirectDriveThrottleCommandResponseParams*& directDriveThrottleResponseParams, + const PxVehicleDirectDriveTransmissionCommandState*& directDriveTransmissionState, + PxVehicleArrayData& directDrivethrottleResponseState, + const PxVehicleClutchCommandResponseParams*& clutchResponseParams, + const PxVehicleClutchParams*& clutchParams, + const PxVehicleEngineParams*& engineParams, + const PxVehicleGearboxParams*& gearboxParams, + const PxVehicleAutoboxParams*& autoboxParams, + const PxVehicleMultiWheelDriveDifferentialParams*& multiWheelDiffParams, + const PxVehicleFourWheelDriveDifferentialParams*& fourWheelDiffParams, + const PxVehicleEngineDriveTransmissionCommandState*& engineDriveTransmissionState, + const PxVehicleClutchCommandResponseState*& clutchResponseState, + const PxVehicleEngineDriveThrottleCommandResponseState*& engineDriveThrottleResponseState, + const PxVehicleEngineState*& engineState, + const PxVehicleGearboxState*& gearboxState, + const PxVehicleAutoboxState*& autoboxState, + const PxVehicleDifferentialState*& diffState, + const PxVehicleClutchSlipState*& clutchSlipState, + PxVehicleArrayData& physxConstraintParams, + PxVehicleArrayData& physxMaterialFrictionParams, + const PxVehiclePhysXActor*& physxActor, + const PxVehiclePhysXRoadGeometryQueryParams*& physxRoadGeomQryParams, + PxVehicleArrayData& physxRoadGeomStates, + PxVehicleArrayData& physxConstraintStates, + PxVehiclePvdObjectHandles*& objectHandles) = 0; + + virtual bool update(const PxReal dt, const PxVehicleSimulationContext& context) + { + PX_UNUSED(dt); + PX_UNUSED(context); + + if(!context.pvdContext.attributeHandles || !context.pvdContext.writer) + return true; + + const PxVehicleAxleDescription* axleDesc = NULL; + const PxVehicleRigidBodyParams* rbodyParams = NULL; + const PxVehicleRigidBodyState* rbodyState = NULL; + const PxVehicleSuspensionStateCalculationParams* suspStateCalcParams = NULL; + VEHICLE_SIZED_ARRAY_DATA(PxVehicleBrakeCommandResponseParams, brakeResponseParams); + const PxVehicleSteerCommandResponseParams* steerResponseParams = NULL; + VEHICLE_FLOAT_ARRAY_DATA(brakeResponseStates); + VEHICLE_FLOAT_ARRAY_DATA(steerResponseStates); + VEHICLE_ARRAY_DATA(PxVehicleWheelParams, wheelParams); + VEHICLE_ARRAY_DATA(PxVehicleWheelActuationState, wheelActuationStates); + VEHICLE_ARRAY_DATA(PxVehicleWheelRigidBody1dState, wheelRigidBody1dStates); + VEHICLE_ARRAY_DATA(PxVehicleWheelLocalPose, wheelLocalPoses); + VEHICLE_ARRAY_DATA(PxVehicleRoadGeometryState, roadGeomStates); + VEHICLE_ARRAY_DATA(PxVehicleSuspensionParams, suspParams); + VEHICLE_ARRAY_DATA(PxVehicleSuspensionComplianceParams, suspComplianceParams); + VEHICLE_ARRAY_DATA(PxVehicleSuspensionForceParams, suspForceParams); + VEHICLE_ARRAY_DATA(PxVehicleSuspensionState, suspStates); + VEHICLE_ARRAY_DATA(PxVehicleSuspensionComplianceState, suspComplianceStates); + VEHICLE_ARRAY_DATA(PxVehicleSuspensionForce, suspForces); + VEHICLE_ARRAY_DATA(PxVehicleTireForceParams, tireForceParams); + VEHICLE_ARRAY_DATA(PxVehicleTireDirectionState, tireDirectionStates); + VEHICLE_ARRAY_DATA(PxVehicleTireSpeedState, tireSpeedStates); + VEHICLE_ARRAY_DATA(PxVehicleTireSlipState, tireSlipStates); + VEHICLE_ARRAY_DATA(PxVehicleTireStickyState, tireStickyStates); + VEHICLE_ARRAY_DATA(PxVehicleTireGripState, tireGripStates); + VEHICLE_ARRAY_DATA(PxVehicleTireCamberAngleState, tireCamberStates); + VEHICLE_ARRAY_DATA(PxVehicleTireForce, tireForces); + VEHICLE_SIZED_ARRAY_DATA(PxVehicleAntiRollForceParams, antiRollParams); + const PxVehicleAntiRollTorque* antiRollTorque = NULL; + const PxVehicleCommandState* commandState = NULL; + const PxVehicleDirectDriveThrottleCommandResponseParams* directDriveThrottleResponseParams = NULL; + const PxVehicleDirectDriveTransmissionCommandState* directDriveTransmissionState = NULL; + VEHICLE_FLOAT_ARRAY_DATA(directDrivethrottleResponseState); + const PxVehicleClutchCommandResponseParams* clutchResponseParams = NULL; + const PxVehicleClutchParams* clutchParams = NULL; + const PxVehicleEngineParams* engineParams = NULL; + const PxVehicleGearboxParams* gearboxParams = NULL; + const PxVehicleAutoboxParams* autoboxParams = NULL; + const PxVehicleMultiWheelDriveDifferentialParams* multiWheelDiffParams = NULL; + const PxVehicleFourWheelDriveDifferentialParams* fourWheelDiffParams = NULL; + const PxVehicleEngineDriveTransmissionCommandState* engineDriveTransmissionCommandState = NULL; + const PxVehicleClutchCommandResponseState* clutchResponseState = NULL; + const PxVehicleEngineDriveThrottleCommandResponseState* throttleResponseState = NULL; + const PxVehicleEngineState* engineState = NULL; + const PxVehicleGearboxState* gearboxState = NULL; + const PxVehicleAutoboxState* autoboxState = NULL; + const PxVehicleDifferentialState* diffState = NULL; + const PxVehicleClutchSlipState* clutchSlipState = NULL; + VEHICLE_ARRAY_DATA(PxVehiclePhysXSuspensionLimitConstraintParams, physxConstraintParams); + VEHICLE_ARRAY_DATA(PxVehiclePhysXMaterialFrictionParams, physxMaterialFrictionParams); + const PxVehiclePhysXActor* physxActor = NULL; + const PxVehiclePhysXRoadGeometryQueryParams* physxRoadGeomQryParams = NULL; + VEHICLE_ARRAY_DATA(PxVehiclePhysXRoadGeometryQueryState, physxRoadGeomStates); + VEHICLE_ARRAY_DATA(PxVehiclePhysXConstraintState, physxConstraintStates); + PxVehiclePvdObjectHandles* omniPvdObjectHandles = NULL; + + getDataForPVDComponent( + axleDesc, + rbodyParams, rbodyState, + suspStateCalcParams, + brakeResponseParams, steerResponseParams, + brakeResponseStates, steerResponseStates, + wheelParams, + wheelActuationStates, wheelRigidBody1dStates, wheelLocalPoses, + roadGeomStates, + suspParams, suspComplianceParams, suspForceParams, + suspStates, suspComplianceStates, + suspForces, + tireForceParams, + tireDirectionStates, tireSpeedStates, tireSlipStates, tireStickyStates, tireGripStates, tireCamberStates, + tireForces, + antiRollParams, antiRollTorque, + commandState, + directDriveThrottleResponseParams, directDriveTransmissionState, directDrivethrottleResponseState, + clutchResponseParams, clutchParams, engineParams, gearboxParams, autoboxParams, multiWheelDiffParams, fourWheelDiffParams, + engineDriveTransmissionCommandState, + clutchResponseState, throttleResponseState, engineState, gearboxState, autoboxState, diffState, clutchSlipState, + physxConstraintParams, physxMaterialFrictionParams, + physxActor, physxRoadGeomQryParams, physxRoadGeomStates, physxConstraintStates, + omniPvdObjectHandles); + + if(!omniPvdObjectHandles) + return true; + + if(firstTime) + { + PxVehiclePvdRigidBodyRegister( + rbodyParams, rbodyState, + *context.pvdContext.attributeHandles, omniPvdObjectHandles, context.pvdContext.writer); + + PxVehiclePvdSuspensionStateCalculationParamsRegister( + suspStateCalcParams, + *context.pvdContext.attributeHandles, omniPvdObjectHandles, context.pvdContext.writer); + + PxVehiclePvdCommandResponseRegister( + brakeResponseParams, steerResponseParams, + brakeResponseStates, steerResponseStates, + *context.pvdContext.attributeHandles, omniPvdObjectHandles, context.pvdContext.writer); + + PxVehiclePvdWheelAttachmentsRegister( + *axleDesc, + wheelParams, wheelActuationStates, wheelRigidBody1dStates, wheelLocalPoses, + roadGeomStates, + suspParams, suspComplianceParams, suspForceParams, suspStates, suspComplianceStates, + suspForces, + tireForceParams, + tireDirectionStates, tireSpeedStates, tireSlipStates, tireStickyStates, tireGripStates, tireCamberStates, + tireForces, + *context.pvdContext.attributeHandles, omniPvdObjectHandles, context.pvdContext.writer); + + PxVehiclePvdAntiRollsRegister( + antiRollParams, antiRollTorque, + *context.pvdContext.attributeHandles, omniPvdObjectHandles, context.pvdContext.writer); + + PxVehiclePvdDirectDrivetrainRegister( + commandState, directDriveTransmissionState, + directDriveThrottleResponseParams, + directDrivethrottleResponseState, + *context.pvdContext.attributeHandles, omniPvdObjectHandles, context.pvdContext.writer); + + PxVehiclePvdEngineDrivetrainRegister( + commandState, engineDriveTransmissionCommandState, + clutchResponseParams, clutchParams, engineParams, gearboxParams, autoboxParams, multiWheelDiffParams, fourWheelDiffParams, + clutchResponseState, throttleResponseState, engineState, gearboxState, autoboxState, diffState, clutchSlipState, + *context.pvdContext.attributeHandles, omniPvdObjectHandles, context.pvdContext.writer); + + PxVehiclePvdPhysXWheelAttachmentRegister( + *axleDesc, + physxConstraintParams, physxMaterialFrictionParams, + physxActor, physxRoadGeomQryParams, physxRoadGeomStates, physxConstraintStates, + *context.pvdContext.attributeHandles, omniPvdObjectHandles, context.pvdContext.writer); + + PxVehiclePvdPhysXRigidActorRegister( + physxActor, + *context.pvdContext.attributeHandles, omniPvdObjectHandles, context.pvdContext.writer); + + firstTime = false; + } + + PxVehiclePvdRigidBodyWrite( + rbodyParams, rbodyState, + *context.pvdContext.attributeHandles, *omniPvdObjectHandles, context.pvdContext.writer); + + PxVehiclePvdSuspensionStateCalculationParamsWrite( + suspStateCalcParams, + *context.pvdContext.attributeHandles, *omniPvdObjectHandles, context.pvdContext.writer); + + PxVehiclePvdCommandResponseWrite( + *axleDesc, brakeResponseParams, steerResponseParams, brakeResponseStates, steerResponseStates, + *context.pvdContext.attributeHandles, *omniPvdObjectHandles, context.pvdContext.writer); + + PxVehiclePvdWheelAttachmentsWrite( + *axleDesc, + wheelParams, wheelActuationStates, wheelRigidBody1dStates, wheelLocalPoses, + roadGeomStates, + suspParams, suspComplianceParams, suspForceParams, suspStates, suspComplianceStates, + suspForces, + tireForceParams, + tireDirectionStates, tireSpeedStates, tireSlipStates, tireStickyStates, tireGripStates, tireCamberStates, + tireForces, + *context.pvdContext.attributeHandles, *omniPvdObjectHandles, context.pvdContext.writer); + + PxVehiclePvdAntiRollsWrite( + antiRollParams, antiRollTorque, + *context.pvdContext.attributeHandles, *omniPvdObjectHandles, context.pvdContext.writer); + + PxVehiclePvdDirectDrivetrainWrite( + *axleDesc, + commandState, directDriveTransmissionState, + directDriveThrottleResponseParams, + directDrivethrottleResponseState, + *context.pvdContext.attributeHandles, *omniPvdObjectHandles, context.pvdContext.writer); + + PxVehiclePvdEngineDrivetrainWrite( + commandState, engineDriveTransmissionCommandState, + clutchResponseParams, clutchParams, engineParams, gearboxParams, autoboxParams, multiWheelDiffParams, fourWheelDiffParams, + clutchResponseState, throttleResponseState, engineState, gearboxState, autoboxState, diffState, clutchSlipState, + *context.pvdContext.attributeHandles, *omniPvdObjectHandles, context.pvdContext.writer); + + PxVehiclePvdPhysXWheelAttachmentWrite( + *axleDesc, + physxConstraintParams, physxMaterialFrictionParams, + physxActor, physxRoadGeomQryParams, physxRoadGeomStates, physxConstraintStates, + *context.pvdContext.attributeHandles, *omniPvdObjectHandles, context.pvdContext.writer); + + PxVehiclePvdPhysXRigidActorWrite( + physxActor, + *context.pvdContext.attributeHandles, *omniPvdObjectHandles, context.pvdContext.writer); + + return true; + } + +private: + + bool firstTime; +}; + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/pvd/PxVehiclePvdFunctions.h b/Source/ThirdParty/PhysX/vehicle2/pvd/PxVehiclePvdFunctions.h new file mode 100644 index 000000000..9bff4dbb3 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/pvd/PxVehiclePvdFunctions.h @@ -0,0 +1,610 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "vehicle2/PxVehicleParams.h" +#include "vehicle2/braking/PxVehicleBrakingParams.h" +#include "vehicle2/commands/PxVehicleCommandStates.h" +#include "vehicle2/drivetrain/PxVehicleDrivetrainParams.h" +#include "vehicle2/drivetrain/PxVehicleDrivetrainStates.h" +#include "vehicle2/physxActor/PxVehiclePhysXActorStates.h" +#include "vehicle2/physxConstraints/PxVehiclePhysXConstraintParams.h" +#include "vehicle2/physxConstraints/PxVehiclePhysXConstraintStates.h" +#include "vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryParams.h" +#include "vehicle2/physxRoadGeometry/PxVehiclePhysXRoadGeometryState.h" +#include "vehicle2/roadGeometry/PxVehicleRoadGeometryState.h" +#include "vehicle2/steering/PxVehicleSteeringParams.h" +#include "vehicle2/suspension/PxVehicleSuspensionParams.h" +#include "vehicle2/suspension/PxVehicleSuspensionStates.h" +#include "vehicle2/tire/PxVehicleTireParams.h" +#include "vehicle2/tire/PxVehicleTireStates.h" +#include "vehicle2/wheel/PxVehicleWheelParams.h" +#include "vehicle2/wheel/PxVehicleWheelStates.h" + +class OmniPvdWriter; +namespace physx +{ +class PxAllocatorCallback; +namespace vehicle2 +{ +struct PxVehiclePvdAttributeHandles; +struct PxVehiclePvdObjectHandles; +} // namespace vehicle2 +} // namespace physx + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +/** +\brief Create object instances in omnipvd that will be used to reflect the parameters and state of the rigid body of a vehicle instance. +Handles to the created object instances will be stored in a PxVehiclePvdObjectHandles instance. +\param[in] rbodyParams describes the parameters of the vehicle's rigid body. +\param[in] rbodyState describes the state of the vehicle's rigid body. +\param[in] attributeHandles contains a general description of vehicle parameters and states that will be reflected in omnipvd. +\param[in] objectHandles contains unique handles for the parameters and states of each vehicle instance. +\param[in] omniWriter is an OmniPvdWriter instance used to communicate state and parameter data to omnipvd. +\note If rbodyParams is NULL, omnipvd will not reflect rigid body parameters. +\note If rbodyState is NULL, omnipvd will not reflect rigid body state. +\note objectHandles must be non-NULL +\note omniWriter must be non-NULL +\note PxVehiclePvdRigidBodyRegister should be called once for each vehicle instance. +@see PxVehiclePvdAttributesCreate +@see PxVehiclePvdObjectCreate +@see PxVehiclePvdRigidBodyWrite +*/ +void PxVehiclePvdRigidBodyRegister +(const PxVehicleRigidBodyParams* rbodyParams, const PxVehicleRigidBodyState* rbodyState, + const PxVehiclePvdAttributeHandles& attributeHandles, + PxVehiclePvdObjectHandles* objectHandles, OmniPvdWriter* omniWriter); + +/** +\brief Write the parameters and state of the rigid body of a vehicle instance to omnipvd. +\param[in] rbodyParams describes the parameters of the vehicle's rigid body. +\param[in] rbodyState describes the state of the vehicle's rigid body. +\param[in] attributeHandles contains a general description of vehicle parameters and states that will be reflected in omnipvd. +\param[in] objectHandles contains unique handles for the parameters and states of each vehicle instance. +\param[in] omniWriter is an OmniPvdWriter instance used to communicate state and parameter data to omnipvd. +\note If rbodyParams is NULL but a non-NULL value was used in PxVehiclePvdRigidBodyRegister(), the rigid body parameters will not be updated in omnipvd. +\note If rbodyState is NULL but a non-NULL value was used in PxVehiclePvdRigidBodyRegister(), the rigid body state will not be updated in omnipvd. +\note omniWriter must be non-NULL and must be the same instance used in PxVehiclePvdRigidBodyRegister(). +@see PxVehiclePvdAttributesCreate +@see PxVehiclePvdObjectCreate +@see PxVehiclePvdRigidBodyRegister +*/ +void PxVehiclePvdRigidBodyWrite +(const PxVehicleRigidBodyParams* rbodyParams, const PxVehicleRigidBodyState* rbodyState, + const PxVehiclePvdAttributeHandles& attributeHandles, + const PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter* omniWriter); + +/** +\brief Register object instances in omnipvd that will be used to reflect the suspension state calculation parameters of a vehicle instance. +\param[in] suspStateCalcParams describes parameters used to calculate suspension state. +\param[in] attributeHandles contains a general description of vehicle parameters and states that will be reflected in omnipvd. +\param[in] objectHandles contains unique handles for the parameters and states of each vehicle instance. +\param[in] omniWriter is an OmniPvdWriter instance used to communicate state and parameter data to omnipvd. +\note If suspStateCalcParams is NULL, omnipvd will not reflect the suspension state calculation parameters. +\note objectHandles must be non-NULL +\note omniWriter must be non-NULL +@see PxVehiclePvdAttributesCreate +@see PxVehiclePvdObjectCreate +@see PxVehiclePvdSuspensionStateCalculationParamsWrite +*/ +void PxVehiclePvdSuspensionStateCalculationParamsRegister +(const PxVehicleSuspensionStateCalculationParams* suspStateCalcParams, + const PxVehiclePvdAttributeHandles& attributeHandles, + PxVehiclePvdObjectHandles* objectHandles, OmniPvdWriter* omniWriter); + +/** +\brief Write the parameters and state of the rigid body of a vehicle instance to omnipvd. +\param[in] suspStateCalcParams describes parameters used to calculate suspension state. +\param[in] attributeHandles contains a general description of vehicle parameters and states that will be reflected in omnipvd. +\param[in] objectHandles contains unique handles for the parameters and states of each vehicle instance. +\param[in] omniWriter is an OmniPvdWriter instance used to communicate state and parameter data to omnipvd. +\note If suspStateCalcParams is NULL but a non-NULL value was used in void PxVehiclePvdSuspensionStateCalculationParamsRegister(), +the suspension state calculation parameters will not be updated in omnipvd. +\note omniWriter must be non-NULL and must be the same instance used in PxVehiclePvdSuspensionStateCalculationParamsRegister(). +@see PxVehiclePvdAttributesCreate +@see PxVehiclePvdObjectCreate +@see PxVehiclePvdSuspensionStateCalculationParamsRegister +*/ +void PxVehiclePvdSuspensionStateCalculationParamsWrite +(const PxVehicleSuspensionStateCalculationParams* suspStateCalcParams, + const PxVehiclePvdAttributeHandles& attributeHandles, + const PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter* omniWriter); + +/** +\brief Register object instances in omnipvd that will be used to reflect the brake and steer command response parameters of a vehicle instance. +\param[in] brakeResponseParams is an array of brake command response parameters. +\param[in] steerResponseParams describes the steer command response parameters. +\param[in] brakeResponseStates is an array of brake responses torqyes, +\param[in] steerResponseStates is an array of steer response angles. +\param[in] attributeHandles contains a general description of vehicle parameters and states that will be reflected in omnipvd. +\param[in] objectHandles contains unique handles for the parameters and states of each vehicle instance. +\param[in] omniWriter is an OmniPvdWriter instance used to communicate state and parameter data to omnipvd. +\note If brakeResponseParams is empty, omnipvd will not reflect any brake command response parameters. +\note If steerResponseParams is NULL, omnipvd will not reflect the steer command response parameters. +\note If brakeResponseStates is empty, omnipvd will not reflect any brake command response state. +\note If steerResponseStates is empty, omnipvd will not reflect any steer command response state. +\note objectHandles must be non-NULL +\note omniWriter must be non-NULL +@see PxVehiclePvdAttributesCreate +@see PxVehiclePvdObjectCreate +@see PxVehiclePvdCommandResponseWrite +*/ +void PxVehiclePvdCommandResponseRegister +(const PxVehicleSizedArrayData& brakeResponseParams, + const PxVehicleSteerCommandResponseParams* steerResponseParams, + const PxVehicleArrayData& brakeResponseStates, + const PxVehicleArrayData& steerResponseStates, + const PxVehiclePvdAttributeHandles& attributeHandles, + PxVehiclePvdObjectHandles* objectHandles, OmniPvdWriter* omniWriter); + +/** +\brief Write brake and steer command response parameters to omnipvd. +\param[in] axleDesc is a description of the wheels and axles of a vehicle. +\param[in] brakeResponseParams is an array of brake command response parameters. +\param[in] steerResponseParams describes the steer command response parameters. +\param[in] brakeResponseStates is an array of brake response torques. +\param[in] steerResponseStates is an array of steer response angles. +\param[in] attributeHandles contains a general description of vehicle parameters and states that will be reflected in omnipvd. +\param[in] objectHandles contains unique handles for the parameters and states of each vehicle instance. +\param[in] omniWriter is an OmniPvdWriter instance used to communicate state and parameter data to omnipvd. +\note If brakeResponseParams is empty but a non-empty array was used in PxVehiclePvdCommandResponseRegister(), +the brake command response parameters will not be updated in omnipvd. +\note If steerResponseParams is non-NULL but a NULL value was used in PxVehiclePvdCommandResponseRegister(), +the steer command parameters will not be updated in omnipvd. +\note If brakeResponseStates is empty but a non-empty array was used in PxVehiclePvdCommandResponseRegister(), +the brake response states will not be updated in omnipvd. +\note If steerResponseStates is empty but a non-empty array was used in PxVehiclePvdCommandResponseRegister(), +the steer response states will not be updated in omnipvd. +\note omniWriter must be non-NULL and must be the same instance used in PxVehiclePvdCommandResponseRegister(). +@see PxVehiclePvdAttributesCreate +@see PxVehiclePvdObjectCreate +@see PxVehiclePvdCommandResponseRegister +*/ +void PxVehiclePvdCommandResponseWrite +(const PxVehicleAxleDescription& axleDesc, + const PxVehicleSizedArrayData& brakeResponseParams, + const PxVehicleSteerCommandResponseParams* steerResponseParams, + const PxVehicleArrayData& brakeResponseStates, + const PxVehicleArrayData& steerResponseStates, + const PxVehiclePvdAttributeHandles& attributeHandles, + const PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter* omniWriter); + +/** +\brief Register object instances in omnipvd that will be used to reflect wheel attachment data such as tires, suspensions and wheels. +\param[in] axleDesc is a description of the wheels and axles of a vehicle. +\param[in] wheelParams is an array of wheel parameters. +\param[in] wheelActuationStates is an array of wheel actuation states. +\param[in] wheelRigidBody1dStates is an array of wheel rigid body states. +\param[in] wheelLocalPoses is an array of wheel local poses. +\param[in] roadGeometryStates is an array of road geometry states. +\param[in] suspParams is an array of suspension parameters. +\param[in] suspCompParams is an array of suspension compliance parameters. +\param[in] suspForceParams is an array of suspension force parameters. +\param[in] suspStates is an array of suspension states. +\param[in] suspCompStates is an array of suspension compliance states. +\param[in] suspForces is an array of suspension forces. +\param[in] tireForceParams is an array of tire force parameters. +\param[in] tireDirectionStates is an array of tire direction states. +\param[in] tireSpeedStates is an array of tire speed states. +\param[in] tireSlipStates is an array of tire slip states. +\param[in] tireStickyStates is an array of tire sticky states. +\param[in] tireGripStates is an array of tire grip states. +\param[in] tireCamberStates is an array of tire camber states. +\param[in] tireForces is an array of tire forces. +\param[in] attributeHandles contains a general description of vehicle parameters and states that will be reflected in omnipvd. +\param[in] objectHandles contains unique handles for the parameters and states of each vehicle instance. +\param[in] omniWriter is an OmniPvdWriter instance used to communicate state and parameter data to omnipvd. +\note If any array is empty, the corresponding data will not be reflected in omnipvd. +\note Each array must either be empty or contain an entry for each wheel present in axleDesc. +\note objectHandles must be non-NULL +\note omniWriter must be non-NULL +@see PxVehiclePvdAttributesCreate +@see PxVehiclePvdObjectCreate +@see PxVehiclePvdWheelAttachmentsWrite +*/ +void PxVehiclePvdWheelAttachmentsRegister +(const PxVehicleAxleDescription& axleDesc, + const PxVehicleArrayData& wheelParams, + const PxVehicleArrayData& wheelActuationStates, + const PxVehicleArrayData& wheelRigidBody1dStates, + const PxVehicleArrayData& wheelLocalPoses, + const PxVehicleArrayData& roadGeometryStates, + const PxVehicleArrayData& suspParams, + const PxVehicleArrayData& suspCompParams, + const PxVehicleArrayData& suspForceParams, + const PxVehicleArrayData& suspStates, + const PxVehicleArrayData& suspCompStates, + const PxVehicleArrayData& suspForces, + const PxVehicleArrayData& tireForceParams, + const PxVehicleArrayData& tireDirectionStates, + const PxVehicleArrayData& tireSpeedStates, + const PxVehicleArrayData& tireSlipStates, + const PxVehicleArrayData& tireStickyStates, + const PxVehicleArrayData& tireGripStates, + const PxVehicleArrayData& tireCamberStates, + const PxVehicleArrayData& tireForces, + const PxVehiclePvdAttributeHandles& attributeHandles, + PxVehiclePvdObjectHandles* objectHandles, OmniPvdWriter* omniWriter); + +/** +\brief Write wheel attachment data such as tire, suspension and wheel data to omnipvd. +\param[in] axleDesc is a description of the wheels and axles of a vehicle. +\param[in] wheelParams is an array of wheel parameters. +\param[in] wheelActuationStates is an array of wheel actuation states. +\param[in] wheelRigidBody1dStates is an array of wheel rigid body states. +\param[in] wheelLocalPoses is an array of wheel local poses. +\param[in] roadGeometryStates is an array of road geometry states. +\param[in] suspParams is an array of suspension parameters. +\param[in] suspCompParams is an array of suspension compliance parameters. +\param[in] suspForceParams is an array of suspension force parameters. +\param[in] suspStates is an array of suspension states. +\param[in] suspCompStates is an array of suspension compliance states. +\param[in] suspForces is an array of suspension forces. +\param[in] tireForceParams is an array of tire force parameters. +\param[in] tireDirectionStates is an array of tire direction states. +\param[in] tireSpeedStates is an array of tire speed states. +\param[in] tireSlipStates is an array of tire slip states. +\param[in] tireStickyStates is an array of tire sticky states. +\param[in] tireGripStates is an array of tire grip states. +\param[in] tireCamberStates is an array of tire camber states. +\param[in] tireForces is an array of tire forces. +\param[in] attributeHandles contains a general description of vehicle parameters and states that will be reflected in omnipvd. +\param[in] objectHandles contains unique handles for the parameters and states of each vehicle instance. +\param[in] omniWriter is an OmniPvdWriter instance used to communicate state and parameter data to omnipvd. +\note If any array is empty but the corresponding argument in PxVehiclePvdWheelAttachmentsRegister was not empty, the corresponding data will not be updated in omnipvd. +\note Each array must either be empty or contain an entry for each wheel present in axleDesc. +\note omniWriter must be non-NULL +@see PxVehiclePvdAttributesCreate +@see PxVehiclePvdObjectCreate +@see PxVehiclePvdWheelAttachmentsRegister +*/ +void PxVehiclePvdWheelAttachmentsWrite +(const PxVehicleAxleDescription& axleDesc, + const PxVehicleArrayData& wheelParams, + const PxVehicleArrayData& wheelActuationStates, + const PxVehicleArrayData& wheelRigidBody1dStates, + const PxVehicleArrayData& wheelLocalPoses, + const PxVehicleArrayData& roadGeometryStates, + const PxVehicleArrayData& suspParams, + const PxVehicleArrayData& suspCompParams, + const PxVehicleArrayData& suspForceParams, + const PxVehicleArrayData& suspStates, + const PxVehicleArrayData& suspCompStates, + const PxVehicleArrayData& suspForces, + const PxVehicleArrayData& tireForceParams, + const PxVehicleArrayData& tireDirectionStates, + const PxVehicleArrayData& tireSpeedStates, + const PxVehicleArrayData& tireSlipStates, + const PxVehicleArrayData& tireStickyStates, + const PxVehicleArrayData& tireGripStates, + const PxVehicleArrayData& tireCamberStates, + const PxVehicleArrayData& tireForces, + const PxVehiclePvdAttributeHandles& attributeHandles, + const PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter* omniWriter); + +/** +\brief Register object instances in omnipvd that will be used to reflect the antiroll bars of a vehicle instance. +\param[in] antiRollForceParams is an array of antiroll parameters. +\param[in] antiRollTorque describes the instantaneous accumulated torque from all antiroll bas. +\param[in] attributeHandles contains a general description of vehicle parameters and states that will be reflected in omnipvd. +\param[in] objectHandles contains unique handles for the parameters and states of each vehicle instance. +\param[in] omniWriter is an OmniPvdWriter instance used to communicate state and parameter data to omnipvd. +\note If antiRollForceParams is empty, the corresponding data will not be reflected in omnipvd. +\note If antiRollTorque is NULL, the corresponding data will not be reflected in omnipvd. +\note objectHandles must be non-NULL +\note omniWriter must be non-NULL +@see PxVehiclePvdAttributesCreate +@see PxVehiclePvdObjectCreate +@see PxVehiclePvdAntiRollsWrite +*/ +void PxVehiclePvdAntiRollsRegister +(const PxVehicleSizedArrayData& antiRollForceParams, const PxVehicleAntiRollTorque* antiRollTorque, + const PxVehiclePvdAttributeHandles& attributeHandles, + PxVehiclePvdObjectHandles* objectHandles, OmniPvdWriter* omniWriter); + +/** +\brief Write antiroll data to omnipvd. +\param[in] antiRollForceParams is an array of antiroll parameters. +\param[in] antiRollTorque describes the instantaneous accumulated torque from all antiroll bas. +\param[in] attributeHandles contains a general description of vehicle parameters and states that will be reflected in omnipvd. +\param[in] objectHandles contains unique handles for the parameters and states of each vehicle instance. +\param[in] omniWriter is an OmniPvdWriter instance used to communicate state and parameter data to omnipvd. +\note If antiRollForceParams is empty but the corresponding argument was not empty, the corresponding data will not be updated in omnipvd. +\note If antiRollTorque is NULL but the corresponding argument was not NULL, the corresponding data will not be updated in omnipvd. +\note omniWriter must be non-NULL +@see PxVehiclePvdAttributesCreate +@see PxVehiclePvdObjectCreate +@see PxVehiclePvdAntiRollsRegister +*/ +void PxVehiclePvdAntiRollsWrite +(const PxVehicleSizedArrayData& antiRollForceParams, const PxVehicleAntiRollTorque* antiRollTorque, + const PxVehiclePvdAttributeHandles& attributeHandles, + const PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter* omniWriter); + +/** +\brief Register object instances in omnipvd that will be used to reflect the direct drivetrain of a vehicle instance. +\param[in] commandState describes the control values applied to the vehicle. +\param[in] transmissionCommandState describes the state of the direct drive transmission. +\param[in] directDriveThrottleResponseParams describes the vehicle's torque response to a throttle command. +\param[in] directDriveThrottleResponseState is the instantaneous torque response of each wheel to a throttle command. +\param[in] attributeHandles contains a general description of vehicle parameters and states that will be reflected in omnipvd. +\param[in] objectHandles contains unique handles for the parameters and states of each vehicle instance. +\param[in] omniWriter is an OmniPvdWriter instance used to communicate state and parameter data to omnipvd. +\note If commandState is NULL, the corresponding data will not be reflected in omnipvd. +\note If transmissionCommandState is NULL, the corresponding data will not be reflected in omnipvd. +\note If directDriveThrottleResponseParams is NULL, the corresponding data will not be reflected in omnipvd. +\note If directDriveThrottleResponseState is empty, the corresponding data will not be reflected in omnipvd. +\note objectHandles must be non-NULL +\note omniWriter must be non-NULL +@see PxVehiclePvdAttributesCreate +@see PxVehiclePvdObjectCreate +@see PxVehiclePvdDirectDrivetrainWrite +*/ +void PxVehiclePvdDirectDrivetrainRegister +(const PxVehicleCommandState* commandState, const PxVehicleDirectDriveTransmissionCommandState* transmissionCommandState, + const PxVehicleDirectDriveThrottleCommandResponseParams* directDriveThrottleResponseParams, + const PxVehicleArrayData& directDriveThrottleResponseState, + const PxVehiclePvdAttributeHandles& attributeHandles, + PxVehiclePvdObjectHandles* objectHandles, OmniPvdWriter* omniWriter); + +/** +\brief Write direct drivetrain data to omnipvd. +\param[in] axleDesc is a description of the wheels and axles of a vehicle. +\param[in] commandState describes the control values applied to the vehicle. +\param[in] transmissionCommandState describes the state of the direct drive transmission. +\param[in] directDriveThrottleResponseParams describes the vehicle's torque response to a throttle command. +\param[in] directDriveThrottleResponseState is the instantaneous torque response of each wheel to a throttle command. +\param[in] attributeHandles contains a general description of vehicle parameters and states that will be reflected in omnipvd. +\param[in] objectHandles contains unique handles for the parameters and states of each vehicle instance. +\param[in] omniWriter is an OmniPvdWriter instance used to communicate state and parameter data to omnipvd. +\note If commandState is NULL but the corresponding entry in PxVehiclePvdDirectDrivetrainRegister() was not NULL, the corresponding data will not be updated in omnipvd. +\note If transmissionCommandState is NULL but the corresponding entry in PxVehiclePvdDirectDrivetrainRegister() was not NULL, the corresponding data will not be updated in omnipvd. +\note If directDriveThrottleResponseParams is NULL but the corresponding entry in PxVehiclePvdDirectDrivetrainRegister() was not NULL, the corresponding data will not be updated in omnipvd. +\note If directDriveThrottleResponseState is empty but the corresponding entry in PxVehiclePvdDirectDrivetrainRegister() was not empty, the corresponding data will not be updated in omnipvd. +\note omniWriter must be non-NULL +@see PxVehiclePvdAttributesCreate +@see PxVehiclePvdObjectCreate +@see PxVehiclePvdDirectDrivetrainRegister +*/ +void PxVehiclePvdDirectDrivetrainWrite +(const PxVehicleAxleDescription& axleDesc, + const PxVehicleCommandState* commandState, const PxVehicleDirectDriveTransmissionCommandState* transmissionCommandState, + const PxVehicleDirectDriveThrottleCommandResponseParams* directDriveThrottleResponseParams, + const PxVehicleArrayData& directDriveThrottleResponseState, + const PxVehiclePvdAttributeHandles& attributeHandles, + const PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter* omniWriter); + +/** +\brief Register object instances in omnipvd that will be used to reflect the engine drivetrain of a vehicle instance. +\param[in] commandState describes the control values applied to the vehicle. +\param[in] transmissionCommandState describes the state of the engine drive transmission. +\param[in] clutchResponseParams describes the vehicle's response to a clutch command. +\param[in] clutchParams describes the vehicle's clutch. +\param[in] engineParams describes the engine. +\param[in] gearboxParams describes the gearbox. +\param[in] autoboxParams describes the automatic gearbox. +\param[in] multiWheelDiffParams describes a multiwheel differential without limited slip compensation. +\param[in] fourWheelDiffPrams describes a differential that delivers torque to four drive wheels with limited slip compensation. +\param[in] clutchResponseState is the instantaneous reponse of the clutch to a clutch command. +\param[in] throttleResponseState is the instantaneous response to a throttle command. +\param[in] engineState is the instantaneous state of the engine. +\param[in] gearboxState is the instantaneous state of the gearbox. +\param[in] autoboxState is the instantaneous state of the automatic gearbox. +\param[in] diffState is the instantaneous state of the differential. +\param[in] clutchSlipState is the instantaneous slip recorded at the clutch. +\param[in] attributeHandles contains a general description of vehicle parameters and states that will be reflected in omnipvd. +\param[in] objectHandles contains unique handles for the parameters and states of each vehicle instance. +\param[in] omniWriter is an OmniPvdWriter instance used to communicate state and parameter data to omnipvd. +\note If any pointer is NULL, the corresponding data will not be reflected in omnipvd. +\note objectHandles must be non-NULL +\note omniWriter must be non-NULL +@see PxVehiclePvdAttributesCreate +@see PxVehiclePvdObjectCreate +@see PxVehiclePvdEngineDrivetrainWrite +*/ +void PxVehiclePvdEngineDrivetrainRegister +(const PxVehicleCommandState* commandState, const PxVehicleEngineDriveTransmissionCommandState* transmissionCommandState, + const PxVehicleClutchCommandResponseParams* clutchResponseParams, + const PxVehicleClutchParams* clutchParams, + const PxVehicleEngineParams* engineParams, + const PxVehicleGearboxParams* gearboxParams, + const PxVehicleAutoboxParams* autoboxParams, + const PxVehicleMultiWheelDriveDifferentialParams* multiWheelDiffParams, + const PxVehicleFourWheelDriveDifferentialParams* fourWheelDiffPrams, + const PxVehicleClutchCommandResponseState* clutchResponseState, + const PxVehicleEngineDriveThrottleCommandResponseState* throttleResponseState, + const PxVehicleEngineState* engineState, + const PxVehicleGearboxState* gearboxState, + const PxVehicleAutoboxState* autoboxState, + const PxVehicleDifferentialState* diffState, + const PxVehicleClutchSlipState* clutchSlipState, + const PxVehiclePvdAttributeHandles& attributeHandles, + PxVehiclePvdObjectHandles* objectHandles, OmniPvdWriter* omniWriter); + +/** +\brief Write engine drivetrain data of a vehicle instance to omnipvd. +\param[in] commandState describes the control values applied to the vehicle. +\param[in] transmissionCommandState describes the state of the engine drive transmission. +\param[in] clutchResponseParams describes the vehicle's response to a clutch command. +\param[in] clutchParams describes the vehicle's clutch. +\param[in] engineParams describes the engine. +\param[in] gearboxParams describes the gearbox. +\param[in] autoboxParams describes the automatic gearbox. +\param[in] multiWheelDiffParams describes a multiwheel differential without limited slip compensation. +\param[in] fourWheelDiffPrams describes a differential that delivers torque to four drive wheels with limited slip compensation. +\param[in] clutchResponseState is the instantaneous reponse of the clutch to a clutch command. +\param[in] throttleResponseState is the instantaneous response to a throttle command. +\param[in] engineState is the instantaneous state of the engine. +\param[in] gearboxState is the instantaneous state of the gearbox. +\param[in] autoboxState is the instantaneous state of the automatic gearbox. +\param[in] diffState is the instantaneous state of the differential. +\param[in] clutchSlipState is the instantaneous slip recorded at the clutch. +\param[in] attributeHandles contains a general description of vehicle parameters and states that will be reflected in omnipvd. +\param[in] objectHandles contains unique handles for the parameters and states of each vehicle instance. +\param[in] omniWriter is an OmniPvdWriter instance used to communicate state and parameter data to omnipvd. +\note If any pointer is NULL and the corresponding argument in PxVehiclePvdEngineDrivetrainRegister() was not NULL, the corresponding data will not be reflected in omnipvd. +\note omniWriter must be non-NULL +@see PxVehiclePvdAttributesCreate +@see PxVehiclePvdObjectCreate +@see PxVehiclePvdEngineDrivetrainRegister +*/ +void PxVehiclePvdEngineDrivetrainWrite +(const PxVehicleCommandState* commandState, const PxVehicleEngineDriveTransmissionCommandState* transmissionCommandState, + const PxVehicleClutchCommandResponseParams* clutchResponseParams, + const PxVehicleClutchParams* clutchParams, + const PxVehicleEngineParams* engineParams, + const PxVehicleGearboxParams* gearboxParams, + const PxVehicleAutoboxParams* autoboxParams, + const PxVehicleMultiWheelDriveDifferentialParams* multiWheelDiffParams, + const PxVehicleFourWheelDriveDifferentialParams* fourWheelDiffPrams, + const PxVehicleClutchCommandResponseState* clutchResponseState, + const PxVehicleEngineDriveThrottleCommandResponseState* throttleResponseState, + const PxVehicleEngineState* engineState, + const PxVehicleGearboxState* gearboxState, + const PxVehicleAutoboxState* autoboxState, + const PxVehicleDifferentialState* diffState, + const PxVehicleClutchSlipState* clutchSlipState, + const PxVehiclePvdAttributeHandles& attributeHandles, + const PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter* omniWriter); + +/** +\brief Register per wheel attachment data that involves the vehicle's integration with a PhysX scene. +\param[in] axleDesc is a description of the wheels and axles of a vehicle. +\param[in] physxSuspLimitConstraintParams describes the method used by PhysX to enforce suspension travel limits. +\param[in] physxMaterialFrictionParams describes the friction response of each wheel to a set of PxMaterial instances. +\param[in] physxActor describes the PxRigidActor and PxShape instances that are used to represent the vehicle's rigid body and wheel shapes in PhysX. +\param[in] physxRoadGeometryQueryParams describes the physx scene query method used to place each wheel on the ground. +\param[in] physxRoadGeomState is an array of per wheel physx scene query results. +\param[in] physxConstraintStates is an array of constraints states used by PhysX to enforce sticky tire and suspension travel limit constraints. +\param[in] attributeHandles contains a general description of vehicle parameters and states that will be reflected in omnipvd. +\param[in] objectHandles contains unique handles for the parameters and states of each vehicle instance. +\param[in] omniWriter is an OmniPvdWriter instance used to communicate state and parameter data to omnipvd. +\note If any array is empty, the corresponding data will not be reflected in omnipvd. +\note If physxActor is NULL, the corresponding data will not be reflected in omnipvd. +\note If physxRoadGeometryQueryParams is NULL, the corresponding data will not be reflected in omnipvd. +\note Each array must either be empty or contain an entry for each wheel present in axleDesc. +\note objectHandles must be non-NULL. +\note omniWriter must be non-NULL. +@see PxVehiclePvdAttributesCreate +@see PxVehiclePvdObjectCreate +@see PxVehiclePvdPhysXWheelAttachmentWrite +*/ +void PxVehiclePvdPhysXWheelAttachmentRegister +(const PxVehicleAxleDescription& axleDesc, + const PxVehicleArrayData& physxSuspLimitConstraintParams, + const PxVehicleArrayData& physxMaterialFrictionParams, + const PxVehiclePhysXActor* physxActor, const PxVehiclePhysXRoadGeometryQueryParams* physxRoadGeometryQueryParams, + const PxVehicleArrayData& physxRoadGeomState, + const PxVehicleArrayData& physxConstraintStates, + const PxVehiclePvdAttributeHandles& attributeHandles, + PxVehiclePvdObjectHandles* objectHandles, OmniPvdWriter* omniWriter); + +/** +\brief Write to omnipvd the per wheel attachment data that involves the vehicle's integration with a PhysX scene. +\param[in] axleDesc is a description of the wheels and axles of a vehicle. +\param[in] physxSuspLimitConstraintParams describes the method used by PhysX to enforce suspension travel limits. +\param[in] physxMaterialFrictionParams describes the friction response of each wheel to a set of PxMaterial instances. +\param[in] physxActor describes the PxShape instances that are used to represent the vehicle's wheel shapes in PhysX. +\param[in] physxRoadGeometryQueryParams describes the physx scene query method used to place each wheel on the ground. +\param[in] physxRoadGeomState is an array of per wheel physx scene query results. +\param[in] physxConstraintStates is an array of constraints states used by PhysX to enforce sticky tire and suspension travel limit constraints. +\param[in] attributeHandles contains a general description of vehicle parameters and states that will be reflected in omnipvd. +\param[in] objectHandles contains unique handles for the parameters and states of each vehicle instance. +\param[in] omniWriter is an OmniPvdWriter instance used to communicate state and parameter data to omnipvd. +\note If any array is empty but the corresponding array in PxVehiclePvdPhysXWheelAttachmentRegister() was not empty, the corresponding data will not be updated in omnipvd. +\note If physxActor is NULL but the corresponding argument in PxVehiclePvdPhysXWheelAttachmentRegister was not NULL, the corresponding data will not be reflected in omnipvd. +\note If physxRoadGeometryQueryParams is NULL but the corresponding argument in PxVehiclePvdPhysXWheelAttachmentRegister was not NULL, the corresponding data will not be reflected in omnipvd. +\note Each array must either be empty or contain an entry for each wheel present in axleDesc. +\note omniWriter must be non-NULL. +@see PxVehiclePvdAttributesCreate +@see PxVehiclePvdObjectCreate +@see PxVehiclePvdPhysXWheelAttachmentWrite +*/ +void PxVehiclePvdPhysXWheelAttachmentWrite +(const PxVehicleAxleDescription& axleDesc, + const PxVehicleArrayData& physxSuspLimitConstraintParams, + const PxVehicleArrayData& physxMaterialFrictionParams, + const PxVehiclePhysXActor* physxActor, const PxVehiclePhysXRoadGeometryQueryParams* physxRoadGeometryQueryParams, + const PxVehicleArrayData& physxRoadGeomState, + const PxVehicleArrayData& physxConstraintStates, + const PxVehiclePvdAttributeHandles& attributeHandles, + const PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter* omniWriter); + +/** +\brief Register the PxRigidActor instance that represents the vehicle's rigid body in a PhysX scene. +\param[in] physxActor describes the PxRigidActor instance that is used to represent the vehicle's rigid body in PhysX. +\param[in] attributeHandles contains a general description of vehicle parameters and states that will be reflected in omnipvd. +\param[in] objectHandles contains unique handles for the parameters and states of each vehicle instance. +\param[in] omniWriter is an OmniPvdWriter instance used to communicate state and parameter data to omnipvd. +\note If physxActor is NULL, the corresponding data will not be reflected in omnipvd. +\note objectHandles must be non-NULL. +\note omniWriter must be non-NULL. +@see PxVehiclePvdAttributesCreate +@see PxVehiclePvdObjectCreate +@see PxVehiclePvdPhysXRigidActorWrite +*/ +void PxVehiclePvdPhysXRigidActorRegister +(const PxVehiclePhysXActor* physxActor, + const PxVehiclePvdAttributeHandles& attributeHandles, + PxVehiclePvdObjectHandles* objectHandles, OmniPvdWriter* omniWriter); + +/** +\brief Write the PxRigidActor instance to omnipvd. +\param[in] physxActor describes the PxRigidActor instance that is used to represent the vehicle's rigid body in PhysX. +\param[in] attributeHandles contains a general description of vehicle parameters and states that will be reflected in omnipvd. +\param[in] objectHandles contains unique handles for the parameters and states of each vehicle instance. +\param[in] omniWriter is an OmniPvdWriter instance used to communicate state and parameter data to omnipvd. +\note If physxActor is NULL and the corresponding argument in PxVehiclePvdPhysXRigidActorRegister was not NULL, the corresponding data will not be updated in omnipvd. +\note objectHandles must be non-NULL. +\note omniWriter must be non-NULL. +@see PxVehiclePvdAttributesCreate +@see PxVehiclePvdObjectCreate +@see PxVehiclePvdPhysXRigidActorRegister +*/ +void PxVehiclePvdPhysXRigidActorWrite +(const PxVehiclePhysXActor* physxActor, + const PxVehiclePvdAttributeHandles& attributeHandles, + const PxVehiclePvdObjectHandles& objectHandles, OmniPvdWriter* omniWriter); + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/pvd/PxVehiclePvdHelpers.h b/Source/ThirdParty/PhysX/vehicle2/pvd/PxVehiclePvdHelpers.h new file mode 100644 index 000000000..1151dee8d --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/pvd/PxVehiclePvdHelpers.h @@ -0,0 +1,114 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "foundation/PxSimpleTypes.h" + +class OmniPvdWriter; +namespace physx +{ +class PxAllocatorCallback; +namespace vehicle2 +{ +struct PxVehiclePvdAttributeHandles; +struct PxVehiclePvdObjectHandles; +} +} + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +/** +\brief Create the attribute handles necessary to reflect vehicles in omnipvd. +\param[in] allocator is used to allocate the memory used to store the attribute handles. +\param[in] omniWriter is used to register the attribute handles with omnipvd. +\note omniWriter must be a valid pointer to an instance of OmniPvdWriter. +@see PxVehicleSimulationContext +@see PxVehiclePVDComponent +@see PxVehiclePvdAttributesRelease +*/ +PxVehiclePvdAttributeHandles* PxVehiclePvdAttributesCreate +(PxAllocatorCallback& allocator, OmniPvdWriter* omniWriter); + +/** +\brief Destory the attribute handles created by PxVehiclePvdAttributesCreate(). +\param[in] allocator must be the instance used by PxVehiclePvdObjectCreate(). +\param[in] omniWriter must point to the same OmniPvdWriter instance used for the complementary call to PxVehiclePvdAttributesCreate(). +\param[in] attributeHandles is the PxVehiclePvdAttributeHandles created by PxVehiclePvdAttributesCreate(). +@see PxVehiclePvdAttributesCreate +*/ +void PxVehiclePvdAttributesRelease +(PxAllocatorCallback& allocator, OmniPvdWriter* omniWriter, PxVehiclePvdAttributeHandles* attributeHandles); + +/** +\brief Create omnipvd objects that will be used to reflect an individual veicle in omnipvd. +\param[in] nbWheels must be greater than or equal to the number of wheels on the vehicle. +\param[in] nbAntirolls must be greater than or equal to the number of antiroll bars on the vehicle. +\param[in] maxNbPhysxMaterialFrictions must be greater than or equal to the number of PxPhysXMaterialFriction instances associated with any wheel of the vehicle. +\param[in] contextHandle is typically used to associated vehicles with a particular scene or group. +\param[in] attributeHandles is the PxVehiclePvdAttributeHandles instance returned by PxVehiclePvdAttributesCreate() +\param[in] omniWriter is used to register the attribute handles with omnipvd. +\param[in] allocator is used to allocate the memory used to store handles to the created omnipvd objects. +\note PxVehiclePvdObjectCreate() must be called after PxVehiclePvdAttributesCreate(). +@see PxVehicleAxleDescription +@see PxVehicleAntiRollForceParams +@see PxVehiclePhysXMaterialFrictionParams +@see PxVehiclePVDComponent +@see PxVehiclePvdAttributesCreate +*/ +PxVehiclePvdObjectHandles* PxVehiclePvdObjectCreate +(const PxU32 nbWheels, const PxU32 nbAntirolls, const PxU32 maxNbPhysxMaterialFrictions, + const PxU64 contextHandle, const PxVehiclePvdAttributeHandles& attributeHandles, + OmniPvdWriter* omniWriter, PxAllocatorCallback& allocator); + +/** +\brief Destroy the PxVehiclePvdObjectHandles instance created by PxVehiclePvdObjectCreate(). +\param[in] attributeHandles is the PxVehiclePvdAttributeHandles created by PxVehiclePvdAttributesCreate(). +\param[in] omniWriter is used to register the attribute handles with omnipvd. +\param[in] allocator must be the instance used by PxVehiclePvdObjectCreate(). +\param[in] objectHandles is the PxVehiclePvdObjectHandles that was created by PxVehiclePvdObjectCreate(). +*/ +void PxVehiclePvdObjectRelease +(const PxVehiclePvdAttributeHandles& attributeHandles, + OmniPvdWriter* omniWriter, PxAllocatorCallback& allocator, PxVehiclePvdObjectHandles* objectHandles); + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/rigidBody/PxVehicleRigidBodyComponents.h b/Source/ThirdParty/PhysX/vehicle2/rigidBody/PxVehicleRigidBodyComponents.h new file mode 100644 index 000000000..c4a976660 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/rigidBody/PxVehicleRigidBodyComponents.h @@ -0,0 +1,114 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ +#include "vehicle2/PxVehicleParams.h" +#include "vehicle2/PxVehicleComponent.h" + +#include "PxVehicleRigidBodyFunctions.h" + +#include "common/PxProfileZone.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +/** +\brief Forward integrate the momentum and pose of the vehicle's rigid body after applying forces and torques +from the suspension, tires and anti-roll bars. +*/ +class PxVehicleRigidBodyComponent : public PxVehicleComponent +{ +public: + + PxVehicleRigidBodyComponent() : PxVehicleComponent() {} + virtual ~PxVehicleRigidBodyComponent() {} + + /** + \brief Retrieve pointers to the parameter and state data required to update the dynamic state of a rigid body. + \param[out] axleDescription must be returned as a non-null pointer to a single PxVehicleAxleDescription instance that describes the wheels and axles + of the vehicle. + \param[out] rigidBodyParams must be returned as a non-null pointer to a single PxVehicleRigidBodyParams instance that describes the mass and moment of + inertia of the rigid body. + \param[out] suspensionForces must be returned as a non-null pointer to an array of suspension forces and torques in the world frame. + The suspension forces and torques will be applied to the rigid body to update *rigidBodyState*. + \param[out] tireForces must be returned as a non-null pointer to an array of tire forces and torques in the world frame. + The tire forces and torques will be applied to the rigid body to update *rigidBodyState*. + \param[out] antiRollTorque may be returned an optionally non-null pointer to a single PxVehicleAntiRollTorque instance that contains the accumulated anti-roll + torque to apply to the rigid body. + \param[out] rigidBodyState imust be returned as a non-null pointer to a single PxVehicleRigidBodyState instance that is to be forward integrated. + \note The suspensionForces array must contain an entry for each wheel listed as an active wheel in axleDescription. + \note The tireForces array must contain an entry for each wheel listed as an active wheel in axleDescription. + \note If antiRollTorque is returned as a null pointer then zero anti-roll torque will be applied to the rigid body. + */ + virtual void getDataForRigidBodyComponent( + const PxVehicleAxleDescription*& axleDescription, + const PxVehicleRigidBodyParams*& rigidBodyParams, + PxVehicleArrayData& suspensionForces, + PxVehicleArrayData& tireForces, + const PxVehicleAntiRollTorque*& antiRollTorque, + PxVehicleRigidBodyState*& rigidBodyState) = 0; + + virtual bool update(const PxReal dt, const PxVehicleSimulationContext& context) + { + PX_PROFILE_ZONE("PxVehicleRigidBodyComponent::update", 0); + + const PxVehicleAxleDescription* axleDescription; + const PxVehicleRigidBodyParams* rigidBodyParams; + PxVehicleArrayData suspensionForces; + PxVehicleArrayData tireForces; + const PxVehicleAntiRollTorque* antiRollTorque; + PxVehicleRigidBodyState* rigidBodyState; + + getDataForRigidBodyComponent(axleDescription, rigidBodyParams, + suspensionForces, tireForces, antiRollTorque, + rigidBodyState); + + PxVehicleRigidBodyUpdate( + *axleDescription, *rigidBodyParams, + suspensionForces, tireForces, antiRollTorque, + dt, context.gravity, + *rigidBodyState); + + return true; + } +}; + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/rigidBody/PxVehicleRigidBodyFunctions.h b/Source/ThirdParty/PhysX/vehicle2/rigidBody/PxVehicleRigidBodyFunctions.h new file mode 100644 index 000000000..c1e555ea6 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/rigidBody/PxVehicleRigidBodyFunctions.h @@ -0,0 +1,80 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "foundation/PxVec3.h" +#include "foundation/PxSimpleTypes.h" +#include "vehicle2/PxVehicleParams.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +struct PxVehicleRigidBodyParams; +struct PxVehicleSuspensionForce; +struct PxVehicleTireForce; +struct PxVehicleAntiRollTorque; +struct PxVehicleRigidBodyState; + +/** +\brief Forward integrate rigid body state. +\param[in] axleDescription is a description of the axles of the vehicle and the wheels on each axle. +\param[in] rigidBodyParams is a description of rigid body mass and moment of inertia. +\param[in] suspensionForces is an array of suspension forces and torques in the world frame to be applied to the rigid body. +\param[in] tireForces is an array of tire forces and torques in the world frame to be applied to the rigid body. +\param[in] antiRollTorque is an optional pointer to a single PxVehicleAntiRollTorque instance that contains the accumulated anti-roll +torque to apply to the rigid body. +\param[in] dt is the timestep of the forward integration. +\param[in] gravity is gravitational acceleration. +\param[in,out] rigidBodyState is the rigid body state that is to be updated. +\note The suspensionForces array must contain an entry for each wheel listed as an active wheel in axleDescription. +\note The tireForces array must contain an entry for each wheel listed as an active wheel in axleDescription. +\note If antiRollTorque is a null pointer then zero anti-roll torque will be applied to the rigid body. +*/ +void PxVehicleRigidBodyUpdate + (const PxVehicleAxleDescription& axleDescription, const PxVehicleRigidBodyParams& rigidBodyParams, + const PxVehicleArrayData& suspensionForces, + const PxVehicleArrayData& tireForces, + const PxVehicleAntiRollTorque* antiRollTorque, + const PxReal dt, const PxVec3& gravity, + PxVehicleRigidBodyState& rigidBodyState); + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/rigidBody/PxVehicleRigidBodyParams.h b/Source/ThirdParty/PhysX/vehicle2/rigidBody/PxVehicleRigidBodyParams.h new file mode 100644 index 000000000..8fe3dea37 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/rigidBody/PxVehicleRigidBodyParams.h @@ -0,0 +1,91 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "foundation/PxFoundation.h" +#include "vehicle2/PxVehicleParams.h" +#include "vehicle2/PxVehicleFunctions.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +/** +\brief The properties of the rigid body. +*/ +struct PxVehicleRigidBodyParams +{ + /** + \brief The mass of the rigid body. + + Range: (0, inf)
+ Unit: mass + */ + PxReal mass; + + /** + \brief The moment of inertia of the rigid body. + + Range: (0, inf)
+ Unit: mass * (length^2) + */ + PxVec3 moi; + + PX_FORCE_INLINE PxVehicleRigidBodyParams transformAndScale( + const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const + { + PxVehicleRigidBodyParams r = *this; + r.moi = PxVehicleTransformFrameToFrame(srcFrame, trgFrame, moi).abs(); + const PxReal scale = trgScale.scale/srcScale.scale; + r.moi *= (scale*scale); + return r; + } + + PX_FORCE_INLINE bool isValid() const + { + PX_CHECK_AND_RETURN_VAL(mass > 0.0f, "PxVehicleRigidBodyParams.mass must be greater than zero", false); + PX_CHECK_AND_RETURN_VAL(moi.x > 0.0f && moi.y > 0.0f && moi.z> 0.0f, "PxVehicleRigidBodyParams.moi must be greater than zero", false); + return true; + } +}; + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ + diff --git a/Source/ThirdParty/PhysX/vehicle2/rigidBody/PxVehicleRigidBodyStates.h b/Source/ThirdParty/PhysX/vehicle2/rigidBody/PxVehicleRigidBodyStates.h new file mode 100644 index 000000000..ce2b33e9a --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/rigidBody/PxVehicleRigidBodyStates.h @@ -0,0 +1,98 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "foundation/PxTransform.h" +#include "foundation/PxVec3.h" +#include "vehicle2/PxVehicleParams.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +struct PxVehicleRigidBodyState +{ + PxTransform pose; //!< the body's pose (in world space) + PxVec3 linearVelocity; //!< the body's linear velocity (in world space) + PxVec3 angularVelocity; //!< the body's angular velocity (in world space) + PxVec3 previousLinearVelocity; //!< the previous linear velocity of the body (in world space) + PxVec3 previousAngularVelocity; //!< the previous angular velocity of the body (in world space) + PxVec3 externalForce; //!< external force (in world space) affecting the rigid body (usually excluding gravitational force) + PxVec3 externalTorque; //!< external torque (in world space) affecting the rigid body + + PX_FORCE_INLINE void setToDefault() + { + pose = PxTransform(PxIdentity); + linearVelocity = PxVec3(PxZero); + angularVelocity = PxVec3(PxZero); + externalForce = PxVec3(PxZero); + externalTorque = PxVec3(PxZero); + } + + /** + \brief Compute the vertical speed of the rigid body transformed to the world frame. + \param[in] frame describes the axes of the vehicle + */ + PX_FORCE_INLINE PxReal getVerticalSpeed(const PxVehicleFrame& frame) const + { + return linearVelocity.dot(pose.q.rotate(frame.getVrtAxis())); + } + + /** + \param[in] frame describes the axes of the vehicle + \brief Compute the lateral speed of the rigid body transformed to the world frame. + */ + PX_FORCE_INLINE PxReal getLateralSpeed(const PxVehicleFrame& frame) const + { + return linearVelocity.dot(pose.q.rotate(frame.getLatAxis())); + } + + /** + \brief Compute the longitudinal speed of the rigid body transformed to the world frame. + \param[in] frame describes the axes of the vehicle + */ + PX_FORCE_INLINE PxReal getLongitudinalSpeed(const PxVehicleFrame& frame) const + { + return linearVelocity.dot(pose.q.rotate(frame.getLngAxis())); + } +}; + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/roadGeometry/PxVehicleRoadGeometryState.h b/Source/ThirdParty/PhysX/vehicle2/roadGeometry/PxVehicleRoadGeometryState.h new file mode 100644 index 000000000..1c4a9e2e2 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/roadGeometry/PxVehicleRoadGeometryState.h @@ -0,0 +1,63 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "foundation/PxPlane.h" +#include "foundation/PxMemory.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +struct PxVehicleRoadGeometryState +{ + PxPlane plane; //!< the plane under the wheel + PxReal friction; //!< the friction to be used by the tire model + PxVec3 velocity; //!< the velocity of the road geometry + bool hitState; //!< true if a plane is found, false if there is no plane. + + PX_FORCE_INLINE void setToDefault() + { + PxMemZero(this, sizeof(PxVehicleRoadGeometryState)); + } +}; + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/steering/PxVehicleSteeringFunctions.h b/Source/ThirdParty/PhysX/vehicle2/steering/PxVehicleSteeringFunctions.h new file mode 100644 index 000000000..3b77b3921 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/steering/PxVehicleSteeringFunctions.h @@ -0,0 +1,80 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "foundation/PxPreprocessor.h" +#include "foundation/PxSimpleTypes.h" + +#include "vehicle2/PxVehicleParams.h" +#include "PxVehicleSteeringParams.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +struct PxVehicleCommandState; + +/** +\brief Compute the yaw angle response to a steer command. +\param[in] steer is the input steer command value. +\param[in] longitudinalSpeed is the longitudinal speed of the vehicle. +\param[in] wheelId specifies the wheel to have its steer response computed. +\param[in] steerResponseParmas specifies the per wheel yaw angle response to the steer command as a nonlinear function of steer command and longitudinal speed. +\param[out] steerResponseState is the yaw angle response to the input steer command. +*/ +void PxVehicleSteerCommandResponseUpdate +(const PxReal steer, const PxReal longitudinalSpeed, + const PxU32 wheelId, const PxVehicleSteerCommandResponseParams& steerResponseParmas, + PxReal& steerResponseState); + +/** +\brief Account for Ackermann correction by modifying the per wheel steer response multipliers to engineer an asymmetric steer response across axles. +\param[in] steer is the input steer command value. +\param[in] steerResponseParmas describes the maximum response and a response multiplier per axle. +\param[in] ackermannParams is an array that describes the wheels affected by Ackerman steer correction. +\param[in,out] steerResponseStates contains the corrected per wheel steer response multipliers that take account of Ackermann steer correction. +*/ +void PxVehicleAckermannSteerUpdate +(const PxReal steer, const PxVehicleSteerCommandResponseParams& steerResponseParmas, + const PxVehicleSizedArrayData& ackermannParams, + PxVehicleArrayData& steerResponseStates); + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/steering/PxVehicleSteeringParams.h b/Source/ThirdParty/PhysX/vehicle2/steering/PxVehicleSteeringParams.h new file mode 100644 index 000000000..f40cd14f2 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/steering/PxVehicleSteeringParams.h @@ -0,0 +1,122 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once +/** \addtogroup vehicle2 + @{ +*/ + +#include "foundation/PxFoundation.h" + +#include "vehicle2/PxVehicleParams.h" + +#include "vehicle2/commands/PxVehicleCommandParams.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +struct PxVehicleFrame; +struct PxVehicleScale; + +/** +\brief Distribute a steer response to the wheels of a vehicle. +\note The steer angle applied to each wheel on the ith wheel is steerCommand * maxResponse * wheelResponseMultipliers[i]. +\note A typical use case is to set maxResponse to be the vehicle's maximum achievable steer angle +that occurs when the steer command is equal to 1.0. The array wheelResponseMultipliers[i] would then be used +to specify the maximum achievable steer angle per wheel as a fractional multiplier of the vehicle's maximum achievable steer angle. +*/ +struct PxVehicleSteerCommandResponseParams : public PxVehicleCommandResponseParams +{ + PX_FORCE_INLINE PxVehicleSteerCommandResponseParams transformAndScale( + const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const + { + PX_UNUSED(srcFrame); + PX_UNUSED(trgFrame); + PX_UNUSED(srcScale); + PX_UNUSED(trgScale); + return *this; + } + + PX_FORCE_INLINE bool isValid(const PxVehicleAxleDescription& axleDesc) const + { + if (!axleDesc.isValid()) + return false; + for (PxU32 i = 0; i < axleDesc.nbWheels; i++) + { + PX_CHECK_AND_RETURN_VAL(PxAbs(maxResponse*wheelResponseMultipliers[axleDesc.wheelIdsInAxleOrder[i]]) <= PxPi, + "PxVehicleSteerCommandResponseParams.maxResponse*PxVehicleSteerCommandResponseParams.wheelResponseMultipliers[i] must be in range [-Pi, Pi]", false); + } + return true; + } +}; + +/** +\brief A description of a single axle that is to be affected by Ackermann steer correction. +*/ +struct PxVehicleAckermannParams +{ + PxU32 wheelIds[2]; //!< wheelIds[0] is the id of the wheel that is negative along the lateral axis, wheelIds[1] is the wheel id that is positive along the lateral axis. + PxReal wheelBase; //!< wheelBase is the longitudinal distance between the axle that is affected by Ackermann correction and a reference axle. + PxReal trackWidth; //!< trackWidth is the width of the axle specified by #wheelIds + PxReal strength; //!< is the strength of the correction with 0 denoting no correction and 1 denoting perfect correction. + + PX_FORCE_INLINE bool isValid(const PxVehicleAxleDescription& axleDesc) const + { + PX_CHECK_AND_RETURN_VAL(0.0f == strength || wheelIds[0] < axleDesc.getNbWheels(), "PxVehicleAckermannParams.wheelIds[0] must be valid wheel", false); + PX_CHECK_AND_RETURN_VAL(0.0f == strength || wheelIds[1] < axleDesc.getNbWheels(), "PxVehicleAckermannParams.wheelIds[1] must be a valid wheel", false); + PX_CHECK_AND_RETURN_VAL(0.0f == strength || wheelIds[0] != wheelIds[1], "PxVehicleAckermannParams.wheelIds[0] and PxVehicleAckermannParams.wheelIds[1] must reference two different wheels", false); + PX_CHECK_AND_RETURN_VAL(0.0f == strength || wheelBase > 0.0f, "PxVehicleAckermannParams.wheelBase must be greater than zero", false); + PX_CHECK_AND_RETURN_VAL(0.0f == strength || trackWidth > 0.0f, "PxVehicleAckermannParams.trackWidth must be greater than zero", false); + PX_CHECK_AND_RETURN_VAL(strength >= 0.0f && strength <= 1.0f, "PxVehicleAckermannParams.strength must be in range [0,1]", false); + PX_UNUSED(axleDesc); + return true; + } + + PX_FORCE_INLINE PxVehicleAckermannParams transformAndScale( + const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const + { + PX_UNUSED(srcFrame); + PX_UNUSED(trgFrame); + PxVehicleAckermannParams r = *this; + const PxReal scale = trgScale.scale / srcScale.scale; + r.wheelBase *= scale; + r.trackWidth *= scale; + return r; + } +}; + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/suspension/PxVehicleSuspensionComponents.h b/Source/ThirdParty/PhysX/vehicle2/suspension/PxVehicleSuspensionComponents.h new file mode 100644 index 000000000..fd6201fd8 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/suspension/PxVehicleSuspensionComponents.h @@ -0,0 +1,328 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "vehicle2/PxVehicleParams.h" +#include "vehicle2/PxVehicleComponent.h" + +#include "vehicle2/commands/PxVehicleCommandStates.h" +#include "vehicle2/commands/PxVehicleCommandHelpers.h" +#include "vehicle2/rigidBody/PxVehicleRigidBodyParams.h" +#include "vehicle2/roadGeometry/PxVehicleRoadGeometryState.h" +#include "vehicle2/wheel/PxVehicleWheelParams.h" + +#include "PxVehicleSuspensionParams.h" +#include "PxVehicleSuspensionStates.h" +#include "PxVehicleSuspensionFunctions.h" + +#include "common/PxProfileZone.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + + +class PxVehicleSuspensionComponent : public PxVehicleComponent +{ +public: + + PxVehicleSuspensionComponent() : PxVehicleComponent() {} + virtual ~PxVehicleSuspensionComponent() {} + + /** + \brief Retrieve pointers to the parameter and state data required to compute the suspension state and the forces/torques that arise from the suspension state. + \param[out] axleDescription must be returned as a non-null pointer to a single PxVehicleAxleDescription instance that describes the wheels and axles + of the vehicle. + \param[out] rigidBodyParams must be returned as a a non-null pointer to a single PxVehicleRigidBodyParams instance that describes the mass and moment + of inertia of the vehicle's rigid body. + \param[out] suspensionStateCalculationParams must be returned as a non-null pointer to a single PxVehicleSuspensionStateCalculationParams instance + that describes the jounce computation type etc. + \param[out] steerResponseStates must be returned as a non-null pointer to a single PxVehicleSteerCommandResponseStates instance that describes the steer + state of the wheels. + \param[out] rigidBodyState must be returned as a non-null pointer to a single PxVehicleRigidBodyState instance that describes the pose and momentum of + the vehicle's rigid body. + \param[out] wheelParams must be set to a non-null pointer to an array of PxVehicleWheelParams containing per-wheel parameters for each wheel + referenced by axleDescription. + \param[out] suspensionParams must be set to a non-null pointer to an array of PxVehicleSuspensionParams containing per-wheel parameters for each + wheel referenced by axleDescription. + \param[out] suspensionComplianceParams must be set to a non-null pointer to an array of PxVehicleSuspensionComplianceParams containing per-wheel + parameters for each wheel referenced by axleDescription. + \param[out] suspensionForceParams must be set to a non-null pointer to an array of PxVehicleSuspensionForceParams containing per-wheel parameters + for each wheel referenced by axleDescription. + \param[out] antiRollForceParams is optionally returned as a non-null pointer to an array of PxVehicleAntiRollForceParams with each element in the array + describing a unique anti-roll bar connecting a pair of wheels. + \param[out] wheelRoadGeomStates must be set to non-null pointer to an array of PxVehicleRoadGeometryState containing per-wheel road geometry for + each wheel referenced by axleDescription. + \param[out] suspensionStates must be set to a non-null pointer to an array of PxVehicleSuspensionState containing per-wheel suspension state for each + wheel referenced by axleDescription. + \param[out] suspensionComplianceStates must be set to a non-null pointer to an array of PxVehicleSuspensionComplianceState containing per-wheel suspension + compliance state for each wheel referenced by axleDescription. + \param[out] suspensionForces must be set to a non-null pointer to an array of PxVehicleSuspensionForce containing per-wheel suspension forces for each + wheel referenced by axleDescription. + \param[out] antiRollTorque is optionally returned as a non-null pointer to a single PxVehicleAntiRollTorque instance that will store the accumulated anti-roll + torque to be applied to the vheicle's rigid body. + \note antiRollForceParams and antiRollTorque should be returned either both non-NULL or both NULL. + */ + virtual void getDataForSuspensionComponent( + const PxVehicleAxleDescription*& axleDescription, + const PxVehicleRigidBodyParams*& rigidBodyParams, + const PxVehicleSuspensionStateCalculationParams*& suspensionStateCalculationParams, + PxVehicleArrayData& steerResponseStates, + const PxVehicleRigidBodyState*& rigidBodyState, + PxVehicleArrayData& wheelParams, + PxVehicleArrayData& suspensionParams, + PxVehicleArrayData& suspensionComplianceParams, + PxVehicleArrayData& suspensionForceParams, + PxVehicleSizedArrayData& antiRollForceParams, + PxVehicleArrayData& wheelRoadGeomStates, + PxVehicleArrayData& suspensionStates, + PxVehicleArrayData& suspensionComplianceStates, + PxVehicleArrayData& suspensionForces, + PxVehicleAntiRollTorque*& antiRollTorque) = 0; + + /** + \brief Update the suspension state and suspension compliance state and use those updated states to compute suspension and anti-roll forces/torques + to apply to the vehicle's rigid body. + \param[in] dt is the simulation time that has passed since the last call to PxVehicleSuspensionComponent::update() + \param[in] context describes a variety of global simulation constants such as frame and scale of the simulation and the gravitational acceleration + of the simulated environment. + \note The suspension and anti-roll forces/torques are computed in the world frame. + */ + virtual bool update(const PxReal dt, const PxVehicleSimulationContext& context) + { + PX_PROFILE_ZONE("PxVehicleSuspensionComponent::update", 0); + + const PxVehicleAxleDescription* axleDescription; + const PxVehicleRigidBodyParams* rigidBodyParams; + const PxVehicleSuspensionStateCalculationParams* suspensionStateCalculationParams; + PxVehicleArrayData steerResponseStates; + const PxVehicleRigidBodyState* rigidBodyState; + PxVehicleArrayData wheelParams; + PxVehicleArrayData suspensionParams; + PxVehicleArrayData suspensionComplianceParams; + PxVehicleArrayData suspensionForceParams; + PxVehicleSizedArrayData antiRollForceParams; + PxVehicleArrayData wheelRoadGeomStates; + PxVehicleArrayData suspensionStates; + PxVehicleArrayData suspensionComplianceStates; + PxVehicleArrayData suspensionForces; + PxVehicleAntiRollTorque* antiRollTorque; + + getDataForSuspensionComponent(axleDescription, rigidBodyParams, suspensionStateCalculationParams, + steerResponseStates, rigidBodyState, + wheelParams, suspensionParams, + suspensionComplianceParams, suspensionForceParams, antiRollForceParams, + wheelRoadGeomStates, suspensionStates, suspensionComplianceStates, + suspensionForces, antiRollTorque); + + for (PxU32 i = 0; i < axleDescription->nbWheels; i++) + { + const PxU32 wheelId = axleDescription->wheelIdsInAxleOrder[i]; + + //Update the suspension state (jounce, jounce speed) + PxVehicleSuspensionStateUpdate( + wheelParams[wheelId], suspensionParams[wheelId], *suspensionStateCalculationParams, + suspensionForceParams[wheelId].stiffness, suspensionForceParams[wheelId].damping, + steerResponseStates[wheelId], wheelRoadGeomStates[wheelId], + *rigidBodyState, + dt, context.frame, context.gravity, + suspensionStates[wheelId]); + + //Update the compliance from the suspension state. + PxVehicleSuspensionComplianceUpdate( + suspensionParams[wheelId], suspensionComplianceParams[wheelId], + suspensionStates[wheelId], + suspensionComplianceStates[wheelId]); + + //Compute the suspension force from the suspension and compliance states. + PxVehicleSuspensionForceUpdate( + suspensionParams[wheelId], suspensionForceParams[wheelId], + wheelRoadGeomStates[wheelId], suspensionStates[wheelId], + suspensionComplianceStates[wheelId], *rigidBodyState, + context.gravity, rigidBodyParams->mass, + suspensionForces[wheelId]); + } + + if (antiRollForceParams.size>0 && antiRollTorque) + { + PxVehicleAntiRollForceUpdate( + suspensionParams, antiRollForceParams, + suspensionStates.getConst(), suspensionComplianceStates.getConst(), *rigidBodyState, + *antiRollTorque); + } + + return true; + } +}; + +/** + * @deprecated + */ +class PX_DEPRECATED PxVehicleLegacySuspensionComponent : public PxVehicleComponent +{ +public: + + PxVehicleLegacySuspensionComponent() : PxVehicleComponent() {} + virtual ~PxVehicleLegacySuspensionComponent() {} + + /** + \brief Retrieve pointers to the parameter and state data required to compute the suspension state and the forces/torques that arise from the suspension state. + \param[out] axleDescription must be returned as a non-null pointer to a single PxVehicleAxleDescription instance that describes the wheels and axles + of the vehicle. + \param[out] suspensionStateCalculationParams must be returned as a non-null pointer to a single PxVehicleSuspensionStateCalculationParams instance + that describes the jounce computation type etc. + \param[out] steerResponseStates must be returned as a non-null pointer to a single PxVehicleSteerCommandResponseStates instance that describes the steer + state of the wheels. + \param[out] rigidBodyState must be returned as a non-null pointer to a single PxVehicleRigidBodyState instance that describes the pose and momentum of + the vehicle's rigid body. + \param[out] wheelParams must be set to a non-null pointer to an array of PxVehicleWheelParams containing per-wheel parameters for each wheel + referenced by axleDescription. + \param[out] suspensionParams must be set to a non-null pointer to an array of PxVehicleSuspensionParams containing per-wheel parameters for each + wheel referenced by axleDescription. + \param[out] suspensionComplianceParams must be set to a non-null pointer to an array of PxVehicleSuspensionComplianceParams containing per-wheel + parameters for each wheel referenced by axleDescription. + \param[out] suspensionForceParams must be set to a non-null pointer to an array of PxVehicleSuspensionForceLegacyParams containing per-wheel parameters + for each wheel referenced by axleDescription. + \param[out] antiRollForceParams is optionally returned as a non-null pointer to an array of PxVehicleAntiRollForceParams with each element in the array + describing a unique anti-roll bar connecting a pair of wheels. + \param[out] wheelRoadGeomStates must be set to non-null pointer to an array of PxVehicleRoadGeometryState containing per-wheel road geometry for + each wheel referenced by axleDescription. + \param[out] suspensionStates must be set to a non-null pointer to an array of PxVehicleSuspensionState containing per-wheel suspension state for each + wheel referenced by axleDescription. + \param[out] suspensionComplianceStates must be set to a non-null pointer to an array of PxVehicleSuspensionComplianceState containing per-wheel suspension + compliance state for each wheel referenced by axleDescription. + \param[out] suspensionForces must be set to a non-null pointer to an array of PxVehicleSuspensionForce containing per-wheel suspension forces for each + wheel referenced by axleDescription. + \param[out] antiRollTorque is optionally returned as a non-null pointer to a single PxVehicleAntiRollTorque instance that will store the accumulated anti-roll + torque to be applied to the vheicle's rigid body. + \note antiRollForceParams and antiRollTorque should be returned either both non-NULL or both NULL. + */ + virtual void getDataForLegacySuspensionComponent( + const PxVehicleAxleDescription*& axleDescription, + const PxVehicleSuspensionStateCalculationParams*& suspensionStateCalculationParams, + PxVehicleArrayData& steerResponseStates, + const PxVehicleRigidBodyState*& rigidBodyState, + PxVehicleArrayData& wheelParams, + PxVehicleArrayData& suspensionParams, + PxVehicleArrayData& suspensionComplianceParams, + PxVehicleArrayData& suspensionForceParams, + PxVehicleSizedArrayData& antiRollForceParams, + PxVehicleArrayData& wheelRoadGeomStates, + PxVehicleArrayData& suspensionStates, + PxVehicleArrayData& suspensionComplianceStates, + PxVehicleArrayData& suspensionForces, + PxVehicleAntiRollTorque*& antiRollTorque) = 0; + + /** + \brief Update the suspension state and suspension compliance state and use those updated states to compute suspension and anti-roll forces/torques + to apply to the vehicle's rigid body. + \param[in] dt is the simulation time that has passed since the last call to PxVehicleSuspensionComponent::update() + \param[in] context describes a variety of global simulation constants such as frame and scale of the simulation and the gravitational acceleration + of the simulated environment. + \note The suspension and anti-roll forces are computed in the world frame. + \note PxVehicleLegacySuspensionComponent::update() implements legacy suspension behaviour. + */ + virtual bool update(const PxReal dt, const PxVehicleSimulationContext& context) + { + PX_PROFILE_ZONE("PxVehicleLegacySuspensionComponent::update", 0); + + const PxVehicleAxleDescription* axleDescription; + const PxVehicleSuspensionStateCalculationParams* suspensionStateCalculationParams; + PxVehicleArrayData steerResponseStates; + const PxVehicleRigidBodyState* rigidBodyState; + PxVehicleArrayData wheelParams; + PxVehicleArrayData suspensionParams; + PxVehicleArrayData suspensionComplianceParams; + PxVehicleArrayData suspensionForceParams; + PxVehicleSizedArrayData antiRollForceParams; + PxVehicleArrayData wheelRoadGeomStates; + PxVehicleArrayData suspensionStates; + PxVehicleArrayData suspensionComplianceStates; + PxVehicleArrayData suspensionForces; + PxVehicleAntiRollTorque* antiRollTorque; + + getDataForLegacySuspensionComponent(axleDescription, suspensionStateCalculationParams, + steerResponseStates, rigidBodyState, wheelParams, + suspensionParams, suspensionComplianceParams, + suspensionForceParams, antiRollForceParams, + wheelRoadGeomStates, suspensionStates, suspensionComplianceStates, + suspensionForces, antiRollTorque); + + for (PxU32 i = 0; i < axleDescription->nbWheels; i++) + { + const PxU32 wheelId = axleDescription->wheelIdsInAxleOrder[i]; + + //Update the suspension state (jounce, jounce speed) + PxVehicleSuspensionStateUpdate( + wheelParams[wheelId], suspensionParams[wheelId], *suspensionStateCalculationParams, + suspensionForceParams[wheelId].stiffness, suspensionForceParams[wheelId].damping, + steerResponseStates[wheelId], wheelRoadGeomStates[wheelId], *rigidBodyState, + dt, context.frame, context.gravity, + suspensionStates[wheelId]); + + //Update the compliance from the suspension state. + PxVehicleSuspensionComplianceUpdate( + suspensionParams[wheelId], suspensionComplianceParams[wheelId], + suspensionStates[wheelId], + suspensionComplianceStates[wheelId]); + + //Compute the suspension force from the suspension and compliance states. + PxVehicleSuspensionLegacyForceUpdate( + suspensionParams[wheelId], suspensionForceParams[wheelId], + wheelRoadGeomStates[wheelId], suspensionStates[wheelId], + suspensionComplianceStates[wheelId], *rigidBodyState, + context.gravity, + suspensionForces[wheelId]); + } + + if (antiRollForceParams.size>0 && antiRollTorque) + { + PxVehicleAntiRollForceUpdate( + suspensionParams, antiRollForceParams, + suspensionStates.getConst(), suspensionComplianceStates.getConst(), *rigidBodyState, + *antiRollTorque); + } + + return true; + } +}; + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/suspension/PxVehicleSuspensionFunctions.h b/Source/ThirdParty/PhysX/vehicle2/suspension/PxVehicleSuspensionFunctions.h new file mode 100644 index 000000000..5e63350af --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/suspension/PxVehicleSuspensionFunctions.h @@ -0,0 +1,166 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "foundation/PxVec3.h" +#include "foundation/PxSimpleTypes.h" +#include "vehicle2/PxVehicleParams.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +struct PxVehicleWheelParams; +struct PxVehicleSuspensionParams; +struct PxVehicleSuspensionStateCalculationParams; +struct PxVehicleRoadGeometryState; +struct PxVehicleRigidBodyState; +struct PxVehicleSuspensionState; +struct PxVehicleSuspensionComplianceParams; +struct PxVehicleSuspensionComplianceState; +struct PxVehicleSuspensionForceParams; +struct PxVehicleSuspensionForce; +struct PxVehicleSuspensionForceLegacyParams; +struct PxVehicleAntiRollForceParams; +struct PxVehicleAntiRollTorque; + +/** +\brief Compute the suspension compression and compression speed for a single suspension. +\param[in] wheelParams is a description of the radius and half-width of the wheel on the suspension. +\param[in] suspensionParams is a description of the suspension and wheel frames. +\param[in] suspensionStateCalcParams specifies whether to compute the suspension compression by either +raycasting or sweeping against the plane of the road geometry under the wheel. +\param[in] suspensionStiffness is the stiffness of the suspension +\param[in] suspensionDamping is the damping rate of the suspension. +or whether to apply a limit to the expansion speed so that the wheel may not reach the ground. +\param[in] steerAngle is the yaw angle (in radians) of the wheel. +\param[in] roadGeometryState describes the plane under the wheel. +\param[in] rigidBodyState describes the pose of the rigid body. +\param[in] dt is the simulation time that has lapsed since the last call to PxVehicleSuspensionStateUpdate +\param[in] frame describes the longitudinal, lateral and vertical axes of the vehicle. +\param[in] gravity is the gravitational acceleration that acts on the suspension sprung mass. +\param[in,out] suspState is the compression (jounce) and compression speed of the suspension. +*/ +void PxVehicleSuspensionStateUpdate +(const PxVehicleWheelParams& wheelParams, const PxVehicleSuspensionParams& suspensionParams, const PxVehicleSuspensionStateCalculationParams& suspensionStateCalcParams, + const PxReal suspensionStiffness, const PxReal suspensionDamping, + const PxReal steerAngle, const PxVehicleRoadGeometryState& roadGeometryState, const PxVehicleRigidBodyState& rigidBodyState, + const PxReal dt, const PxVehicleFrame& frame, const PxVec3& gravity, + PxVehicleSuspensionState& suspState); + +/** +\brief Compute the toe, camber and force application points that are affected by suspension compression. +\param[in] suspensionParams is a description of the suspension and wheel frames. +\param[in] complianceParams describes how toe, camber and force application points are affected by suspension compression. +\param[in] suspensionState describes the current suspension compression. +\param[in] complianceState is the computed toe, camber and force application points. +*/ +void PxVehicleSuspensionComplianceUpdate +(const PxVehicleSuspensionParams& suspensionParams, + const PxVehicleSuspensionComplianceParams& complianceParams, + const PxVehicleSuspensionState& suspensionState, + PxVehicleSuspensionComplianceState& complianceState); + +/** +\brief Compute the suspension force and torque arising from suspension compression and speed. +\param[in] suspensionParams is a description of the suspension and wheel frames. +\param[in] suspensionForceParams describes the conversion of suspension state to suspension force. +\param[in] roadGeometryState describes the plane under the wheel of the suspension. +\param[in] suspensionState is the current compression state of the suspension. +\param[in] complianceState is the current compliance state of the suspension. +\param[in] rigidBodyState describes the current pose of the rigid body. +\param[in] gravity is the gravitational acceleration. +\param[in] vehicleMass is the rigid body mass. +\param[out] suspensionForce is the force and torque to apply to the rigid body arising from the suspension state. +*/ +void PxVehicleSuspensionForceUpdate +(const PxVehicleSuspensionParams& suspensionParams, + const PxVehicleSuspensionForceParams& suspensionForceParams, + const PxVehicleRoadGeometryState& roadGeometryState, const PxVehicleSuspensionState& suspensionState, + const PxVehicleSuspensionComplianceState& complianceState, const PxVehicleRigidBodyState& rigidBodyState, + const PxVec3& gravity, const PxReal vehicleMass, + PxVehicleSuspensionForce& suspensionForce); + + +/** +\brief Compute the suspension force and torque arising from suspension compression and speed. +\param[in] suspensionParams is a description of the suspension and wheel frames. +\param[in] suspensionForceParams describes the conversion of suspension state to suspension force. +\param[in] roadGeometryState describes the plane under the wheel of the suspension. +\param[in] suspensionState is the current compression state of the suspension. +\param[in] complianceState is the current compliance state of the suspension. +\param[in] rigidBodyState describes the current pose of the rigid body. +\param[in] gravity is the gravitational acceleration. +\param[out] suspensionForce is the force and torque to apply to the rigid body arising from the suspension state. +\note PxVehicleSuspensionLegacyForceUpdate implements the legacy force computation of PhysX 5.0 and earlier. +@deprecated +*/ +PX_DEPRECATED void PxVehicleSuspensionLegacyForceUpdate +(const PxVehicleSuspensionParams& suspensionParams, + const PxVehicleSuspensionForceLegacyParams& suspensionForceParams, + const PxVehicleRoadGeometryState& roadGeometryState, const PxVehicleSuspensionState& suspensionState, + const PxVehicleSuspensionComplianceState& complianceState, const PxVehicleRigidBodyState& rigidBodyState, + const PxVec3& gravity, + PxVehicleSuspensionForce& suspensionForce); + +/** +\brief Compute the accumulated anti-roll torque to apply to the vehicle's rigid body. +\param[in] suspensionParams The suspension parameters for each wheel. +\param[in] antiRollParams describes the wheel pairs connected by anti-roll bars and the strength of each anti-roll bar. +\param[in] suspensionStates The suspension states for each wheel. +\param[in] complianceStates The suspension compliance states for each wheel. +\param[in] rigidBodyState describes the pose and momentum of the vehicle's rigid body in the world frame. +\param[in] antiRollTorque is the accumulated anti-roll torque that is computed by iterating over all anti-roll bars +describes in *antiRollParams*. +\note suspensionParams must contain an entry for each wheel index referenced by *antiRollParams*. +\note suspensionStates must contain an entry for each wheel index referenced by *antiRollParams*. +\note complianceStates must contain an entry for each wheel index referenced by *antiRollParams*. +\note antiRollTorque is expressed in the world frame. +*/ +void PxVehicleAntiRollForceUpdate +(const PxVehicleArrayData& suspensionParams, + const PxVehicleSizedArrayData& antiRollParams, + const PxVehicleArrayData& suspensionStates, + const PxVehicleArrayData& complianceStates, + const PxVehicleRigidBodyState& rigidBodyState, + PxVehicleAntiRollTorque& antiRollTorque); + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/suspension/PxVehicleSuspensionHelpers.h b/Source/ThirdParty/PhysX/vehicle2/suspension/PxVehicleSuspensionHelpers.h new file mode 100644 index 000000000..648e73959 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/suspension/PxVehicleSuspensionHelpers.h @@ -0,0 +1,154 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ + + */ +#include "foundation/PxTransform.h" + +#include "vehicle2/wheel/PxVehicleWheelParams.h" +#include "vehicle2/wheel/PxVehicleWheelHelpers.h" + +#include "PxVehicleSuspensionParams.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +/** +\brief Compute suspension travel direction in the world frame. +\param[in] suspensionParams is a description of the suspension frame. +\param[in] rigidBodyPose is the current pose of the vehicle's rigid body. +\return The return value is the suspension travel direction in the world frame. +\note The suspension travel direction is used to perform queries against the road geometry. +*/ +PX_FORCE_INLINE PxVec3 PxVehicleComputeSuspensionDirection(const PxVehicleSuspensionParams& suspensionParams, const PxTransform& rigidBodyPose) +{ + const PxVec3 suspDir = rigidBodyPose.rotate(suspensionParams.suspensionTravelDir); + return suspDir; +} + +/** +\brief Compute the start pose of a suspension query. +\param[in] frame is a description of the longitudinal, lateral and vertical axes. +\param[in] suspensionParams is a description of the suspension frame. +\param[in] steerAngle is the yaw angle of the wheel in radians. +\param[in] rigidBodyPose is the pose of the rigid body in the world frame. +*/ +PX_FORCE_INLINE PxTransform PxVehicleComputeWheelPoseForSuspensionQuery(const PxVehicleFrame& frame, const PxVehicleSuspensionParams& suspensionParams, + const PxReal steerAngle, const PxTransform& rigidBodyPose) +{ + //Compute the wheel pose with zero travel from attachment point, zero compliance, + //zero wheel pitch (ignore due to radial symmetry). + //Zero travel from attachment point (we want the wheel pose at the top of the suspension, i.e., at max compression) + PxVehicleSuspensionState suspState; + suspState.setToDefault(); + //Compute the wheel pose. + const PxTransform wheelPose = PxVehicleComputeWheelPose(frame, suspensionParams, suspState, 0.0f, 0.0f, steerAngle, rigidBodyPose, + 0.0f); + + return wheelPose; +} + +/** +\brief Compute the start point, direction and length of a suspension scene raycast. +\param[in] frame is a description of the longitudinal, lateral and vertical axes. +\param[in] wheelParams describes the radius and halfwidth of the wheel. +\param[in] suspensionParams describes the suspension frame and the maximum suspension travel. +\param[in] steerAngle is the yaw angle of the wheel in radians. +\param[in] rigidBodyPose is the pose of the rigid body in the world frame. +\param[out] start is the starting point of the raycast in the world frame. +\param[out] dir is the direction of the raycast in the world frame. +\param[out] dist is the length of the raycast. +\note start, dir and dist together describe a raycast that begins at the top of wheel at maximum compression +and ends at the bottom of wheel at maximum droop. +*/ +PX_FORCE_INLINE void PxVehicleComputeSuspensionRaycast +(const PxVehicleFrame& frame, const PxVehicleWheelParams& wheelParams, const PxVehicleSuspensionParams& suspensionParams, + const PxF32 steerAngle, const PxTransform& rigidBodyPose, + PxVec3& start, PxVec3& dir, PxReal& dist) +{ + const PxTransform wheelPose = PxVehicleComputeWheelPoseForSuspensionQuery(frame, suspensionParams, steerAngle, rigidBodyPose); + + //Raycast from top of wheel at max compression to bottom of wheel at max droop. + dir = PxVehicleComputeSuspensionDirection(suspensionParams, rigidBodyPose); + start = wheelPose.p - dir * wheelParams.radius; + dist = suspensionParams.suspensionTravelDist + 2.0f*wheelParams.radius; +} + +/** +\brief Compute the start pose, direction and length of a suspension scene sweep. +\param[in] frame is a description of the longitudinal, lateral and vertical axes. +\param[in] suspensionParams describes the suspension frame and the maximum suspension travel. +\param[in] steerAngle is the yaw angle of the wheel in radians. +\param[in] rigidBodyPose is the pose of the rigid body in the world frame. +\param[out] start is the start pose of the sweep in the world frame. +\param[out] dir is the direction of the sweep in the world frame. +\param[out] dist is the length of the sweep. +\note start, dir and dist together describe a sweep that begins with the wheel placed at maximum +compression and ends at the maximum droop pose. +*/ +PX_FORCE_INLINE void PxVehicleComputeSuspensionSweep +(const PxVehicleFrame& frame, const PxVehicleSuspensionParams& suspensionParams, + const PxReal steerAngle, const PxTransform& rigidBodyPose, + PxTransform& start, PxVec3& dir, PxReal& dist) +{ + start = PxVehicleComputeWheelPoseForSuspensionQuery(frame, suspensionParams, steerAngle, rigidBodyPose); + dir = PxVehicleComputeSuspensionDirection(suspensionParams, rigidBodyPose); + dist = suspensionParams.suspensionTravelDist; +} + + +/** +\brief Compute the sprung masses of the suspension springs given (i) the number of sprung masses, +(ii) coordinates of the sprung masses in the rigid body frame, (iii) the center of mass offset of the rigid body, (iv) the +total mass of the rigid body, and (v) the direction of gravity +\param[in] nbSprungMasses is the number of sprung masses of the vehicle. This value corresponds to the number of wheels on the vehicle. +\param[in] sprungMassCoordinates are the coordinates of the sprung masses in the rigid body frame. The array sprungMassCoordinates must be of +length nbSprungMasses or greater. +\param[in] totalMass is the total mass of all the sprung masses. +\param[in] gravityDirection describes the direction of gravitational acceleration. +\param[out] sprungMasses are the masses to set in the associated suspension data with PxVehicleSuspensionData::mSprungMass. The sprungMasses array must be of length +nbSprungMasses or greater. Each element in the sprungMasses array corresponds to the suspension located at the same array element in sprungMassCoordinates. +The center of mass of the masses in sprungMasses with the coordinates in sprungMassCoordinates satisfy the specified centerOfMass. +\return True if the sprung masses were successfully computed, false if the sprung masses were not successfully computed. +*/ +bool PxVehicleComputeSprungMasses(const PxU32 nbSprungMasses, const PxVec3* sprungMassCoordinates, const PxReal totalMass, const PxVehicleAxes::Enum gravityDirection, PxReal* sprungMasses); + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/suspension/PxVehicleSuspensionParams.h b/Source/ThirdParty/PhysX/vehicle2/suspension/PxVehicleSuspensionParams.h new file mode 100644 index 000000000..a58a8d7cf --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/suspension/PxVehicleSuspensionParams.h @@ -0,0 +1,414 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once +/** \addtogroup vehicle2 + @{ +*/ + + +#include "foundation/PxTransform.h" +#include "foundation/PxFoundation.h" + +#include "common/PxCoreUtilityTypes.h" + +#include "vehicle2/PxVehicleParams.h" +#include "vehicle2/PxVehicleFunctions.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +struct PxVehicleSuspensionParams +{ + /** + \brief suspensionAttachment specifies the wheel pose at maximum compression. + \note suspensionAttachment is specified in the frame of the rigid body. + \note camber, steer and toe angles are all applied in the suspension frame. + */ + PxTransform suspensionAttachment; + + /** + \brief suspensionTravelDir specifies the direction of suspension travel. + \note suspensionTravelDir is specified in the frame of the rigid body. + */ + PxVec3 suspensionTravelDir; + + /** + \brief suspensionTravelDist is the maximum distance that the suspenson can elongate along #suspensionTravelDir + from the pose specified by #suspensionAttachment. + \note The position suspensionAttachment.p + #suspensionTravelDir*#suspensionTravelDist corresponds to the + the suspension at maximum droop in the rigid body frame. + */ + PxReal suspensionTravelDist; + + /** + \brief wheelAttachment is the pose of the wheel in the suspension frame. + \note The rotation angle around the wheel's lateral axis is applied in the wheel attachment frame. + */ + PxTransform wheelAttachment; + + + PX_FORCE_INLINE PxVehicleSuspensionParams transformAndScale( + const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const + { + PxVehicleSuspensionParams r = *this; + r.suspensionAttachment= PxVehicleTransformFrameToFrame(srcFrame, trgFrame, srcScale, trgScale, suspensionAttachment); + r.suspensionTravelDir = PxVehicleTransformFrameToFrame(srcFrame, trgFrame, suspensionTravelDir); + r.suspensionTravelDist *= (trgScale.scale/srcScale.scale); + r.wheelAttachment = PxVehicleTransformFrameToFrame(srcFrame, trgFrame, srcScale, trgScale, wheelAttachment); + return r; + } + + PX_FORCE_INLINE bool isValid() const + { + PX_CHECK_AND_RETURN_VAL(suspensionAttachment.isValid(), "PxVehicleSuspensionParams.suspensionAttachment must be a valid transform", false); + PX_CHECK_AND_RETURN_VAL(suspensionTravelDir.isFinite(), "PxVehicleSuspensionParams.suspensionTravelDir must be a valid vector", false); + PX_CHECK_AND_RETURN_VAL(suspensionTravelDir.isNormalized(), "PxVehicleSuspensionParams.suspensionTravelDir must be a unit vector", false); + PX_CHECK_AND_RETURN_VAL(suspensionTravelDist > 0.0f, "PxVehicleSuspensionParams.suspensionTravelDist must be greater than zero", false); + PX_CHECK_AND_RETURN_VAL(wheelAttachment.isValid(), "PxVehicleSuspensionParams.wheelAttachment must be a valid transform", false); + return true; + } +}; + +struct PxVehicleSuspensionJounceCalculationType +{ + enum Enum + { + eRAYCAST, //!< The jounce is calculated using a raycast against the plane of the road geometry state + eSWEEP, //!< The jounce is calculated by sweeping a cylinder against the plane of the road geometry state + eMAX_NB + }; +}; + +struct PxVehicleSuspensionStateCalculationParams +{ + PxVehicleSuspensionJounceCalculationType::Enum suspensionJounceCalculationType; + + /** + \brief Limit the suspension expansion dynamics. + + If a hit with the ground is detected, the suspension jounce will be set such that the wheel + is placed on the ground. This can result in large changes to jounce within a single + simulation frame, if the ground surface has high frequency or if the simulation time step + is large. As a result, large damping forces can evolve and cause undesired behavior. If this + parameter is set to true, the suspension expansion speed will be limited to what can be + achieved given the time step, suspension stiffness etc. As a consequence, handling of the + vehicle will be affected as the wheel might loose contact with the ground more easily. + */ + bool limitSuspensionExpansionVelocity; + + PX_FORCE_INLINE PxVehicleSuspensionStateCalculationParams transformAndScale( + const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const + { + PX_UNUSED(srcFrame); + PX_UNUSED(trgFrame); + PX_UNUSED(srcScale); + PX_UNUSED(trgScale); + return *this; + } + + PX_FORCE_INLINE bool isValid() const + { + return true; + } +}; + +/** +\brief Compliance describes how toe and camber angle and force application points are affected by suspension compression. +\note Each compliance term is in the form of a graph with up to 3 points. +\note Each point in the graph has form (jounce/suspensionTravelDist, complianceValue). +\note The sequence of points must respresent monotonically increasing values of jounce. +\note The compliance value can be computed by linear interpolation. +\note If any graph has zero points in it, a value of 0.0 is used for the compliance value. +\note If any graph has 1 point in it, the compliance value of that point is used directly. +*/ +struct PxVehicleSuspensionComplianceParams +{ + /** + \brief A graph of toe angle against jounce/suspensionTravelDist with the toe angle expressed in radians. + \note The toe angle is applied in the suspension frame. + */ + PxVehicleFixedSizeLookupTable wheelToeAngle; + + /** + \brief A graph of camber angle against jounce/suspensionTravelDist with the camber angle expressed in radians. + \note The camber angle is applied in the suspension frame. + */ + PxVehicleFixedSizeLookupTable wheelCamberAngle; + + /** + \brief Suspension forces are applied at an offset from the suspension frame. suspForceAppPoint + specifies the (X, Y, Z) components of that offset as a function of jounce/suspensionTravelDist. + */ + PxVehicleFixedSizeLookupTable suspForceAppPoint; + + /** + \brief Tire forces are applied at an offset from the suspension frame. tireForceAppPoint + specifies the (X, Y, Z) components of that offset as a function of jounce/suspensionTravelDist. + */ + PxVehicleFixedSizeLookupTable tireForceAppPoint; + + PX_FORCE_INLINE PxVehicleSuspensionComplianceParams transformAndScale( + const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const + { + PX_UNUSED(srcFrame); + PX_UNUSED(trgFrame); + PxVehicleSuspensionComplianceParams r = *this; + + const PxReal scale = trgScale.scale / srcScale.scale; + for (PxU32 i = 0; i < r.suspForceAppPoint.nbDataPairs; i++) + { + r.suspForceAppPoint.yVals[i] = PxVehicleTransformFrameToFrame(srcFrame, trgFrame, suspForceAppPoint.yVals[i]); + r.suspForceAppPoint.yVals[i] *= scale; + } + for (PxU32 i = 0; i < r.tireForceAppPoint.nbDataPairs; i++) + { + r.tireForceAppPoint.yVals[i] = PxVehicleTransformFrameToFrame(srcFrame, trgFrame, tireForceAppPoint.yVals[i]); + r.tireForceAppPoint.yVals[i] *= scale; + } + return r; + } + + PX_FORCE_INLINE bool isValid() const + { + PX_CHECK_AND_RETURN_VAL(wheelToeAngle.isValid(), "PxVehicleSuspensionComplianceParams.wheelToeAngle is invalid", false); + PX_CHECK_AND_RETURN_VAL(wheelCamberAngle.isValid(), "PxVehicleSuspensionComplianceParams.wheelCamberAngle is invalid", false); + PX_CHECK_AND_RETURN_VAL(suspForceAppPoint.isValid(), "PxVehicleSuspensionComplianceParams.wheelToeAngle is invalid", false); + PX_CHECK_AND_RETURN_VAL(tireForceAppPoint.isValid(), "PxVehicleSuspensionComplianceParams.wheelCamberAngle is invalid", false); + + for (PxU32 i = 0; i < wheelToeAngle.nbDataPairs; i++) + { + PX_CHECK_AND_RETURN_VAL(wheelToeAngle.xVals[i] >= 0.0f && wheelToeAngle.xVals[i] <= 1.0f, "PxVehicleSuspensionComplianceParams.wheelToeAngle must be an array of points (x,y) with x in range [0, 1]", false); + PX_CHECK_AND_RETURN_VAL(wheelToeAngle.yVals[i] >= -PxPi && wheelToeAngle.yVals[i] <= PxPi, "PxVehicleSuspensionComplianceParams.wheelToeAngle must be an array of points (x,y) with y in range [-Pi, Pi]", false); + } + for (PxU32 i = 0; i < wheelCamberAngle.nbDataPairs; i++) + { + PX_CHECK_AND_RETURN_VAL(wheelCamberAngle.xVals[i] >= 0.0f && wheelCamberAngle.xVals[i] <= 1.0f, "PxVehicleSuspensionComplianceParams.wheelCamberAngle must be an array of points (x,y) with x in range [0, 1]", false); + PX_CHECK_AND_RETURN_VAL(wheelCamberAngle.yVals[i] >= -PxPi && wheelCamberAngle.yVals[i] <= PxPi, "PxVehicleSuspensionComplianceParams.wheelCamberAngle must be an array of points (x,y) with y in range [-Pi, Pi]", false); + } + + for (PxU32 i = 0; i < suspForceAppPoint.nbDataPairs; i++) + { + PX_CHECK_AND_RETURN_VAL(suspForceAppPoint.xVals[i] >= 0.0f && suspForceAppPoint.xVals[i] <= 1.0f, "PxVehicleSuspensionComplianceParams.suspForceAppPoint[0] must be an array of points (x,y) with x in range [0, 1]", false); + } + for (PxU32 i = 0; i < tireForceAppPoint.nbDataPairs; i++) + { + PX_CHECK_AND_RETURN_VAL(tireForceAppPoint.xVals[i] >= 0.0f && tireForceAppPoint.xVals[i] <= 1.0f, "PxVehicleSuspensionComplianceParams.tireForceAppPoint[0] must be an array of points (x,y) with x in range [0, 1]", false); + } + return true; + } +}; + +/** +\brief Suspension force is computed by converting suspenson state to suspension force under the assumption of a linear spring. +@see PxVehicleSuspensionForceUpdate +*/ +struct PxVehicleSuspensionForceParams +{ + /** + \brief Spring strength of suspension. + + Range: (0, inf)
+ Unit: mass / (time^2) + */ + PxReal stiffness; + + /** + \brief Spring damper rate of suspension. + + Range: [0, inf)
+ Unit: mass / time + */ + PxReal damping; + + /** + \brief Part of the vehicle mass that is supported by the suspension spring. + + Range: (0, inf)
+ Unit: mass + */ + PxReal sprungMass; + + PX_FORCE_INLINE PxVehicleSuspensionForceParams transformAndScale( + const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const + { + PX_UNUSED(srcFrame); + PX_UNUSED(trgFrame); + PX_UNUSED(srcScale); + PX_UNUSED(trgScale); + return *this; + } + + PX_FORCE_INLINE bool isValid() const + { + PX_CHECK_AND_RETURN_VAL(stiffness > 0.0f, "PxVehicleSuspensionForceParams.stiffness must be greater than zero", false); + PX_CHECK_AND_RETURN_VAL(damping >= 0.0f, "PxVehicleSuspensionForceParams.damping must be greater than or equal to zero", false); + PX_CHECK_AND_RETURN_VAL(sprungMass > 0.0f, "PxVehicleSuspensionForceParams.sprungMass must be greater than zero", false); + return true; + } +}; + +/** +\brief Suspension force is computed by converting suspenson state to suspension force under the assumption of a linear spring. +@see PxVehicleSuspensionLegacyForceUpdate +@deprecated +*/ +struct PX_DEPRECATED PxVehicleSuspensionForceLegacyParams +{ + /** + \brief Spring strength of suspension. + + Range: (0, inf)
+ Unit: mass / (time^2) + */ + PxReal stiffness; + + /** + \brief Spring damper rate of suspension. + + Range: [0, inf)
+ Unit: mass / time + */ + PxReal damping; + + /** + \brief The suspension compression that balances the gravitational force acting on the sprung mass. + + Range: (0, inf)
+ Unit: length + */ + PxReal restDistance; + + /** + \brief The mass supported by the suspension spring. + + Range: (0, inf)
+ Unit: mass + */ + PxReal sprungMass; + + PX_FORCE_INLINE PxVehicleSuspensionForceLegacyParams transformAndScale( + const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const + { + PX_UNUSED(srcFrame); + PX_UNUSED(trgFrame); + PxVehicleSuspensionForceLegacyParams r = *this; + r.restDistance *= (trgScale.scale / srcScale.scale); + return *this; + } + + PX_FORCE_INLINE bool isValid() const + { + PX_CHECK_AND_RETURN_VAL(stiffness > 0.0f, "PxVehicleSuspensionForceLegacyParams.stiffness must be greater than zero", false); + PX_CHECK_AND_RETURN_VAL(damping >= 0.0f, "PxVehicleSuspensionForceLegacyParams.damping must be greater than or equal to zero", false); + PX_CHECK_AND_RETURN_VAL(restDistance > 0.0f, "PxVehicleSuspensionForceLegacyParams.restDistance must be greater than zero", false); + PX_CHECK_AND_RETURN_VAL(sprungMass > 0.0f, "PxVehicleSuspensionForceLegacyParams.sprungMass must be greater than zero", false); + return true; + } + +}; + +/** +\brief The purpose of the anti-roll bar is to generate a torque to apply to the vehicle's rigid body that will reduce the jounce difference arising +between any pair of chosen wheels. If the chosen wheels share an axle, the anti-roll bar will attempt to reduce the roll angle of the vehicle's rigid body. +Alternatively, if the chosen wheels are the front and rear wheels along one side of the vehicle, the anti-roll bar will attempt to reduce the pitch angle of the +vehicle's rigid body. +*/ +struct PxVehicleAntiRollForceParams +{ + /* + \brief The anti-roll bar connects two wheels with indices wheel0 and wheel1 + \note wheel0 and wheel1 may be chosen to have the effect of an anti-dive bar or to have the effect of an anti-roll bar. + */ + PxU32 wheel0; + + /* + \brief The anti-roll bar connects two wheels with indices wheel0 and wheel1 + \note wheel0 and wheel1 may be chosen to have the effect of an anti-dive bar or to have the effect of an anti-roll bar. + */ + PxU32 wheel1; + + /* + \brief The linear stiffness of the anti-roll bar. + \note A positive stiffness will work to reduce the discrepancy in jounce between wheel0 and wheel1. + \note A negative stiffness will work to increase the discrepancy in jounce between wheel0 and wheel1. + + Unit: mass / (time^2) + */ + PxReal stiffness; + + PX_FORCE_INLINE PxVehicleAntiRollForceParams transformAndScale( + const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const + { + PX_UNUSED(srcFrame); + PX_UNUSED(trgFrame); + PX_UNUSED(srcScale); + PX_UNUSED(trgScale); + return *this; + } + + PX_FORCE_INLINE bool isValid(const PxVehicleAxleDescription& axleDesc) const + { + if (!PxIsFinite(stiffness)) + return false; + if (wheel0 == wheel1) + return false; + + //Check that each wheel id is a valid wheel. + const PxU32 wheelIds[2] = { wheel0, wheel1 }; + for (PxU32 k = 0; k < 2; k++) + { + const PxU32 wheelToFind = wheelIds[k]; + bool foundWheelInAxleDescription = false; + for (PxU32 i = 0; i < axleDesc.nbWheels; i++) + { + const PxU32 wheel = axleDesc.wheelIdsInAxleOrder[i]; + if (wheel == wheelToFind) + { + foundWheelInAxleDescription = true; + } + } + if (!foundWheelInAxleDescription) + return false; + } + + return true; + } +}; + + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/suspension/PxVehicleSuspensionStates.h b/Source/ThirdParty/PhysX/vehicle2/suspension/PxVehicleSuspensionStates.h new file mode 100644 index 000000000..af916c86b --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/suspension/PxVehicleSuspensionStates.h @@ -0,0 +1,189 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "foundation/PxSimpleTypes.h" +#include "foundation/PxVec3.h" +#include "foundation/PxMemory.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +#define PX_VEHICLE_UNSPECIFIED_JOUNCE PX_MAX_F32 +#define PX_VEHICLE_UNSPECIFIED_SEPARATION PX_MAX_F32 + +/** + +*/ +struct PxVehicleSuspensionState +{ + /** + \brief jounce is the distance from maximum droop. + \note jounce is positive semi-definite + \note A value of 0.0 represents the suspension at maximum droop and zero suspension force. + \note A value of suspensionTravelDist represents the suspension at maximum compression. + \note jounce is clamped in range [0, suspensionTravelDist]. + */ + PxReal jounce; + + /** + \brief jounceSpeed is the rate of change of jounce. + */ + PxReal jounceSpeed; + + /** + \brief separation holds extra information about the contact state of the wheel with the ground. + + If the suspension travel range is enough to place the wheel on the ground, then separation will be 0. + If separation holds a negative value, then the wheel penetrates into the ground at maximum compression + as well as maximum droop. The suspension would need to go beyond maximum compression (ground normal + pointing in opposite direction of suspension) or beyond maximum droop (ground normal pointing in same + direction as suspension) to place the wheel on the ground. In that case the separation value defines + how much the wheel penetrates into the ground along the ground plane normal. This penetration may be + resolved by using a constraint that simulates the effect of a bump stop. + If separation holds a positive value, then the wheel does not penetrate the ground at maximum droop + but can not touch the ground because the suspension would need to expand beyond max droop to reach it + or because the suspension could not expand fast enough to reach the ground. + */ + PxReal separation; + + PX_FORCE_INLINE void setToDefault(const PxReal _jounce = PX_VEHICLE_UNSPECIFIED_JOUNCE, + const PxReal _separation = PX_VEHICLE_UNSPECIFIED_SEPARATION) + { + jounce = _jounce; + jounceSpeed = 0; + separation = _separation; + } +}; + +/** +\brief The effect of suspension compliance on toe and camber angle and on the tire and suspension force application points. +*/ +struct PxVehicleSuspensionComplianceState +{ + /** + \brief The toe angle in radians that arises from suspension compliance. + \note toe is expressed in the suspension frame. + */ + PxReal toe; + + /** + \brief The camber angle in radians that arises from suspension compliance. + \note camber is expressed in the suspension frame. + */ + PxReal camber; + + /** + \brief The tire force application point that arises from suspension compliance. + \note tireForceAppPoint is expressed in the suspension frame. + */ + PxVec3 tireForceAppPoint; + + /** + \brief The suspension force application point that arises from suspension compliance. + \note suspForceAppPoint is expressed in the suspension frame. + */ + PxVec3 suspForceAppPoint; + + PX_FORCE_INLINE void setToDefault() + { + PxMemZero(this, sizeof(PxVehicleSuspensionComplianceState)); + } +}; + +/** +\brief The force and torque for a single suspension to apply to the vehicle's rigid body. +*/ +struct PxVehicleSuspensionForce +{ + /** + \brief The force to apply to the rigid body. + \note force is expressed in the world frame. + + Unit: mass * length / (time^2) + */ + PxVec3 force; + + /** + \brief The torque to apply to the rigid body. + \note torque is expressed in the world frame. + + Unit: mass * (length^2) / (time^2) + */ + PxVec3 torque; + + /** + \brief The component of force that lies along the normal of the plane under the wheel. + \note normalForce may be used by the tire model as the tire load. + + Unit: mass * length / (time^2) + */ + PxReal normalForce; + + PX_FORCE_INLINE void setToDefault() + { + PxMemZero(this, sizeof(PxVehicleSuspensionForce)); + } +}; + +/** +\brief The anti-roll torque of all anti-roll bars accumulates in a single torque to apply +to the vehicle's rigid body. +*/ +struct PxVehicleAntiRollTorque +{ + /** + \brief The accumulated torque to apply to the rigid body. + \note antiRollTorque is expressed in the world frame. + + Unit: mass * (length^2) / (time^2) + */ + PxVec3 antiRollTorque; + + PX_FORCE_INLINE void setToDefault() + { + PxMemZero(this, sizeof(PxVehicleAntiRollTorque)); + } +}; + + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/tire/PxVehicleTireComponents.h b/Source/ThirdParty/PhysX/vehicle2/tire/PxVehicleTireComponents.h new file mode 100644 index 000000000..32b1f1f74 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/tire/PxVehicleTireComponents.h @@ -0,0 +1,333 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ +#include "vehicle2/PxVehicleParams.h" +#include "vehicle2/PxVehicleComponent.h" + +#include "vehicle2/commands/PxVehicleCommandHelpers.h" +#include "vehicle2/roadGeometry/PxVehicleRoadGeometryState.h" +#include "vehicle2/suspension/PxVehicleSuspensionParams.h" +#include "vehicle2/suspension/PxVehicleSuspensionStates.h" +#include "vehicle2/wheel/PxVehicleWheelStates.h" +#include "vehicle2/wheel/PxVehicleWheelParams.h" + +#include "PxVehicleTireFunctions.h" +#include "PxVehicleTireParams.h" + +#include "common/PxProfileZone.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +class PxVehicleTireComponent : public PxVehicleComponent +{ +public: + + PxVehicleTireComponent() : PxVehicleComponent() {} + virtual ~PxVehicleTireComponent() {} + + virtual void getDataForTireComponent( + const PxVehicleAxleDescription*& axleDescription, + PxVehicleArrayData& steerResponseStates, + const PxVehicleRigidBodyState*& rigidBodyState, + PxVehicleArrayData& actuationStates, + PxVehicleArrayData& wheelParams, + PxVehicleArrayData& suspensionParams, + PxVehicleArrayData& tireForceParams, + PxVehicleArrayData& roadGeomStates, + PxVehicleArrayData& suspensionStates, + PxVehicleArrayData& suspensionComplianceStates, + PxVehicleArrayData& suspensionForces, + PxVehicleArrayData& wheelRigidBody1DStates, + PxVehicleArrayData& tireGripStates, + PxVehicleArrayData& tireDirectionStates, + PxVehicleArrayData& tireSpeedStates, + PxVehicleArrayData& tireSlipStates, + PxVehicleArrayData& tireCamberAngleStates, + PxVehicleArrayData& tireStickyStates, + PxVehicleArrayData& tireForces) = 0; + + virtual bool update(const PxReal dt, const PxVehicleSimulationContext& context) + { + PX_PROFILE_ZONE("PxVehicleTireComponent::update", 0); + + const PxVehicleAxleDescription* axleDescription; + PxVehicleArrayData steerResponseStates; + const PxVehicleRigidBodyState* rigidBodyState; + PxVehicleArrayData actuationStates; + PxVehicleArrayData wheelParams; + PxVehicleArrayData suspensionParams; + PxVehicleArrayData tireForceParams; + PxVehicleArrayData roadGeomStates; + PxVehicleArrayData suspensionStates; + PxVehicleArrayData suspensionComplianceStates; + PxVehicleArrayData suspensionForces; + PxVehicleArrayData wheelRigidBody1DStates; + PxVehicleArrayData tireGripStates; + PxVehicleArrayData tireDirectionStates; + PxVehicleArrayData tireSpeedStates; + PxVehicleArrayData tireSlipStates; + PxVehicleArrayData tireCamberAngleStates; + PxVehicleArrayData tireStickyStates; + PxVehicleArrayData tireForces; + + getDataForTireComponent(axleDescription, steerResponseStates, + rigidBodyState, actuationStates, wheelParams, suspensionParams, tireForceParams, + roadGeomStates, suspensionStates, suspensionComplianceStates, suspensionForces, + wheelRigidBody1DStates, tireGripStates, tireDirectionStates, tireSpeedStates, + tireSlipStates, tireCamberAngleStates, tireStickyStates, tireForces); + + for (PxU32 i = 0; i < axleDescription->nbWheels; i++) + { + const PxU32 wheelId = axleDescription->wheelIdsInAxleOrder[i]; + + //Compute the tire slip directions + PxVehicleTireDirsUpdate( + suspensionParams[wheelId], + steerResponseStates[wheelId], + roadGeomStates[wheelId], suspensionComplianceStates[wheelId], + *rigidBodyState, + context.frame, + tireDirectionStates[wheelId]); + + //Compute the rigid body speeds along the tire slip directions. + PxVehicleTireSlipSpeedsUpdate( + wheelParams[wheelId], suspensionParams[wheelId], + steerResponseStates[wheelId], suspensionStates[wheelId], tireDirectionStates[wheelId], + *rigidBodyState, roadGeomStates[i], + context.frame, + tireSpeedStates[wheelId]); + + //Compute the tire slip angles. + PxVehicleTireSlipsUpdate( + wheelParams[wheelId], context.tireSlipParams, + actuationStates[wheelId], tireSpeedStates[wheelId], + wheelRigidBody1DStates[wheelId], + tireSlipStates[wheelId]); + + //Update the camber angle + PxVehicleTireCamberAnglesUpdate( + suspensionParams[wheelId], steerResponseStates[wheelId], roadGeomStates[wheelId], + suspensionComplianceStates[wheelId], *rigidBodyState, + context.frame, + tireCamberAngleStates[wheelId]); + + //Compute the friction + PxVehicleTireGripUpdate( + tireForceParams[wheelId], roadGeomStates[wheelId], + suspensionStates[wheelId], suspensionForces[wheelId], + tireSlipStates[wheelId], tireGripStates[wheelId]); + + //Update the tire sticky state + // + //Note: this should be skipped if tires do not use the sticky feature + PxVehicleTireStickyStateUpdate( + *axleDescription, + wheelParams[wheelId], + context.tireStickyParams, + actuationStates, tireGripStates[wheelId], + tireSpeedStates[wheelId], wheelRigidBody1DStates[wheelId], + dt, + tireStickyStates[wheelId]); + + //If sticky tire is active set the slip angle to zero. + // + //Note: this should be skipped if tires do not use the sticky feature + PxVehicleTireSlipsAccountingForStickyStatesUpdate( + tireStickyStates[wheelId], + tireSlipStates[wheelId]); + + //Compute the tire forces + PxVehicleTireForcesUpdate( + wheelParams[wheelId], suspensionParams[wheelId], + tireForceParams[wheelId], + suspensionComplianceStates[wheelId], + tireGripStates[wheelId], tireDirectionStates[wheelId], + tireSlipStates[wheelId], tireCamberAngleStates[wheelId], + *rigidBodyState, + tireForces[wheelId]); + } + + return true; + } +}; + +/** + * @deprecated + */ +class PX_DEPRECATED PxVehicleLegacyTireComponent : public PxVehicleComponent +{ +public: + + PxVehicleLegacyTireComponent() : PxVehicleComponent() {} + virtual ~PxVehicleLegacyTireComponent() {} + + virtual void getDataForLegacyTireComponent( + const PxVehicleAxleDescription*& axleDescription, + PxVehicleArrayData& steerResponseStates, + const PxVehicleRigidBodyState*& rigidBodyState, + PxVehicleArrayData& actuationStates, + PxVehicleArrayData& wheelParams, + PxVehicleArrayData& suspensionParams, + PxVehicleArrayData& tireForceParams, + PxVehicleArrayData& roadGeomStates, + PxVehicleArrayData& suspensionStates, + PxVehicleArrayData& suspensionComplianceStates, + PxVehicleArrayData& suspensionForces, + PxVehicleArrayData& wheelRigidBody1DStates, + PxVehicleArrayData& tireGripStates, + PxVehicleArrayData& tireDirectionStates, + PxVehicleArrayData& tireSpeedStates, + PxVehicleArrayData& tireSlipStates, + PxVehicleArrayData& tireCamberAngleStates, + PxVehicleArrayData& tireStickyStates, + PxVehicleArrayData& tireForces) = 0; + + virtual bool update(const PxReal dt, const PxVehicleSimulationContext& context) + { + PX_PROFILE_ZONE("PxVehicleLegacyTireComponent::update", 0); + + const PxVehicleAxleDescription* axleDescription; + PxVehicleArrayData steerResponseStates; + const PxVehicleRigidBodyState* rigidBodyState; + PxVehicleArrayData actuationStates; + PxVehicleArrayData wheelParams; + PxVehicleArrayData suspensionParams; + PxVehicleArrayData tireForceParams; + PxVehicleArrayData roadGeomStates; + PxVehicleArrayData suspensionStates; + PxVehicleArrayData suspensionComplianceStates; + PxVehicleArrayData suspensionForces; + PxVehicleArrayData wheelRigidBody1DStates; + PxVehicleArrayData tireGripStates; + PxVehicleArrayData tireDirectionStates; + PxVehicleArrayData tireSpeedStates; + PxVehicleArrayData tireSlipStates; + PxVehicleArrayData tireCamberAngleStates; + PxVehicleArrayData tireStickyStates; + PxVehicleArrayData tireForces; + + getDataForLegacyTireComponent(axleDescription, steerResponseStates, + rigidBodyState, actuationStates, + wheelParams, suspensionParams, tireForceParams, + roadGeomStates, suspensionStates, suspensionComplianceStates, + suspensionForces, wheelRigidBody1DStates, + tireGripStates, tireDirectionStates, tireSpeedStates, tireSlipStates, + tireCamberAngleStates, tireStickyStates, tireForces); + + for (PxU32 i = 0; i < axleDescription->nbWheels; i++) + { + const PxU32 wheelId = axleDescription->wheelIdsInAxleOrder[i]; + + //Compute the tire slip directions + PxVehicleTireDirsLegacyUpdate( + suspensionParams[wheelId], + steerResponseStates[wheelId], + roadGeomStates[wheelId], *rigidBodyState, + context.frame, + tireDirectionStates[wheelId]); + + //Compute the rigid body speeds along the tire slip directions. + PxVehicleTireSlipSpeedsUpdate( + wheelParams[wheelId], suspensionParams[wheelId], + steerResponseStates[wheelId], suspensionStates[wheelId], tireDirectionStates[wheelId], + *rigidBodyState, roadGeomStates[wheelId], + context.frame, + tireSpeedStates[wheelId]); + + //Compute the tire slip angles. + PxVehicleTireSlipsLegacyUpdate( + wheelParams[wheelId], context.tireSlipParams, + actuationStates[wheelId], tireSpeedStates[wheelId], + wheelRigidBody1DStates[wheelId], + tireSlipStates[wheelId]); + + //Update the camber angle + PxVehicleTireCamberAnglesUpdate( + suspensionParams[wheelId], steerResponseStates[wheelId], roadGeomStates[wheelId], + suspensionComplianceStates[wheelId], *rigidBodyState, + context.frame, + tireCamberAngleStates[wheelId]); + + //Compute the friction + PxVehicleTireGripUpdate( + tireForceParams[wheelId], roadGeomStates[wheelId], + suspensionStates[wheelId], suspensionForces[wheelId], + tireSlipStates[wheelId], tireGripStates[wheelId]); + + //Update the tire sticky state + // + //Note: this should be skipped if tires do not use the sticky feature + PxVehicleTireStickyStateUpdate( + *axleDescription, + wheelParams[wheelId], + context.tireStickyParams, + actuationStates, tireGripStates[wheelId], + tireSpeedStates[wheelId], wheelRigidBody1DStates[wheelId], + dt, + tireStickyStates[wheelId]); + + //If sticky tire is active set the slip angle to zero. + // + //Note: this should be skipped if tires do not use the sticky feature + PxVehicleTireSlipsAccountingForStickyStatesUpdate( + tireStickyStates[wheelId], + tireSlipStates[wheelId]); + + //Compute the tire forces + PxVehicleTireForcesUpdate( + wheelParams[wheelId], suspensionParams[wheelId], + tireForceParams[wheelId], + suspensionComplianceStates[wheelId], + tireGripStates[wheelId], tireDirectionStates[wheelId], + tireSlipStates[wheelId], tireCamberAngleStates[wheelId], + *rigidBodyState, + tireForces[wheelId]); + } + + return true; + } +}; + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ + + diff --git a/Source/ThirdParty/PhysX/vehicle2/tire/PxVehicleTireFunctions.h b/Source/ThirdParty/PhysX/vehicle2/tire/PxVehicleTireFunctions.h new file mode 100644 index 000000000..cd8cd14c4 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/tire/PxVehicleTireFunctions.h @@ -0,0 +1,269 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once +/** \addtogroup vehicle2 + @{ +*/ + +#include "foundation/PxSimpleTypes.h" +#include "vehicle2/PxVehicleParams.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +struct PxVehicleSuspensionParams; +struct PxVehicleRoadGeometryState; +struct PxVehicleRigidBodyState; +struct PxVehicleTireDirectionState; +struct PxVehicleSuspensionComplianceState; +struct PxVehicleWheelParams; +struct PxVehicleTireSpeedState; +struct PxVehicleWheelActuationState; +struct PxVehicleWheelRigidBody1dState; +struct PxVehicleTireSlipState; +struct PxVehicleSuspensionState; +struct PxVehicleTireCamberAngleState; +struct PxVehicleTireGripState; +struct PxVehicleTireForceParams; +struct PxVehicleSuspensionForce; +struct PxVehicleTireForce; +struct PxVehicleTireStickyState; + +/** +\brief Compute the longitudinal and lateral tire directions in the ground plane. +\param[in] suspensionParams describes the frame of the suspension and wheel. +\param[in] steerAngle is the steer angle in radians to be applied to the wheel. +\param[in] roadGeometryState describes the plane of the road geometry under the wheel +\param[in] rigidBodyState describes the current pose of the vehicle's rigid body in the world frame. +\param[in] frame is a description of the vehicle's lateral and longitudinal axes. +\param[out] tireDirectionState is the computed tire longitudinal and lateral directions in the world frame. +\note PxVehicleTireDirsLegacyUpdate replicates the tire direction calculation of PhysX 5.0 and earlier. +@deprecated +*/ +PX_DEPRECATED void PxVehicleTireDirsLegacyUpdate +(const PxVehicleSuspensionParams& suspensionParams, + const PxReal steerAngle, const PxVehicleRoadGeometryState& roadGeometryState, const PxVehicleRigidBodyState& rigidBodyState, + const PxVehicleFrame& frame, + PxVehicleTireDirectionState& tireDirectionState); + +/** +\brief Compute the longitudinal and lateral tire directions in the ground plane. +\param[in] suspensionParams describes the frame of the suspension and wheel. +\param[in] steerAngle is the steer angle in radians to be applied to the wheel. +\param[in] roadGeometryState describes the plane of the road geometry under the wheel. +\param[in] rigidBodyState describes the current pose of the vehicle's rigid body in the world frame. +\param[in] complianceState is a description of the camber and toe angle that arise from suspension compliance. +\param[in] frame is a description of the vehicle's lateral and longitudinal axes. +\param[out] tireDirectionState is the computed tire longitudinal and lateral directions in the world frame. +\note The difference between PxVehicleTireDirsUpdate and PxVehicleTireDirsLegacyUpdate is that +PxVehicleTireDirsUpdate accounts for suspension compliance while PxVehicleTireDirsLegacyUpdate does not. +*/ +void PxVehicleTireDirsUpdate +(const PxVehicleSuspensionParams& suspensionParams, + const PxReal steerAngle, const PxVehicleRoadGeometryState& roadGeometryState, const PxVehicleSuspensionComplianceState& complianceState, + const PxVehicleRigidBodyState& rigidBodyState, + const PxVehicleFrame& frame, + PxVehicleTireDirectionState& tireDirectionState); + +/** +\brief Project the rigid body velocity at the tire contact point along the tire longitudinal directions. +\param[in] wheelParams is a description of the wheel's radius and half-width. +\param[in] suspensionParams describes the frame of the suspension and wheel. +\param[in] steerAngle is the steer angle in radians to be applied to the wheel. +\param[in] suspensionStates is the current suspension compression state. +\param[in] tireDirectionState is the tire's longitudinal and lateral directions in the ground plane. +\param[in] rigidBodyState describes the current pose and velocity of the vehicle's rigid body in the world frame. +\param[in] roadGeometryState describes the current velocity of the road geometry under each wheel. +\param[in] frame is a description of the vehicle's lateral and longitudinal axes. +\param[out] tireSpeedState is the components of rigid body velocity at the tire contact point along the +tire's longitudinal and lateral axes. +@see PxVehicleTireDirsUpdate +@see PxVehicleTireDirsLegacyUpdate +*/ +void PxVehicleTireSlipSpeedsUpdate +(const PxVehicleWheelParams& wheelParams, const PxVehicleSuspensionParams& suspensionParams, + const PxF32 steerAngle, const PxVehicleSuspensionState& suspensionStates, const PxVehicleTireDirectionState& tireDirectionState, + const PxVehicleRigidBodyState& rigidBodyState, const PxVehicleRoadGeometryState& roadGeometryState, + const PxVehicleFrame& frame, + PxVehicleTireSpeedState& tireSpeedState); + +/** +\brief Compute a tire's longitudinal and lateral slip angles. +\param[in] wheelParams describes the radius of the wheel. +\param[in] tireSlipParams describes how to manage small longitudinal speeds by setting minimum values on the +denominator of the quotients used to calculate lateral and longitudinal slip. +\param[in] actuationState describes whether a wheel is to be driven by a drive torque or not. +\param[in] tireSpeedState is the component of rigid body velocity at the tire contact point projected along the +tire's longitudinal and lateral axes. +\param[in] wheelRigidBody1dState is the wheel rotation speed. +\param[out] tireSlipState is the computed tire longitudinal and lateral slips. +\note Longitudinal slip angle has the following theoretical form: (wheelRotationSpeed*wheelRadius - longitudinalSpeed)/|longitudinalSpeed| +\note Lateral slip angle has the following theoretical form: atan(lateralSpeed/|longitudinalSpeed|) +\note The calculation of both longitudinal and lateral slip angles avoid a zero denominator using minimum values for the denominator set in +tireSlipParams. +*/ +void PxVehicleTireSlipsUpdate +(const PxVehicleWheelParams& wheelParams, + const PxVehicleTireSlipParams& tireSlipParams, + const PxVehicleWheelActuationState& actuationState, PxVehicleTireSpeedState& tireSpeedState, const PxVehicleWheelRigidBody1dState& wheelRigidBody1dState, + PxVehicleTireSlipState& tireSlipState); + +/** +@deprecated + +\brief Compute a tire's longitudinal and lateral slip angles. +\param[in] wheelParams describes the radius of the wheel. +\param[in] tireSlipParams describes how to manage small longitudinal speeds by setting minimum values on the +denominator of the quotients used to calculate lateral and longitudinal slip. +\param[in] actuationState describes whether a wheel is to be driven by a drive torque or not. +\param[in] tireSpeedState is the component of rigid body velocity at the tire contact point projected along the +tire's longitudinal and lateral axes. +\param[in] wheelRigidBody1dState is the wheel rotation speed. +\param[out] tireSlipState is the computed tire longitudinal and lateral slips. +\note Longitudinal slip angle has the following theoretical form: (wheelRotationSpeed*wheelRadius - longitudinalSpeed)/|longitudinalSpeed| +\note Lateral slip angle has the following theoretical form: atan(lateralSpeed/|longitudinalSpeed|) +\note The calculation of both longitudinal and lateral slip angles avoid a zero denominator using minimum values for the denominator set in +tireSlipParams. +*/ +void PX_DEPRECATED PxVehicleTireSlipsLegacyUpdate +(const PxVehicleWheelParams& wheelParams, + const PxVehicleTireSlipParams& tireSlipParams, + const PxVehicleWheelActuationState& actuationState, PxVehicleTireSpeedState& tireSpeedState, const PxVehicleWheelRigidBody1dState& wheelRigidBody1dState, + PxVehicleTireSlipState& tireSlipState); + + +/** +\brief Compute the camber angle of the wheel +\param[in] suspensionParams describes the frame of the suspension and wheel. +\param[in] steerAngle is the steer angle in radians to be applied to the wheel. +\param[in] roadGeometryState describes the plane of the road geometry under the wheel. +\param[in] complianceState is a description of the camber and toe angle that arise from suspension compliance. +\param[in] rigidBodyState describes the current pose of the vehicle's rigid body in the world frame. +\param[in] frame is a description of the vehicle's lateral and longitudinal axes. +\param[out] tireCamberAngleState is the computed camber angle of the tire expressed in radians. +*/ +void PxVehicleTireCamberAnglesUpdate +(const PxVehicleSuspensionParams& suspensionParams, + const PxReal steerAngle, const PxVehicleRoadGeometryState& roadGeometryState, const PxVehicleSuspensionComplianceState& complianceState, + const PxVehicleRigidBodyState& rigidBodyState, + const PxVehicleFrame& frame, + PxVehicleTireCamberAngleState& tireCamberAngleState); + +/** +\brief Compute the load and friction experienced by the tire. +\param[in] tireForceParams describes the tire's friction response to longitudinal lip angle and its load response. +\param[in] roadGeometryState describes the plane of the road geometry under the wheel. +\param[in] suspensionState is the current suspension compression state. +\param[in] suspensionForce is the force that the suspension exerts on the sprung mass of the suspension. +\param[in] tireSlipState is the tire longitudinal and lateral slip angles. +\param[out] tireGripState is the computed load and friction experienced by the tire. +\note If the suspension cannot place the wheel on the ground the tire load and friction will be 0.0. +*/ +void PxVehicleTireGripUpdate +(const PxVehicleTireForceParams& tireForceParams, + const PxVehicleRoadGeometryState& roadGeometryState, const PxVehicleSuspensionState& suspensionState, const PxVehicleSuspensionForce& suspensionForce, + const PxVehicleTireSlipState& tireSlipState, + PxVehicleTireGripState& tireGripState); + +/** +\brief When a tire has been at a very low speed for a threshold time without application of drive torque, a +secondary tire model is applied to bring the tire to rest using velocity constraints that asymptotically approach zero speed +along the tire's lateral and longitudinal directions. This secondary tire model is referred to as the sticky tire model and the +tire is considered to be in the sticky tire state when the speed and time conditions are satisfied. The purpose of +PxVehicleTireStickyStateUpdate is to compute the target speeds of the sticky state and to record whether sticky state is +active or not. +\param[in] axleDescription is the axles of the vehicle and the wheels on each axle. +\param[in] wheelParams describes the radius of the wheel +\param[in] tireStickyParams describe the threshold speeds and times for the lateral and longitudinal sticky states. +\param[in] actuationStates describes whether each wheel experiences a drive torque. +\param[in] tireGripState is the load and friction experienced by the tire. +\param[in] tireSpeedState is the component of rigid body velocity at the tire contact point projected along the +tire's longitudinal and lateral axes. +\param[in] wheelRigidBody1dState is the wheel rotation speed. +\param[in] dt is the simulation time that has lapsed since the last call to PxVehicleTireStickyStateUpdate +\param[out] tireStickyState is a description of the sticky state of the tire in the longitudinal and lateral directions. +\note The velocity constraints are maintained through integration with the PhysX scene using the function +PxVehiclePhysXConstraintStatesUpdate. Alternative implementations independent of PhysX are possible. +@see PxVehiclePhysXConstraintStatesUpdate +@see PxVehicleTireSlipsAccountingForStickyStatesUpdate +*/ +void PxVehicleTireStickyStateUpdate +(const PxVehicleAxleDescription& axleDescription, const PxVehicleWheelParams& wheelParams, + const PxVehicleTireStickyParams& tireStickyParams, + const PxVehicleArrayData& actuationStates, + const PxVehicleTireGripState& tireGripState, const PxVehicleTireSpeedState& tireSpeedState, const PxVehicleWheelRigidBody1dState& wheelRigidBody1dState, + const PxReal dt, + PxVehicleTireStickyState& tireStickyState); + +/** +\brief Set the tire longitudinal and lateral slip values to 0.0 in the event that the tire has entred tire sticky state. This is +necessary to avoid both tire models being simultaneously active and interfering with each other. +\param[in] tireStickyState is a description of the sticky state of the tire in the longitudinal and lateral directions. +\param[out] tireSlipState is the updated lateral and longudinal slip with either set to 0.0 in the event that the correspoinding +sticky state is active. +\note This function should not be invoked if there is no subsequent component to implement the sticky tire model. +*/ +void PxVehicleTireSlipsAccountingForStickyStatesUpdate +(const PxVehicleTireStickyState& tireStickyState, + PxVehicleTireSlipState& tireSlipState); + +/** +\brief Compute the longitudinal and lateral forces in the world frame that develop on the tire as a consequence of +the tire's slip angles, friction and load. +\param[in] wheelParams describes the radius and half-width of the wheel. +\param[in] suspensionParams describes the frame of the suspension and wheel. +\param[in] tireForceParams describes the conversion of slip angle, friction and load to a force along the longitudinal +and lateral directions of the tire. +\param[in] complianceState is a description of the camber and toe angle that arise from suspension compliance. +\param[out] tireGripState is the load and friction experienced by the tire. +\param[in] tireDirectionState is the tire's longitudinal and lateral directions in the ground plane. +\param[in] tireSlipState is the longitudinal and lateral slip angles. +\param[in] tireCamberAngleState is the camber angle of the tire expressed in radians. +\param[in] rigidBodyState describes the current pose of the vehicle's rigid body in the world frame. +\param[out] tireForce is the computed tire forces in the world frame. +*/ +void PxVehicleTireForcesUpdate +(const PxVehicleWheelParams& wheelParams, const PxVehicleSuspensionParams& suspensionParams, + const PxVehicleTireForceParams& tireForceParams, + const PxVehicleSuspensionComplianceState& complianceState, + const PxVehicleTireGripState& tireGripState, const PxVehicleTireDirectionState& tireDirectionState, + const PxVehicleTireSlipState& tireSlipState, const PxVehicleTireCamberAngleState& tireCamberAngleState, + const PxVehicleRigidBodyState& rigidBodyState, + PxVehicleTireForce& tireForce); + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/tire/PxVehicleTireHelpers.h b/Source/ThirdParty/PhysX/vehicle2/tire/PxVehicleTireHelpers.h new file mode 100644 index 000000000..5a6d1eb41 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/tire/PxVehicleTireHelpers.h @@ -0,0 +1,73 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once +/** \addtogroup vehicle2 + @{ +*/ + +#include "vehicle2/PxVehicleParams.h" +#include "vehicle2/wheel/PxVehicleWheelStates.h" +#include "PxVehicleTireStates.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +/** +\brief Compute the intention to accelerate by inspecting the actuation states of the wheels of a powered vehicle. +\param[in] poweredVehicleAxleDesc describes the axles and wheels of a powered vehicle in a jointed ensemble of vehicles. +\param[in] poweredVehicleActuationStates describes the drive state of each wheel of the powered vehicle. +@see PxVehicleTireStickyStateReset +*/ +bool PxVehicleAccelerationIntentCompute +(const PxVehicleAxleDescription& poweredVehicleAxleDesc, const PxVehicleArrayData& poweredVehicleActuationStates); + +/** +\brief Reset the sticky tire states of an unpowered vehicle if it is in a jointed ensemble of vehicles with at least one powered vehicle. +\param[in] poweredVehicleIntentionToAccelerate describes the state of the powered vehicle in an ensemble of jointed vehicles. +\param[in] unpoweredVehicleAxleDesc describes the axles and wheels of an unpowered vehicle towed by a powered vehicle. +\param[out] unpoweredVehicleStickyState is the sticky state of the wheels of an unpowered vehicle towed by a powered vehicle. +\note If any wheel on the powered vehicle is to receive a drive torque, the sticky tire states of the towed vehicle will be reset to the deactivated state. +\note poweredVehicleIntentionToAccelerate may be computed using PxVehicleAccelerationIntentCompute(). +@see PxVehicleAccelerationIntentCompute +*/ +void PxVehicleTireStickyStateReset +(const bool poweredVehicleIntentionToAccelerate, + const PxVehicleAxleDescription& unpoweredVehicleAxleDesc, + PxVehicleArrayData& unpoweredVehicleStickyState); + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/tire/PxVehicleTireParams.h b/Source/ThirdParty/PhysX/vehicle2/tire/PxVehicleTireParams.h new file mode 100644 index 000000000..a47428a54 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/tire/PxVehicleTireParams.h @@ -0,0 +1,166 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "foundation/PxFoundation.h" + +#include "vehicle2/PxVehicleParams.h" + +#include "PxVehicleTireStates.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +struct PxVehicleTireForceParams +{ + /** + \brief Tire lateral stiffness is a graph of tire load that has linear behavior near zero load and + flattens at large loads. latStiffX describes the minimum normalized load (load/restLoad) that gives a + flat lateral stiffness response to load. + \note A value of 0.0 indicates that the tire lateral stiffness is independent of load and will adopt + the value #latStiffY for all values of tire load. + */ + PxReal latStiffX; + + /** + \brief Tire lateral stiffness is a graph of tire load that has linear behavior near zero load and + flattens at large loads. latStiffY describes the maximum possible value of lateral stiffness that occurs + when (load/restLoad) >= #latStiffX. + + Unit: force per lateral slip = mass * length / (time^2) + */ + PxReal latStiffY; + + /** + \brief Tire Longitudinal stiffness + \note Longitudinal force can be approximated as longStiff*longitudinalSlip. + + Unit: force per longitudinal slip = mass * length / (time^2) + */ + PxReal longStiff; + + /** + \brief Tire camber stiffness + \note Camber force can be approximated as camberStiff*camberAngle. + + Unit: force per radian = mass * length / (time^2) + */ + PxReal camberStiff; + + /** + \brief Graph of friction vs longitudinal slip with 3 points. + \note frictionVsSlip[0][0] is always zero. + \note frictionVsSlip[0][1] is the friction available at zero longitudinal slip. + \note frictionVsSlip[1][0] is the value of longitudinal slip with maximum friction. + \note frictionVsSlip[1][1] is the maximum friction. + \note frictionVsSlip[2][0] is the end point of the graph. + \note frictionVsSlip[2][1] is the value of friction for slips greater than frictionVsSlip[2][0]. + \note The friction value is computed from the friction vs longitudinal slip graph using linear interpolation. + \note The friction value computed from the friction vs longitudinal slip graph is used to scale the friction + value of the road geometry. + \note frictionVsSlip[2][0] > frictionVsSlip[1][0] > frictionVsSlip[0][0] + \note frictionVsSlip[1][1] is typically greater than frictionVsSlip[0][1] + \note frictionVsSlip[2][1] is typically smaller than frictionVsSlip[1][1] + \note longitudinal slips > frictionVsSlip[2][0] use friction multiplier frictionVsSlip[2][1] + */ + PxReal frictionVsSlip[3][2]; //3 (x,y) points + + /** + \brief The rest load is the load that develops on the tire when the vehicle is at rest on a flat plane. + \note The rest load is approximately the product of gravitational acceleration and (sprungMass + wheelMass). + + Unit: force = mass * length / (time^2) + */ + PxReal restLoad; + + /** + \brief Tire load variation can be strongly dependent on the time-step so it is a good idea to filter it + to give less jerky handling behavior. + \note Tire load filtering is implemented by linear interpolating a graph containing just two points. + The x-axis of the graph is normalized tire load, while the y-axis is the filtered normalized tire load that is + to be applied during the tire force calculation. + \note The normalized load is the force acting downwards on the tire divided by restLoad. + \note The minimum possible normalized load is zero. + \note There are two points on the graph: (minNormalisedLoad, minNormalisedFilteredLoad) and (maxNormalisedLoad, maxFilteredNormalisedLoad). + \note Normalized loads less than minNormalisedLoad have filtered normalized load = minNormalisedFilteredLoad. + \note Normalized loads greater than maxNormalisedLoad have filtered normalized load = maxFilteredNormalisedLoad. + \note Normalized loads in-between are linearly interpolated between minNormalisedFilteredLoad and maxFilteredNormalisedLoad. + \note The tire load applied as input to the tire force computation is the filtered normalized load multiplied by the rest load. + \note loadFilter[0][0] is minNormalisedLoad + \note loadFilter[0][1] is minFilteredNormalisedLoad + \note loadFilter[1][0] is maxNormalisedLoad + \note loadFilter[1][1] is maxFilteredNormalisedLoad + */ + PxReal loadFilter[2][2]; //2 (x,y) points + + PX_FORCE_INLINE PxVehicleTireForceParams transformAndScale( + const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const + { + PX_UNUSED(srcFrame); + PX_UNUSED(trgFrame); + PxVehicleTireForceParams r = *this; + const PxReal scale = trgScale.scale / srcScale.scale; + r.latStiffY *= scale; + r.longStiff *= scale; + r.camberStiff *= scale; + r.restLoad *= scale; + return r; + } + + PX_FORCE_INLINE bool isValid() const + { + PX_CHECK_AND_RETURN_VAL(latStiffX >= 0, "PxVehicleTireForceParams.latStiffX must be greater than or equal to zero", false); + PX_CHECK_AND_RETURN_VAL(latStiffY > 0, "PxVehicleTireForceParams.latStiffY must be greater than zero", false); + PX_CHECK_AND_RETURN_VAL(longStiff > 0, "PxVehicleTireForceParams.longStiff must be greater than zero", false); + PX_CHECK_AND_RETURN_VAL(camberStiff >= 0, "PxVehicleTireForceParams.camberStiff must be greater than or equal zero", false); + PX_CHECK_AND_RETURN_VAL(restLoad > 0, "PxVehicleTireForceParams.restLoad must be greater than zero", false); + PX_CHECK_AND_RETURN_VAL(loadFilter[1][0] >= loadFilter[0][0], "PxVehicleTireForceParams.loadFilter[1][0] must be greater than or equal to PxVehicleTireForceParams.loadFilter[0][0]", false); + PX_CHECK_AND_RETURN_VAL(loadFilter[1][1] > 0, "PxVehicleTireLoadFilterData.loadFilter[1][1] must be greater than zero", false); + PX_CHECK_AND_RETURN_VAL(0.0f == loadFilter[0][0], "PxVehicleTireLoadFilterData.loadFilter[0][0] must be equal to zero", false); + PX_CHECK_AND_RETURN_VAL(frictionVsSlip[0][0] >= 0.0f && frictionVsSlip[0][1] >= 0.0f, "Illegal values for frictionVsSlip[0]", false); + PX_CHECK_AND_RETURN_VAL(frictionVsSlip[1][0] >= 0.0f && frictionVsSlip[1][1] >= 0.0f, "Illegal values for frictionVsSlip[1]", false); + PX_CHECK_AND_RETURN_VAL(frictionVsSlip[2][0] >= 0.0f && frictionVsSlip[2][1] >= 0.0f, "Illegal values for frictionVsSlip[2]", false); + return true; + } +}; + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/tire/PxVehicleTireStates.h b/Source/ThirdParty/PhysX/vehicle2/tire/PxVehicleTireStates.h new file mode 100644 index 000000000..7e666dba7 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/tire/PxVehicleTireStates.h @@ -0,0 +1,181 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once +/** \addtogroup vehicle2 + @{ +*/ + +#include "foundation/PxVec3.h" +#include "foundation/PxMemory.h" + +#include "vehicle2/PxVehicleParams.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + + +/** +\brief PxVehicleTireDirectionState stores the world frame lateral and longtidinal axes of the tire after +projecting the wheel pose in the world frame onto the road geometry plane (also in the world frame). +*/ +struct PxVehicleTireDirectionState +{ + PxVec3 directions[PxVehicleTireDirectionModes::eMAX_NB_PLANAR_DIRECTIONS]; + + PX_FORCE_INLINE void setToDefault() + { + PxMemZero(this, sizeof(PxVehicleTireDirectionState)); + } +}; + + +/** +\brief PxVehicleTireSpeedState stores the components of the instantaneous velocity of the rigid body at the tire contact point projected +along the lateral and longitudinal axes of the tire. +@see PxVehicleTireDirectionState +*/ +struct PxVehicleTireSpeedState +{ + PxReal speedStates[PxVehicleTireDirectionModes::eMAX_NB_PLANAR_DIRECTIONS]; + + PX_FORCE_INLINE void setToDefault() + { + PxMemZero(this, sizeof(PxVehicleTireSpeedState)); + } +}; + +/** +\brief The lateral and longitudinal tire slips. +@see PxVehicleTireSpeedState +*/ +struct PxVehicleTireSlipState +{ + PxReal slips[PxVehicleTireDirectionModes::eMAX_NB_PLANAR_DIRECTIONS]; + + PX_FORCE_INLINE void setToDefault() + { + PxMemZero(this, sizeof(PxVehicleTireSlipState)); + } +}; + +/** +\brief The load and friction experienced by a tire. +*/ +struct PxVehicleTireGripState +{ + /** + \brief The tire load + + Unit: force = mass * length / (time^2) + */ + PxReal load; + + /** + \brief The tire friction is the product of the road geometry friction and a friction response multiplier. + */ + PxReal friction; + + PX_FORCE_INLINE void setToDefault() + { + PxMemZero(this, sizeof(PxVehicleTireGripState)); + } +}; + +/** +\brief Camber angle of the tire relative to the ground plane. +*/ +struct PxVehicleTireCamberAngleState +{ + PxReal camberAngle; + + PX_FORCE_INLINE void setToDefault() + { + PxMemZero(this, sizeof(PxVehicleTireCamberAngleState)); + } +}; + +/** +\brief Prolonged low speeds in the lateral and longitudinal directions may be handled with "sticky" velocity constraints that activate after +a speed below a threshold has been recorded for a threshold time. +@see PxVehicleTireStickyParams +@see PxVehicleTireSpeedState +*/ +struct PxVehicleTireStickyState +{ + PxReal lowSpeedTime[PxVehicleTireDirectionModes::eMAX_NB_PLANAR_DIRECTIONS]; + bool activeStatus[PxVehicleTireDirectionModes::eMAX_NB_PLANAR_DIRECTIONS]; + + PX_FORCE_INLINE void setToDefault() + { + PxMemZero(this, sizeof(PxVehicleTireStickyState)); + } +}; + +/** +\brief The longitudinal/lateral forces/torques that develop on the tire. +*/ +struct PxVehicleTireForce +{ + /* + \brief The tire forces that develop along the tire's longitudinal and lateral directions. Specified in the world frame. + */ + PxVec3 forces[PxVehicleTireDirectionModes::eMAX_NB_PLANAR_DIRECTIONS]; + + /* + \brief The tire torques that develop around the tire's longitudinal and lateral directions. Specified in the world frame. + */ + PxVec3 torques[PxVehicleTireDirectionModes::eMAX_NB_PLANAR_DIRECTIONS]; + + /** + \brief The aligning moment may be propagated to a torque-driven steering controller. + */ + PxReal aligningMoment; + + /** + \brief The torque to apply to the wheel's 1d rigid body. + */ + PxReal wheelTorque; + + PX_FORCE_INLINE void setToDefault() + { + PxMemZero(this, sizeof(PxVehicleTireForce)); + } +}; + + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/wheel/PxVehicleWheelComponents.h b/Source/ThirdParty/PhysX/vehicle2/wheel/PxVehicleWheelComponents.h new file mode 100644 index 000000000..bb3ca8484 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/wheel/PxVehicleWheelComponents.h @@ -0,0 +1,120 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "vehicle2/PxVehicleParams.h" +#include "vehicle2/PxVehicleComponent.h" + +#include "vehicle2/commands/PxVehicleCommandHelpers.h" +#include "vehicle2/tire/PxVehicleTireStates.h" + +#include "PxVehicleWheelFunctions.h" +#include "PxVehicleWheelHelpers.h" + +#include "common/PxProfileZone.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +class PxVehicleWheelComponent : public PxVehicleComponent +{ +public: + + PxVehicleWheelComponent() : PxVehicleComponent() {} + virtual ~PxVehicleWheelComponent() {} + + virtual void getDataForWheelComponent( + const PxVehicleAxleDescription*& axleDescription, + PxVehicleArrayData& steerResponseStates, + PxVehicleArrayData& wheelParams, + PxVehicleArrayData& suspensionParams, + PxVehicleArrayData& actuationStates, + PxVehicleArrayData& suspensionStates, + PxVehicleArrayData& suspensionComplianceStates, + PxVehicleArrayData& tireSpeedStates, + PxVehicleArrayData& wheelRigidBody1dStates, + PxVehicleArrayData& wheelLocalPoses) = 0; + + virtual bool update(const PxReal dt, const PxVehicleSimulationContext& context) + { + PX_PROFILE_ZONE("PxVehicleWheelComponent::update", 0); + + const PxVehicleAxleDescription* axleDescription; + PxVehicleArrayData steerResponseStates; + PxVehicleArrayData wheelParams; + PxVehicleArrayData suspensionParams; + PxVehicleArrayData actuationStates; + PxVehicleArrayData suspensionStates; + PxVehicleArrayData suspensionComplianceStates; + PxVehicleArrayData tireSpeedStates; + PxVehicleArrayData wheelRigidBody1dStates; + PxVehicleArrayData wheelLocalPoses; + + getDataForWheelComponent(axleDescription, steerResponseStates, + wheelParams, suspensionParams, actuationStates, suspensionStates, + suspensionComplianceStates, tireSpeedStates, wheelRigidBody1dStates, + wheelLocalPoses); + + for (PxU32 i = 0; i < axleDescription->nbWheels; i++) + { + const PxU32 wheelId = axleDescription->wheelIdsInAxleOrder[i]; + + PxVehicleWheelRotationAngleUpdate( + wheelParams[wheelId], + actuationStates[wheelId], suspensionStates[wheelId], + tireSpeedStates[wheelId], + context.thresholdForwardSpeedForWheelAngleIntegration, dt, + wheelRigidBody1dStates[wheelId]); + + wheelLocalPoses[wheelId].localPose = PxVehicleComputeWheelLocalPose(context.frame, + suspensionParams[wheelId], + suspensionStates[wheelId], + suspensionComplianceStates[wheelId], + steerResponseStates[wheelId], + wheelRigidBody1dStates[wheelId]); + } + + return true; + } +}; + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/wheel/PxVehicleWheelFunctions.h b/Source/ThirdParty/PhysX/vehicle2/wheel/PxVehicleWheelFunctions.h new file mode 100644 index 000000000..cd5588c48 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/wheel/PxVehicleWheelFunctions.h @@ -0,0 +1,81 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "foundation/PxSimpleTypes.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +struct PxVehicleWheelParams; +struct PxVehicleWheelActuationState; +struct PxVehicleSuspensionState; +struct PxVehicleTireSpeedState; +struct PxVehicleScale; +struct PxVehicleWheelRigidBody1dState; + +/** +\brief Forward integrate the rotation angle of a wheel +\note The rotation angle of the wheel plays no role in simulation but is important to compute the pose of the wheel for rendering. +\param[in] wheelParams describes the radius and half-width of the wheel +\param[in] actuationState describes whether the wheel has drive or brake torque applied to it. +\param[in] suspensionState describes whether the wheel touches the ground. +\param[in] tireSpeedState describes the components of rigid body velocity at the ground contact point along the tire's lateral and longitudinal directions. +\param[in] thresholdForwardSpeedForWheelAngleIntegration Forward wheel speed below which the wheel rotation speed gets blended with the rolling + speed (based on the forward wheel speed) which is then used to integrate the wheel rotation angle. At low forward wheel speed, the wheel + rotation speed can get unstable (depending on the tire model used) and, for example, oscillate. If brake or throttle is applied, there + will be no blending. +\param[in] dt is the simulation time that has lapsed since the last call to PxVehicleWheelRotationAngleUpdate +\param[in,out] wheelRigidBody1dState describes the current angular speed and angle of the wheel. +\note At low speeds and large timesteps, wheel rotation speed can become noisy due to singularities in the tire slip computations. +At low speeds, therefore, the wheel speed used for integrating the angle is a blend of current angular speed and rolling angular speed if the +wheel experiences neither brake nor drive torque and can be placed on the ground. The blended rotation speed gets stored in +PxVehicleWheelRigidBody1dState::correctedRotationSpeed. +*/ +void PxVehicleWheelRotationAngleUpdate +(const PxVehicleWheelParams& wheelParams, + const PxVehicleWheelActuationState& actuationState, const PxVehicleSuspensionState& suspensionState, const PxVehicleTireSpeedState& tireSpeedState, + const PxReal thresholdForwardSpeedForWheelAngleIntegration, const PxReal dt, + PxVehicleWheelRigidBody1dState& wheelRigidBody1dState); + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ + diff --git a/Source/ThirdParty/PhysX/vehicle2/wheel/PxVehicleWheelHelpers.h b/Source/ThirdParty/PhysX/vehicle2/wheel/PxVehicleWheelHelpers.h new file mode 100644 index 000000000..5a62db2df --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/wheel/PxVehicleWheelHelpers.h @@ -0,0 +1,221 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "vehicle2/PxVehicleFunctions.h" + +#include "vehicle2/suspension/PxVehicleSuspensionParams.h" +#include "vehicle2/suspension/PxVehicleSuspensionStates.h" + +#include "PxVehicleWheelParams.h" +#include "PxVehicleWheelStates.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +/** +\brief Compute the quaternion of a wheel in the rigid body frame. +\param[in] frame describes the longitudinal and lateral axes of the vehicle. +\param[in] suspensionParams describes the suspension and wheel frames. +\param[in] camberAngle is the camber angle in radian sinduced by suspension compliance. +\param[in] toeAngle is the toe angle in radians induced by suspension compliance. +\param[in] steerAngle is the steer angle in radians applied to the wheel. +\param[in] rotationAngle is the angle around the wheel's lateral axis. +\return The quaterion of the wheel in the rigid body frame. +@see PxVehicleComputeWheelOrientation +*/ +PX_FORCE_INLINE PxQuat PxVehicleComputeWheelLocalOrientation +(const PxVehicleFrame& frame, + const PxVehicleSuspensionParams& suspensionParams, + const PxReal camberAngle, const PxReal toeAngle, const PxReal steerAngle, + const PxReal rotationAngle) +{ + const PxQuat wheelLocalOrientation = + (suspensionParams.suspensionAttachment.q * PxVehicleComputeRotation(frame, camberAngle, 0.0f, steerAngle + toeAngle))* + (suspensionParams.wheelAttachment.q * PxVehicleComputeRotation(frame, 0.0f, rotationAngle, 0.0f)); + return wheelLocalOrientation; +} + +/** +\brief Compute the quaternion of a wheel in the world frame. +\param[in] frame describes the longitudinal and lateral axes of the vehicle. +\param[in] suspensionParams describes the suspension and wheel frames. +\param[in] camberAngle is the camber angle in radian induced by suspension compliance. +\param[in] toeAngle is the toe angle in radians induced by suspension compliance. +\param[in] steerAngle is the steer angle in radians applied to the wheel. +\param[in] rigidBodyOrientation is the quaterion of the rigid body in the world frame. +\param[in] rotationAngle is the angle around the wheel's lateral axis. +\return The quaterion of the wheel in the world frame. +@see PxVehicleComputeWheelLocalOrientation +*/ +PX_FORCE_INLINE PxQuat PxVehicleComputeWheelOrientation +(const PxVehicleFrame& frame, + const PxVehicleSuspensionParams& suspensionParams, + const PxReal camberAngle, const PxReal toeAngle, const PxReal steerAngle, + const PxQuat& rigidBodyOrientation, const PxReal rotationAngle) +{ + const PxQuat wheelOrientation = rigidBodyOrientation * PxVehicleComputeWheelLocalOrientation(frame, suspensionParams, + camberAngle, toeAngle, steerAngle, rotationAngle); + return wheelOrientation; +} + +/** +\brief Compute the pose of the wheel in the rigid body frame. +\param[in] frame describes the longitudinal and lateral axes of the vehicle. +\param[in] suspensionParams describes the suspension and wheel frames. +\param[in] suspensionState is the compression state of the suspenson. +\param[in] camberAngle is the camber angle in radian induced by suspension compliance. +\param[in] toeAngle is the toe angle in radians induced by suspension compliance. +\param[in] steerAngle is the steer angle in radians applied to the wheel. +\param[in] rotationAngle is the angle around the wheel's lateral axis. +\return The pose of the wheel in the rigid body frame. +*/ +PX_FORCE_INLINE PxTransform PxVehicleComputeWheelLocalPose +(const PxVehicleFrame& frame, + const PxVehicleSuspensionParams& suspensionParams, + const PxVehicleSuspensionState& suspensionState, + const PxReal camberAngle, const PxReal toeAngle, const PxReal steerAngle, + const PxReal rotationAngle) +{ + //Full equation: + //PxTransform(suspAttachment.p + suspParams.suspensionTravelDir*suspDist, suspAttachment.q) * + //PxTransform(PxVec3(0), PxQuat(camber, 0, steer+toe)) * + //wheelAttachment * + //PxTransform(PxVec3(0), PxQuat(0, rotation, 0)) + //Reduces to: + //PxTransform(suspAttachment.p + suspParams.suspensionTravelDir*suspDist, suspAttachment.q * PxQuat(camber, 0, steer+toe)) * + //PxTranfsorm(wheelAttachment.p, wheelAttachment.q * PxQuat(0, rotation, 0)) + const PxF32 suspDist = (suspensionState.jounce != PX_VEHICLE_UNSPECIFIED_JOUNCE) ? (suspensionParams.suspensionTravelDist - suspensionState.jounce) : 0.0f; + const PxTransform wheelLocalPose = + PxTransform( + suspensionParams.suspensionAttachment.p + suspensionParams.suspensionTravelDir*suspDist, + suspensionParams.suspensionAttachment.q*PxVehicleComputeRotation(frame, camberAngle, 0.0f, steerAngle + toeAngle))* + PxTransform( + suspensionParams.wheelAttachment.p, + suspensionParams.wheelAttachment.q*PxVehicleComputeRotation(frame, 0.0f, rotationAngle, 0.0f)); + return wheelLocalPose; +} + + +/** +\brief Compute the pose of the wheel in the rigid body frame. +\param[in] frame describes the longitudinal and lateral axes of the vehicle. +\param[in] suspensionParams describes the suspension and wheel frames. +\param[in] suspensionState is the compression state of the suspenson. +\param[in] suspensionComplianceState is the camber and toe angles induced by suspension compliance. +\param[in] steerAngle is the steer angle in radians applied to the wheel. +\param[in] wheelState is angle around the wheel's lateral axis. +\return The pose of the wheel in the rigid body frame. +*/ +PX_FORCE_INLINE PxTransform PxVehicleComputeWheelLocalPose +(const PxVehicleFrame& frame, + const PxVehicleSuspensionParams& suspensionParams, + const PxVehicleSuspensionState& suspensionState, const PxVehicleSuspensionComplianceState& suspensionComplianceState, + const PxReal steerAngle, + const PxVehicleWheelRigidBody1dState& wheelState) +{ + return PxVehicleComputeWheelLocalPose(frame, suspensionParams, suspensionState, + suspensionComplianceState.camber, suspensionComplianceState.toe, steerAngle, + wheelState.rotationAngle); +} + +/** +\brief Compute the pose of the wheel in the world frame. +\param[in] frame describes the longitudinal and lateral axes of the vehicle. +\param[in] suspensionParams describes the suspension and wheel frames. +\param[in] suspensionState is the compression state of the suspenson. +\param[in] camberAngle is the camber angle in radian induced by suspension compliance. +\param[in] toeAngle is the toe angle in radians induced by suspension compliance. +\param[in] steerAngle is the steer angle in radians applied to the wheel. +\param[in] rigidBodyPose is the pose of the rigid body in the world frame. +\param[in] rotationAngle is the angle around the wheel's lateral axis. +\return The pose of the wheel in the world frame. +*/ +PX_FORCE_INLINE PxTransform PxVehicleComputeWheelPose +(const PxVehicleFrame& frame, + const PxVehicleSuspensionParams& suspensionParams, + const PxVehicleSuspensionState& suspensionState, + const PxReal camberAngle, const PxReal toeAngle, const PxReal steerAngle, + const PxTransform& rigidBodyPose, const PxReal rotationAngle) +{ + const PxTransform wheelPose = rigidBodyPose * PxVehicleComputeWheelLocalPose(frame, suspensionParams, suspensionState, + camberAngle, toeAngle, steerAngle, rotationAngle); + return wheelPose; +} + +/** +\brief Compute the pose of the wheel in the world frame. +\param[in] frame describes the longitudinal and lateral axes of the vehicle. +\param[in] suspensionParams describes the suspension and wheel frames. +\param[in] suspensionState is the compression state of the suspenson. +\param[in] suspensionComplianceState is the camber and toe angles induced by suspension compliance. +\param[in] steerAngle is the steer angle in radians applied to the wheel. +\param[in] rigidBodyPose is the pose of the rigid body in the world frame. +\param[in] wheelState is angle around the wheel's lateral axis. +\return The pose of the wheel in the world frame. +*/ + +PX_FORCE_INLINE PxTransform PxVehicleComputeWheelPose +(const PxVehicleFrame& frame, + const PxVehicleSuspensionParams& suspensionParams, + const PxVehicleSuspensionState& suspensionState, const PxVehicleSuspensionComplianceState& suspensionComplianceState, const PxReal steerAngle, + const PxTransform& rigidBodyPose, const PxVehicleWheelRigidBody1dState& wheelState) +{ + return PxVehicleComputeWheelPose(frame, suspensionParams, suspensionState, + suspensionComplianceState.camber, suspensionComplianceState.toe, steerAngle, + rigidBodyPose, wheelState.rotationAngle); +} + +/** +\brief Check if the suspension could place the wheel on the ground or not. + +\param[in] suspState The state of the suspension to check. +\return True if the wheel connects to the ground, else false. + +@see PxVehicleSuspensionState +*/ +PX_FORCE_INLINE bool PxVehicleIsWheelOnGround(const PxVehicleSuspensionState& suspState) +{ + return (suspState.separation <= 0.0f); +} + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/ThirdParty/PhysX/vehicle2/wheel/PxVehicleWheelParams.h b/Source/ThirdParty/PhysX/vehicle2/wheel/PxVehicleWheelParams.h new file mode 100644 index 000000000..016f0ccfd --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/wheel/PxVehicleWheelParams.h @@ -0,0 +1,119 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "foundation/PxFoundation.h" + +#include "vehicle2/PxVehicleParams.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +struct PxVehicleWheelParams +{ + /** + \brief Radius of unit that includes metal wheel plus rubber tire. + + Range: (0, inf)
+ Unit: length + */ + PxReal radius; + + /** + \brief Half-width of unit that includes wheel plus tire. + + Range: (0, inf)
+ Unit: length + */ + PxReal halfWidth; + + /** + \brief Mass of unit that includes wheel plus tire. + + Range: (0, inf)
+ Unit: mass + */ + PxReal mass; + + /** + \brief Moment of inertia of unit that includes wheel plus tire about the rolling axis. + + Range: (0, inf)
+ Unit: mass * (length^2) + */ + PxReal moi; + + /** + \brief Damping rate applied to wheel. + + Range: [0, inf)
+ Unit: torque * time = mass * (length^2) / time + */ + PxReal dampingRate; + + PX_FORCE_INLINE PxVehicleWheelParams transformAndScale( + const PxVehicleFrame& srcFrame, const PxVehicleFrame& trgFrame, const PxVehicleScale& srcScale, const PxVehicleScale& trgScale) const + { + PX_UNUSED(srcFrame); + PX_UNUSED(trgFrame); + PxVehicleWheelParams r = *this; + const PxReal scale = trgScale.scale/srcScale.scale; + r.radius *= scale; + r.halfWidth *= scale; + r.moi *= (scale*scale); + r.dampingRate *= (scale*scale); + return r; + } + + PX_FORCE_INLINE bool isValid() const + { + PX_CHECK_AND_RETURN_VAL(radius > 0.0f, "PxVehicleWheelParams.radius must be greater than zero", false); + PX_CHECK_AND_RETURN_VAL(halfWidth > 0.0f, "PxVehicleWheelParams.halfWidth must be greater than zero", false); + PX_CHECK_AND_RETURN_VAL(mass > 0.0f, "PxVehicleWheelParams.mass must be greater than zero", false); + PX_CHECK_AND_RETURN_VAL(moi > 0.0f, "PxVehicleWheelParams.moi must be greater than zero", false); + PX_CHECK_AND_RETURN_VAL(dampingRate >= 0.0f, "PxVehicleWheelParams.dampingRate must be greater than or equal to zero", false); + return true; + } +}; + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ + diff --git a/Source/ThirdParty/PhysX/vehicle2/wheel/PxVehicleWheelStates.h b/Source/ThirdParty/PhysX/vehicle2/wheel/PxVehicleWheelStates.h new file mode 100644 index 000000000..01b28d227 --- /dev/null +++ b/Source/ThirdParty/PhysX/vehicle2/wheel/PxVehicleWheelStates.h @@ -0,0 +1,108 @@ +// Redistribution and use in source and binary forms, with or without +// modification, are permitted provided that the following conditions +// are met: +// * Redistributions of source code must retain the above copyright +// notice, this list of conditions and the following disclaimer. +// * Redistributions in binary form must reproduce the above copyright +// notice, this list of conditions and the following disclaimer in the +// documentation and/or other materials provided with the distribution. +// * Neither the name of NVIDIA CORPORATION nor the names of its +// contributors may be used to endorse or promote products derived +// from this software without specific prior written permission. +// +// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ''AS IS'' AND ANY +// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +// EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR +// PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY +// OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +// +// Copyright (c) 2008-2023 NVIDIA Corporation. All rights reserved. +// Copyright (c) 2004-2008 AGEIA Technologies, Inc. All rights reserved. +// Copyright (c) 2001-2004 NovodeX AG. All rights reserved. + +#pragma once + +/** \addtogroup vehicle2 + @{ +*/ + +#include "foundation/PxSimpleTypes.h" +#include "foundation/PxTransform.h" +#include "foundation/PxMemory.h" + +#if !PX_DOXYGEN +namespace physx +{ +namespace vehicle2 +{ +#endif + +/** +\brief It is useful to know if a brake or drive torque is to be applied to a wheel. +*/ +struct PxVehicleWheelActuationState +{ + bool isBrakeApplied; //!< True if a brake torque is applied, false if not. + bool isDriveApplied; //!< True if a drive torque is applied, false if not. + + PX_FORCE_INLINE void setToDefault() + { + PxMemZero(this, sizeof(PxVehicleWheelActuationState)); + } +}; + +struct PxVehicleWheelRigidBody1dState +{ + /** + \brief The rotation speed of the wheel around the lateral axis. + + Unit: radians / time + */ + PxReal rotationSpeed; + + /** + \brief The corrected rotation speed of the wheel around the lateral axis in radians per second. + + At low forward wheel speed, the wheel rotation speed can get unstable (depending on the tire + model used) and, for example, oscillate. To integrate the wheel rotation angle, a (potentially) + blended rotation speed is used which gets stored in #correctedRotationSpeed. + + Unit: radians / time + + @see PxVehicleSimulationContext::thresholdForwardSpeedForWheelAngleIntegration + */ + PxReal correctedRotationSpeed; + + /** + \brief The accumulated angle of the wheel around the lateral axis in radians in range (-2*Pi,2*Pi) + */ + PxReal rotationAngle; + + PX_FORCE_INLINE void setToDefault() + { + PxMemZero(this, sizeof(PxVehicleWheelRigidBody1dState)); + } +}; + +struct PxVehicleWheelLocalPose +{ + PxTransform localPose; //!< The pose of the wheel in the rigid body frame. + + PX_FORCE_INLINE void setToDefault() + { + localPose = PxTransform(PxIdentity); + } +}; + +#if !PX_DOXYGEN +} // namespace vehicle2 +} // namespace physx +#endif + +/** @} */ diff --git a/Source/Tools/Flax.Build/Deps/Dependencies/PhysX.cs b/Source/Tools/Flax.Build/Deps/Dependencies/PhysX.cs index 7f23511b5..5f02dc086 100644 --- a/Source/Tools/Flax.Build/Deps/Dependencies/PhysX.cs +++ b/Source/Tools/Flax.Build/Deps/Dependencies/PhysX.cs @@ -28,7 +28,6 @@ namespace Flax.Deps.Dependencies return new[] { TargetPlatform.Windows, - TargetPlatform.UWP, TargetPlatform.XboxOne, TargetPlatform.PS4, TargetPlatform.PS5, @@ -81,6 +80,7 @@ namespace Flax.Deps.Dependencies // Configure preset var cmakeSwitches = presetXml["preset"]["CMakeSwitches"]; ConfigureCmakeSwitch(cmakeSwitches, "PX_BUILDSNIPPETS", "False"); + ConfigureCmakeSwitch(cmakeSwitches, "PX_BUILDPVDRUNTIME", "False"); ConfigureCmakeSwitch(cmakeSwitches, "PX_BUILDSAMPLES", "False"); ConfigureCmakeSwitch(cmakeSwitches, "PX_BUILDPUBLICSAMPLES", "False"); ConfigureCmakeSwitch(cmakeSwitches, "PX_GENERATE_STATIC_LIBRARIES", "True"); @@ -95,6 +95,10 @@ namespace Flax.Deps.Dependencies ConfigureCmakeSwitch(cmakeParams, "ANDROID_NATIVE_API_LEVEL", $"android-{Configuration.AndroidPlatformApi}"); ConfigureCmakeSwitch(cmakeParams, "ANDROID_ABI", AndroidToolchain.GetAbiName(architecture)); break; + case TargetPlatform.Mac: + ConfigureCmakeSwitch(cmakeParams, "CMAKE_OSX_DEPLOYMENT_TARGET", Configuration.MacOSXMinVer); + break; + // TODO: support CMAKE_XCODE_ATTRIBUTE_IPHONEOS_DEPLOYMENT_TARGET switch for iOS } // Save preset @@ -144,10 +148,7 @@ namespace Flax.Deps.Dependencies switch (targetPlatform) { case TargetPlatform.Windows: - binariesSubDir = string.Format("win.{0}_{1}.vc140.md", arch, bits); - break; - case TargetPlatform.UWP: - binariesSubDir = string.Format("uwp.{0}_{1}.vc141", arch, bits); + binariesSubDir = string.Format("win.{0}_{1}.vc143.md", arch, bits); break; case TargetPlatform.Linux: binariesSubDir = "linux.clang"; @@ -173,12 +174,11 @@ namespace Flax.Deps.Dependencies switch (architecture) { case TargetArchitecture.ARM64: - binariesSubDir = "android.arm64-v8a.fp-soft"; + binariesSubDir = "android.arm64-v8a"; break; default: throw new InvalidArchitectureException(architecture); } binariesPrefix = "lib"; - suppressBitsPostfix = true; break; case TargetPlatform.Switch: binariesSubDir = "switch64"; @@ -187,10 +187,20 @@ namespace Flax.Deps.Dependencies binariesPrefix = "lib"; break; case TargetPlatform.Mac: - binariesSubDir = "mac.x86_64"; + switch (architecture) + { + case TargetArchitecture.x64: + binariesSubDir = "mac.x86_64"; + break; + case TargetArchitecture.ARM64: + binariesSubDir = "mac.arm64"; + break; + default: throw new InvalidArchitectureException(architecture); + } binariesPrefix = "lib"; envVars.Add("MACOSX_DEPLOYMENT_TARGET", Configuration.MacOSXMinVer); break; + // TODO: set IPHONEOS_DEPLOYMENT_TARGET env var for iOS default: throw new InvalidPlatformException(targetPlatform); } @@ -210,12 +220,14 @@ namespace Flax.Deps.Dependencies envVars.Add("CC", "clang-7"); envVars.Add("CC_FOR_BUILD", "clang-7"); break; - case TargetPlatform.Mac: - break; + case TargetPlatform.Mac: break; default: throw new InvalidPlatformException(BuildPlatform); } if (AndroidNdk.Instance.IsValid) + { + envVars.Add("ANDROID_NDK_HOME", AndroidNdk.Instance.RootPath); envVars.Add("PM_ANDROIDNDK_PATH", AndroidNdk.Instance.RootPath); + } // Print the PhysX version Log.Info("Building PhysX version " + File.ReadAllText(Path.Combine(root, "physx", "version.txt")) + " to " + binariesSubDir); @@ -233,26 +245,7 @@ namespace Flax.Deps.Dependencies case TargetPlatform.XboxOne: case TargetPlatform.XboxScarlett: // Hack: force to use proper Win10 SDK - Utilities.ReplaceInFiles(Path.Combine(root, "physx\\compiler\\vc16win64"), "*.vcxproj", SearchOption.AllDirectories, "10.0.18362.0", "10.0.19041.0"); - - // Hack: fix STL include - Utilities.ReplaceInFile(Path.Combine(root, "physx\\source\\foundation\\include\\PsAllocator.h"), "#include ", "#include "); - break; - case TargetPlatform.Android: - // Hack: fix compilation errors - if (!File.ReadAllText(Path.Combine(root, "physx\\source\\foundation\\include\\PsUtilities.h")).Contains("#if PX_GCC_FAMILY && !PX_EMSCRIPTEN && !PX_LINUX && !PX_ANDROID")) - Utilities.ReplaceInFile(Path.Combine(root, "physx\\source\\foundation\\include\\PsUtilities.h"), "#if PX_GCC_FAMILY && !PX_EMSCRIPTEN && !PX_LINUX", "#if PX_GCC_FAMILY && !PX_EMSCRIPTEN && !PX_LINUX && !PX_ANDROID"); - Utilities.ReplaceInFile(Path.Combine(root, "physx\\source\\compiler\\cmake\\android\\CMakeLists.txt"), "-Wno-maybe-uninitialized", "-Wno-unused-local-typedef -Wno-unused-private-field"); - - // PhysX build system for Android is old and doesn't support new NDK with clang so invoke cmake manually - if (!Directory.Exists(Path.Combine(root, "physx\\compiler\\android"))) - Directory.CreateDirectory(Path.Combine(root, "physx\\compiler\\android")); - envVars.Add("PHYSX_ROOT_DIR", Path.Combine(root, "physx")); - envVars.Add("PM_CMAKEMODULES_PATH", Path.Combine(root, "externals/CMakeModules")); - envVars.Add("PM_PXSHARED_PATH", Path.Combine(root, "pxshared")); - envVars.Add("PM_TARGA_PATH", Path.Combine(root, "externals/targa")); - envVars.Add("PM_PATHS", Path.Combine(root, "externals/CMakeModules") + ';' + Path.Combine(root, "externals/targa")); - RunCmake(Path.Combine(root, "physx\\compiler\\android"), targetPlatform, architecture, string.Format("\"{0}/physx/compiler/public\" -Wno-dev -DANDROID_NATIVE_API_LEVEL=android-{1} -DTARGET_BUILD_PLATFORM=android --no-warn-unused-cli -DCMAKE_BUILD_TYPE={2} -DCMAKE_PREFIX_PATH=\"{0}/externals/CMakeModules;{0}/externals/targa\" -DPHYSX_ROOT_DIR=\"{0}/physx\" -DPX_OUTPUT_LIB_DIR=\"{0}/physx\" -DPX_OUTPUT_BIN_DIR=\"{0}/physx\" -DPX_BUILDSNIPPETS=FALSE -DPX_GENERATE_STATIC_LIBRARIES=TRUE -DCMAKE_INSTALL_PREFIX=\"{0}/physx/install/android-{1}/PhysX\"", root, Configuration.AndroidPlatformApi, configuration), envVars); + Utilities.ReplaceInFiles(Path.Combine(root, "physx\\compiler", preset), "*.vcxproj", SearchOption.AllDirectories, "10.0.18362.0", "10.0.19041.0"); break; } @@ -276,7 +269,7 @@ namespace Flax.Deps.Dependencies switch (targetPlatform) { case TargetPlatform.Android: - Utilities.Run("cmake", "--build .", null, Path.Combine(root, "physx\\compiler\\android"), Utilities.RunOptions.None, envVars); + Utilities.Run("cmake", "--build .", null, Path.Combine(root, "physx\\compiler\\android-release"), Utilities.RunOptions.None, envVars); break; default: VCEnvironment.BuildSolution(Path.Combine(solutionFilesRoot, preset, "PhysXSDK.sln"), configuration, buildPlatform); @@ -306,12 +299,18 @@ namespace Flax.Deps.Dependencies Utilities.FileCopy(Path.Combine(srcBinaries, filenamePdb), Path.Combine(dstBinaries, filenamePdb)); // Strip debug symbols to reduce binaries size - switch (targetPlatform) + switch (BuildPlatform) { case TargetPlatform.Linux: case TargetPlatform.Mac: - case TargetPlatform.Android: - Utilities.Run("strip", "\"" + filename + "\"", null, dstBinaries, Utilities.RunOptions.None); + switch (targetPlatform) + { + case TargetPlatform.Linux: + case TargetPlatform.Mac: + case TargetPlatform.Android: + Utilities.Run("strip", "\"" + filename + "\"", null, dstBinaries, Utilities.RunOptions.None); + break; + } break; } } @@ -354,7 +353,7 @@ namespace Flax.Deps.Dependencies } // Get the source - CloneGitRepoSingleBranch(root, "https://github.com/FlaxEngine/PhysX.git", "flax-master"); + CloneGitRepoSingleBranch(root, "https://github.com/FlaxEngine/PhysX-5.git", "flax-master"); foreach (var platform in options.Platforms) { @@ -362,12 +361,7 @@ namespace Flax.Deps.Dependencies { case TargetPlatform.Windows: { - Build(options, "vc14win64", platform, TargetArchitecture.x64); - break; - } - case TargetPlatform.UWP: - { - Build(options, "vc15uwp64", platform, TargetArchitecture.x64); + Build(options, "vc17win64", platform, TargetArchitecture.x64); break; } case TargetPlatform.Linux: @@ -388,10 +382,6 @@ namespace Flax.Deps.Dependencies break; } case TargetPlatform.XboxScarlett: - { - Build(options, "vc16win64", platform, TargetArchitecture.x64); - break; - } case TargetPlatform.XboxOne: { Build(options, "vc16win64", platform, TargetArchitecture.x64); @@ -411,6 +401,7 @@ namespace Flax.Deps.Dependencies case TargetPlatform.Mac: { Build(options, "mac64", platform, TargetArchitecture.x64); + Build(options, "mac-arm64", platform, TargetArchitecture.ARM64); break; } } @@ -419,15 +410,8 @@ namespace Flax.Deps.Dependencies // Copy header files var dstIncludePath = Path.Combine(options.ThirdPartyFolder, "PhysX"); Directory.GetFiles(dstIncludePath, "*.h", SearchOption.AllDirectories).ToList().ForEach(File.Delete); + Utilities.FileCopy(Path.Combine(root, "LICENSE.md"), Path.Combine(dstIncludePath, "License.txt")); Utilities.DirectoryCopy(Path.Combine(root, "physx", "include"), dstIncludePath); - Utilities.DirectoryCopy(Path.Combine(root, "pxshared", "include"), dstIncludePath); - foreach (var filename in new[] - { - "Ps.h", - "PsAllocator.h", - "PsSync.h", - }) - Utilities.FileCopy(Path.Combine(root, "physx", "source", "foundation", "include", filename), Path.Combine(dstIncludePath, "foundation", filename)); } } } diff --git a/Source/Tools/Flax.Build/Deps/Dependency.cs b/Source/Tools/Flax.Build/Deps/Dependency.cs index f475040ee..625430738 100644 --- a/Source/Tools/Flax.Build/Deps/Dependency.cs +++ b/Source/Tools/Flax.Build/Deps/Dependency.cs @@ -163,7 +163,7 @@ namespace Flax.Deps /// The custom arguments to add to the clone command. public static void CloneGitRepoSingleBranch(string path, string url, string branch, string commit = null, string args = null) { - if (!Directory.Exists(Path.Combine(path, Path.GetFileNameWithoutExtension(url), ".git"))) + if (!Directory.Exists(Path.Combine(path, ".git"))) { string cmdLine = string.Format("clone --single-branch --branch {2} \"{0}\" \"{1}\"", url, path, branch); if (commit == null) diff --git a/Source/Tools/Flax.Build/Deps/DepsBuilder.cs b/Source/Tools/Flax.Build/Deps/DepsBuilder.cs index 9c78dafe5..a225f9404 100644 --- a/Source/Tools/Flax.Build/Deps/DepsBuilder.cs +++ b/Source/Tools/Flax.Build/Deps/DepsBuilder.cs @@ -85,7 +85,7 @@ namespace Flax.Deps continue; } - var forceEmpty = Configuration.ReBuildDeps; + var forceEmpty = false; //Configuration.ReBuildDeps; Dependency.SetupDirectory(options.IntermediateFolder, forceEmpty); dependency.Build(options);