From 19542b61c4fee8e5aaa97f10455933488383d092 Mon Sep 17 00:00:00 2001 From: Ayoub Belarbi Date: Mon, 16 Sep 2024 19:52:18 +0000 Subject: [PATCH] Update PhysX to 5.4.2 at 9950ad0d --- physx/CHANGELOG.md | 21 ++++ .../steps/build_all_win_x86_64_vc16.bat | 30 ++++- .../steps/build_all_win_x86_64_vc17.bat | 29 ++++- physx/dependencies.xml | 6 +- physx/include/extensions/PxSerialization.h | 2 +- physx/include/foundation/PxPhysicsVersion.h | 2 +- .../include/DyFeatherstoneArticulation.h | 2 - .../shared/DyCpuGpuArticulation.h | 118 ++++++++++++++++++ .../lowleveldynamics/src/DyDynamics.cpp | 39 +----- .../src/DyFeatherstoneArticulation.cpp | 11 -- .../lowleveldynamics/src/DySolverControl.cpp | 4 - .../lowleveldynamics/src/DyTGSContactPrep.cpp | 12 +- .../src/DyTGSContactPrepBlock.cpp | 2 +- .../lowleveldynamics/src/DyTGSDynamics.cpp | 67 +++------- .../lowleveldynamics/src/DyTGSDynamics.h | 2 +- physx/source/physx/src/NpRigidDynamic.cpp | 20 +++ .../source/physx/src/NpSceneFetchResults.cpp | 80 ++++-------- physx/version.txt | 2 +- 18 files changed, 263 insertions(+), 186 deletions(-) diff --git a/physx/CHANGELOG.md b/physx/CHANGELOG.md index 2b11f0637..b2c295462 100644 --- a/physx/CHANGELOG.md +++ b/physx/CHANGELOG.md @@ -1,3 +1,24 @@ +# v5.4.2-106.1 + +## Articulations + +### Fixed + +* A bug in the GPU pipeline where setting the maximum joint velocity to zero resulted in a crash. + +### Changed + +* In the CPU codepath, constraints involving the root link of a fixed-base articulation are now resolved simultaneously with constraints that couple pairs of dynamic rigid bodies and/or articulation links. As a consequence of this change, the CPU and GPU codepaths now resolve constraints and contacts involving the root link of an articulation in the same order. This historic inconsistency, which has now been resolved, may have caused a difference in behavior between CPU and GPU simulation. + +## Rigid Body + +### Fixed + +* In cases where TGS was used with a non-zero number of velocity iterations on CPU, an incorrect timestep was used in part of the rigid-body and articulation solver pipeline. +* A bug in collision resolution where a sphere could fall through a flat triangle mesh when it landed precisely on a mesh vertex. +* Acceleration computation for rigid bodies was incorrect for both CPU and GPU APIs if velocities were updated by the user in-between simulation steps. This is fixed now. Affected API: PxRigidBody::getLinearAcceleration(), PxRigidBody::getAngularAcceleration(), PxDirectGPUAPI::getRigidDynamicData(). +* The CPU-side computations of accelerations (controlled with eENABLE_BODY_ACCELERATIONS) have been disabled when eENABLE_DIRECT_GPU_API is enabled. Previously both the CPU and GPU computations happened, which was redundant. + # v5.4.1-106.0 ## General diff --git a/physx/buildtools/steps/build_all_win_x86_64_vc16.bat b/physx/buildtools/steps/build_all_win_x86_64_vc16.bat index 3e59c7503..8cd189038 100644 --- a/physx/buildtools/steps/build_all_win_x86_64_vc16.bat +++ b/physx/buildtools/steps/build_all_win_x86_64_vc16.bat @@ -1,11 +1,31 @@ -:: Setup VS2019 build environment -IF EXIST "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer" SET PATH=%PATH%;%ProgramFiles(x86)%\Microsoft Visual Studio\Installer +@echo off +SETLOCAL EnableDelayedExpansion -for /f "usebackq tokens=*" %%i in (`vswhere -version "[16.0,17.0)" -latest -property installationPath`) do ( - SET "COMNTOOLS=%%i\Common7\Tools\" +:: Locate Visual Studio using vswhere +IF EXIST "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer" ( + SET "VS_INSTALLER_DIR=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer" + echo VS_INSTALLER_DIR: "!VS_INSTALLER_DIR!" + + :: Check if VS_INSTALLER_DIR is already in PATH + echo !PATH! | findstr /i /c:"!VS_INSTALLER_DIR!" >nul + if !errorlevel! neq 0 ( + SET PATH=!PATH!;!VS_INSTALLER_DIR! + echo Updated PATH: !PATH! + ) else ( + echo VS_INSTALLER_DIR is already in PATH + ) ) -@call "%COMNTOOLS%..\..\VC\Auxiliary\Build\vcvarsx86_amd64.bat" +:: Use vswhere to locate the latest Visual Studio installation +for /f "usebackq tokens=*" %%i in (`vswhere -version "[16.0,17.0)" -latest -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`) do ( + SET "VSINSTALLPATH=%%i" + echo VSINSTALLPATH: "!VSINSTALLPATH!" +) + +:: Set COMNTOOLS to point to the correct path +SET "COMNTOOLS=!VSINSTALLPATH!\VC\Auxiliary\Build\vcvarsx86_amd64.bat" +echo COMNTOOLS: "!COMNTOOLS!" +@call "!COMNTOOLS!" :: When run with no arguments we always perform a rebuild (clean & build) @if [%1] == [] ( diff --git a/physx/buildtools/steps/build_all_win_x86_64_vc17.bat b/physx/buildtools/steps/build_all_win_x86_64_vc17.bat index 5da277062..99751bde1 100644 --- a/physx/buildtools/steps/build_all_win_x86_64_vc17.bat +++ b/physx/buildtools/steps/build_all_win_x86_64_vc17.bat @@ -1,12 +1,31 @@ -:: Setup VS2022 build environment +@echo off +SETLOCAL EnableDelayedExpansion -IF EXIST "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer" SET PATH=%PATH%;%ProgramFiles(x86)%\Microsoft Visual Studio\Installer +:: Locate Visual Studio using vswhere +IF EXIST "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer" ( + SET "VS_INSTALLER_DIR=%ProgramFiles(x86)%\Microsoft Visual Studio\Installer" + echo VS_INSTALLER_DIR: "!VS_INSTALLER_DIR!" + + :: Check if VS_INSTALLER_DIR is already in PATH + echo !PATH! | findstr /i /c:"!VS_INSTALLER_DIR!" >nul + if !errorlevel! neq 0 ( + SET PATH=!PATH!;!VS_INSTALLER_DIR! + echo Updated PATH: !PATH! + ) else ( + echo VS_INSTALLER_DIR is already in PATH + ) +) -for /f "usebackq tokens=*" %%i in (`vswhere -version "[17.0,18.0)" -latest -property installationPath`) do ( - SET "COMNTOOLS=%%i\Common7\Tools\" +:: Use vswhere to locate the latest Visual Studio installation +for /f "usebackq tokens=*" %%i in (`vswhere -version "[17.0,18.0)" -latest -requires Microsoft.VisualStudio.Component.VC.Tools.x86.x64 -property installationPath`) do ( + SET "VSINSTALLPATH=%%i" + echo VSINSTALLPATH: "!VSINSTALLPATH!" ) -@call "%COMNTOOLS%..\..\VC\Auxiliary\Build\vcvarsx86_amd64.bat" +:: Set COMNTOOLS to point to the correct path +SET "COMNTOOLS=!VSINSTALLPATH!\VC\Auxiliary\Build\vcvarsx86_amd64.bat" +echo COMNTOOLS: "!COMNTOOLS!" +@call "!COMNTOOLS!" :: When run with no arguments we always perform a rebuild (clean & build) @if [%1] == [] ( diff --git a/physx/dependencies.xml b/physx/dependencies.xml index 44c74d2dc..e05b7696e 100644 --- a/physx/dependencies.xml +++ b/physx/dependencies.xml @@ -16,9 +16,9 @@ - - - + + + diff --git a/physx/include/extensions/PxSerialization.h b/physx/include/extensions/PxSerialization.h index 9f18daa19..f1931a10a 100644 --- a/physx/include/extensions/PxSerialization.h +++ b/physx/include/extensions/PxSerialization.h @@ -41,7 +41,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 "B57177A5EF424885A73E41854E472FC4" +#define PX_BINARY_SERIAL_VERSION "3B794FCE39C34CE58F6065FA172B0A36" #if !PX_DOXYGEN diff --git a/physx/include/foundation/PxPhysicsVersion.h b/physx/include/foundation/PxPhysicsVersion.h index 7f2e3f766..22b9447bf 100644 --- a/physx/include/foundation/PxPhysicsVersion.h +++ b/physx/include/foundation/PxPhysicsVersion.h @@ -47,7 +47,7 @@ sometimes they are stored in a byte. #define PX_PHYSICS_VERSION_MAJOR 5 #define PX_PHYSICS_VERSION_MINOR 4 -#define PX_PHYSICS_VERSION_BUGFIX 1 +#define PX_PHYSICS_VERSION_BUGFIX 2 /** The constant PX_PHYSICS_VERSION is used when creating certain PhysX module objects. diff --git a/physx/source/lowleveldynamics/include/DyFeatherstoneArticulation.h b/physx/source/lowleveldynamics/include/DyFeatherstoneArticulation.h index d39ba7347..1e83746b8 100644 --- a/physx/source/lowleveldynamics/include/DyFeatherstoneArticulation.h +++ b/physx/source/lowleveldynamics/include/DyFeatherstoneArticulation.h @@ -713,8 +713,6 @@ namespace Dy Cm::SpatialVector getMotionAcceleration(const PxU32 linkID, const bool isGpuSimEnabled) const; - void fillIndexType(const PxU32 linkId, PxU8& indexType); - PxReal getLinkMaxPenBias(const PxU32 linkID) const; PxReal getCfm(const PxU32 linkID) const; diff --git a/physx/source/lowleveldynamics/shared/DyCpuGpuArticulation.h b/physx/source/lowleveldynamics/shared/DyCpuGpuArticulation.h index 3db2500c6..95136b190 100644 --- a/physx/source/lowleveldynamics/shared/DyCpuGpuArticulation.h +++ b/physx/source/lowleveldynamics/shared/DyCpuGpuArticulation.h @@ -178,6 +178,124 @@ PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal computeDriveImpulse return unclampedForce; } +/** +\brief Apply limit constraints to an articulation joint dof. +1) Compute the delta impulse required to maintain limit constraints. +2) Individually accumulate the impulses that have been applied to maintain both the lower and upper limit. +3) Compute the updated joint speed after applying the delta impulse. +\param[in] dt is the timestep of the simulation +\param[in] recipDt has value 1/dt +\param[in] isVelIter is true if we are performing a velocity iteration, false if performing a position iteration. +\param[in] response is the deltaSpeed response of the joint dof to a unit impulse. +\param[in] recipResponse has value 1/response. +\param[in] erp is the Baumgarte multiplier used to resolve a fraction of the limit error. +\param[in] errorLow is the lower bound of the limit. +\param[in] errorHigh is the upper bound of the limit. +\param[in] jointPDelta is the change to the joint position that has accumulated over solver iterations. +\param[in,out] lowImpulse_ is the accumulated impulse that has been applied to maintain the limit's lower bound. +\param[in,out] highImpulse_ is the accumulated impulse that has applied to maintain the limit's upper bound. +\param[in,out] jointV_ is the joint speed before and after applying the limit impulses. +\return deltaImpulse required to enforce the upper and lower limits. +*/ +PX_CUDA_CALLABLE PX_FORCE_INLINE PxReal computeLimitImpulse +(const PxReal dt, const PxReal recipDt, const bool isVelIter, + const PxReal response, const PxReal recipResponse, const PxReal erp, + const PxReal errorLow, const PxReal errorHigh, + const PxReal jointPDelta, + PxReal& lowImpulse_, PxReal& highImpulse_, PxReal& jointV_) +{ + // PT: avoid aliasing + PxReal jointV = jointV_; + PxReal lowImpulse = lowImpulse_; + PxReal highImpulse = highImpulse_; + + const PxReal futureDeltaJointP = jointPDelta + jointV * dt; + + // for all errors: Negative means violated + const PxReal currErrLow = errorLow + jointPDelta; + const PxReal nextErrLow = errorLow + futureDeltaJointP; + const PxReal currErrHigh = errorHigh - jointPDelta; + const PxReal nextErrHigh = errorHigh - futureDeltaJointP; + + bool limited = false; + + const PxReal tolerance = 0.f; + + PxReal deltaF = 0.f; + if (currErrLow < tolerance || nextErrLow < tolerance) + { + PxReal newJointV = jointV; + limited = true; + if (currErrLow < tolerance) + { + if (!isVelIter) + newJointV = -currErrLow * recipDt * erp; + } + else + { + // Currently we're not in violation of the limit but would be after this time step given the current velocity. + // To prevent that future violation, we want the current velocity to only take us right to the limit, not across it + newJointV = -currErrLow * recipDt; + } + + // In position iterations, the newJointV is now such that we end up exactly on the limit after this time step (ignoring erp) + // However, we ignored the current velocity, which may already take us further away from the limit than the newJointV. + // Therefore, we additionally have to check now that the impulse we're applying is only repulsive overall. + + const PxReal deltaV = newJointV - jointV; + deltaF = PxMax(lowImpulse + deltaV * recipResponse, 0.f) - lowImpulse; // accumulated limit impulse must be repulsive + lowImpulse += deltaF; + } + else if (currErrHigh < tolerance || nextErrHigh < tolerance) + { + PxReal newJointV = jointV; + limited = true; + if (currErrHigh < tolerance) + { + if (!isVelIter) + newJointV = currErrHigh * recipDt * erp; + } + else + newJointV = currErrHigh * recipDt; + + const PxReal deltaV = newJointV - jointV; + deltaF = PxMin(highImpulse + deltaV * recipResponse, 0.f) - highImpulse; + highImpulse += deltaF; + } + + if (!limited) + { + // If no limit is violated right now, it could still be that a limit was active in an earlier iteration and + // overshot. Therefore, we give that limit from which the joint position is currently moving away a chance to + // pull back and correct the overshoot. + // The pull-back impulse is the smaller of + // a) The impulse needed to bring the joint velocity to zero. + // b) The opposite impulse of the already applied joint limit impulse, thereby cancelling out the accumulated effect of the limit. + + const PxReal impulseForZeroVel = -jointV * recipResponse; + if (jointV > 0.f) // moving away from the lower limit + { + deltaF = PxMax(impulseForZeroVel, -lowImpulse); + lowImpulse += deltaF; + + } + else // moving away from the higher limit + { + deltaF = PxMin(impulseForZeroVel, -highImpulse); + highImpulse += deltaF; + } + } + + jointV += deltaF * response; + + lowImpulse_ = lowImpulse; + highImpulse_ = highImpulse; + jointV_ = jointV; + + return deltaF; +} + + /** \brief Translate a spatial vector from the frame of one link (the source link) to the frame of another link (the target link). \param[in] offset is the vector from the source link to the target link (== posTargetLink - posSourceLlink) diff --git a/physx/source/lowleveldynamics/src/DyDynamics.cpp b/physx/source/lowleveldynamics/src/DyDynamics.cpp index 822ef69d3..904227b91 100644 --- a/physx/source/lowleveldynamics/src/DyDynamics.cpp +++ b/physx/source/lowleveldynamics/src/DyDynamics.cpp @@ -269,21 +269,8 @@ void DynamicsContext::setDescFromIndices(PxSolverConstraintDesc& desc, IG::EdgeI { Dy::FeatherstoneArticulation* a = islandSim.getLLArticulation(node1); - PxU8 type; - - a->fillIndexType(node1.articulationLinkId(), type); - - if (type == PxsIndexedInteraction::eARTICULATION) - { - desc.articulationA = a; - desc.linkIndexA = node1.articulationLinkId(); - } - else - { - desc.bodyA = &mWorldSolverBody; - desc.bodyADataIndex = 0; - desc.linkIndexA = PxSolverConstraintDesc::RIGID_BODY; - } + desc.articulationA = a; + desc.linkIndexA = node1.articulationLinkId(); } else { @@ -308,21 +295,9 @@ void DynamicsContext::setDescFromIndices(PxSolverConstraintDesc& desc, IG::EdgeI if (node.getNodeType() == IG::Node::eARTICULATION_TYPE) { Dy::FeatherstoneArticulation* b = islandSim.getLLArticulation(node2); - PxU8 type; - b->fillIndexType(node2.articulationLinkId(), type); - - if (type == PxsIndexedInteraction::eARTICULATION) - { - desc.articulationB = b; - desc.linkIndexB = node2.articulationLinkId(); - } - else - { - desc.bodyB = &mWorldSolverBody; - desc.bodyBDataIndex = 0; - desc.linkIndexB = PxSolverConstraintDesc::RIGID_BODY; - } + desc.articulationB = b; + desc.linkIndexB = node2.articulationLinkId(); } else { @@ -941,8 +916,7 @@ class PxsSolverStartTask : public Cm::Task if(node1.getNodeType() == IG::Node::eARTICULATION_TYPE) { indexedManager.articulation0 = nodeIndex1.getInd(); - const PxU32 linkId = nodeIndex1.articulationLinkId(); - node1.getArticulation()->fillIndexType(linkId, indexedManager.indexType0); + indexedManager.indexType0 = PxsIndexedInteraction::eARTICULATION; } else { @@ -972,8 +946,7 @@ class PxsSolverStartTask : public Cm::Task if(node2.getNodeType() == IG::Node::eARTICULATION_TYPE) { indexedManager.articulation1 = nodeIndex2.getInd(); - const PxU32 linkId = nodeIndex2.articulationLinkId(); - node2.getArticulation()->fillIndexType(linkId, indexedManager.indexType1); + indexedManager.indexType1 = PxsIndexedInteraction::eARTICULATION; } else { diff --git a/physx/source/lowleveldynamics/src/DyFeatherstoneArticulation.cpp b/physx/source/lowleveldynamics/src/DyFeatherstoneArticulation.cpp index 0fb3bb381..7fbe2a7ab 100644 --- a/physx/source/lowleveldynamics/src/DyFeatherstoneArticulation.cpp +++ b/physx/source/lowleveldynamics/src/DyFeatherstoneArticulation.cpp @@ -936,17 +936,6 @@ namespace Dy return a; } - void FeatherstoneArticulation::fillIndexType(const PxU32 linkId, PxU8& indexType) - { - ArticulationLink& link = mArticulationData.getLink(linkId); - - //turn the fixed-base links to static for the solver - if(link.bodyCore->fixedBaseLink) - indexType = PxsIndexedInteraction::eWORLD; - else - indexType = PxsIndexedInteraction::eARTICULATION; - } - PxReal FeatherstoneArticulation::getLinkMaxPenBias(const PxU32 linkID) const { return mArticulationData.getLinkData(linkID).maxPenBias; diff --git a/physx/source/lowleveldynamics/src/DySolverControl.cpp b/physx/source/lowleveldynamics/src/DySolverControl.cpp index fd86c8af6..fc1b21acf 100644 --- a/physx/source/lowleveldynamics/src/DySolverControl.cpp +++ b/physx/source/lowleveldynamics/src/DySolverControl.cpp @@ -291,7 +291,6 @@ void SolverCoreGeneral::solveVParallelAndWriteBack(SolverIslandParams& params, C const PxReal invDt = params.invDt; const PxI32 positionIterations = PxI32(params.positionIterations); - const PxI32 velocityIterations = PxI32(params.velocityIterations); PxI32* constraintIndex = ¶ms.constraintIndex; // counter for distributing constraints to tasks, incremented before they're solved PxI32* constraintIndexCompleted = ¶ms.constraintIndexCompleted; // counter for completed constraints, incremented after they're solved @@ -307,9 +306,6 @@ void SolverCoreGeneral::solveVParallelAndWriteBack(SolverIslandParams& params, C const PxU32* headersPerPartition = params.headersPerPartition; - PX_UNUSED(velocityIterations); - - PX_ASSERT(velocityIterations >= 1); PX_ASSERT(positionIterations >= 1); PxI32 endIndexCount = UnrollCount; diff --git a/physx/source/lowleveldynamics/src/DyTGSContactPrep.cpp b/physx/source/lowleveldynamics/src/DyTGSContactPrep.cpp index 91b162182..6adc50162 100644 --- a/physx/source/lowleveldynamics/src/DyTGSContactPrep.cpp +++ b/physx/source/lowleveldynamics/src/DyTGSContactPrep.cpp @@ -370,9 +370,7 @@ namespace Dy const FloatV unitResponse = FAdd(resp0, resp1); const FloatV penetration = FSub(separation, restDistance); - const BoolV isSeparated = FIsGrtr(penetration, zero); - const FloatV penetrationInvDt = FMul(penetration, invTotalDt); const BoolV isGreater2 = BAnd(BAnd(FIsGrtr(restitution, zero), FIsGrtr(bounceThreshold, vrel)), FIsGrtr(FNeg(vrel), penetrationInvDt)); @@ -388,8 +386,7 @@ namespace Dy if (FAllGrtr(zero, restitution)) { - // Note: using totalDt here instead of penetrationInvDt because the latter has a fudge factor if there are velocity iterations - const BoolV collidingWithVrel = FIsGrtr(FMul(FNeg(vrel), totalDt), penetration); // true if pen + totalDt*vrel < 0 + const BoolV collidingWithVrel = FIsGrtr(FNeg(vrel), penetrationInvDt); // true if pen + totalDt*vrel < 0 computeCompliantContactCoefficientsTGS(dt, restitution, damping, recipResponse, unitResponse, accelerationSpring, isSeparated, collidingWithVrel, velMultiplier, biasCoeff); } @@ -867,10 +864,11 @@ namespace Dy const FloatV recipResponse = FSel(FIsGrtr(unitResponse, FZero()), FRecip(FAdd(unitResponse, cfm)), zero); + const FloatV penetrationInvDt = FMul(penetration, invDt); + if (FAllGrtr(zero, restitution)) { - // Note: using totalDt here instead of penetrationInvDt because the latter has a fudge factor if there are velocity iterations - const BoolV collidingWithVrel = FIsGrtr(FMul(FNeg(vrel), totalDt), penetration); // true if pen + totalDt*vrel < 0 + const BoolV collidingWithVrel = FIsGrtr(FNeg(vrel), penetrationInvDt); // true if pen + totalDt*vrel < 0 computeCompliantContactCoefficientsTGS(dt, restitution, damping, recipResponse, unitResponse, accelerationSpring, isSeparated, collidingWithVrel, velMultiplier, scaledBias); @@ -880,8 +878,6 @@ namespace Dy velMultiplier = recipResponse; scaledBias = FNeg(FSel(isSeparated, invStepDt, invDtp8)); } - - const FloatV penetrationInvDt = FMul(penetration, invDt); const BoolV isGreater2 = BAnd(BAnd(FIsGrtr(restitution, zero), FIsGrtr(bounceThreshold, vrel)), FIsGrtr(FNeg(vrel), penetrationInvDt)); diff --git a/physx/source/lowleveldynamics/src/DyTGSContactPrepBlock.cpp b/physx/source/lowleveldynamics/src/DyTGSContactPrepBlock.cpp index 1415843a9..f76153902 100644 --- a/physx/source/lowleveldynamics/src/DyTGSContactPrepBlock.cpp +++ b/physx/source/lowleveldynamics/src/DyTGSContactPrepBlock.cpp @@ -731,7 +731,7 @@ static void setupFinalizeSolverConstraints4Step(PxTGSSolverContactDesc* PX_RESTR // rdt, a, b, x only needed in compliant case const BoolV isCompliant = V4IsGrtr(restitution, zero); const Vec4V rdt = V4Scale(restitution, dt); - const BoolV collidingWithVrel = V4IsGrtr(V4Mul(V4Neg(vrel), totalDt), penetration); // Note: using totalDt here instead of penetrationInvDt because the latter has a fudge factor if there are velocity iterations + const BoolV collidingWithVrel = V4IsGrtr(V4Neg(vrel), penetrationInvDt); const Vec4V dampingIfEnabled = V4Sel(BAndNot(isSeparated, collidingWithVrel), zero, damping); const Vec4V a = V4Scale(V4Add(dampingIfEnabled, rdt), dt); const Vec4V massIfAccelElseOne = V4Sel(accelSpring, recipResponse, one); diff --git a/physx/source/lowleveldynamics/src/DyTGSDynamics.cpp b/physx/source/lowleveldynamics/src/DyTGSDynamics.cpp index aea413a08..465ce978b 100644 --- a/physx/source/lowleveldynamics/src/DyTGSDynamics.cpp +++ b/physx/source/lowleveldynamics/src/DyTGSDynamics.cpp @@ -412,21 +412,9 @@ void DynamicsTGSContext::setDescFromIndices(PxSolverConstraintDesc& desc, IG::Ed PX_ASSERT(node1.isArticulation()); Dy::FeatherstoneArticulation* a = islandSim.getLLArticulation(node1); - PxU8 type; - a->fillIndexType(node1.articulationLinkId(),type); - - if (type == PxsIndexedInteraction::eARTICULATION) - { - desc.articulationA = a; - desc.linkIndexA = node1.articulationLinkId(); - } - else - { - desc.tgsBodyA = &mWorldSolverBodyVel; - desc.linkIndexA = PxSolverConstraintDesc::RIGID_BODY; - } - + desc.articulationA = a; + desc.linkIndexA = node1.articulationLinkId(); desc.bodyADataIndex = 0; } else @@ -455,21 +443,8 @@ void DynamicsTGSContext::setDescFromIndices(PxSolverConstraintDesc& desc, IG::Ed PX_ASSERT(node2.isArticulation()); Dy::FeatherstoneArticulation* b = islandSim.getLLArticulation(node2); - PxU8 type; - - b->fillIndexType(node2.articulationLinkId(), type); - - if (type == PxsIndexedInteraction::eARTICULATION) - { - desc.articulationB = b; - desc.linkIndexB = node2.articulationLinkId(); - } - else - { - desc.tgsBodyB = &mWorldSolverBodyVel; - desc.linkIndexB = PxSolverConstraintDesc::RIGID_BODY; - } - + desc.articulationB = b; + desc.linkIndexB = node2.articulationLinkId(); desc.bodyBDataIndex = 0; } else @@ -945,8 +920,7 @@ void DynamicsTGSContext::prepareBodiesAndConstraints(const SolverIslandObjectsSt if (node1.getNodeType() == IG::Node::eARTICULATION_TYPE) { indexedManager.articulation0 = nodeIndex1.getInd(); - const PxU32 linkId = nodeIndex1.articulationLinkId(); - node1.getArticulation()->fillIndexType(linkId, indexedManager.indexType0); + indexedManager.indexType0 = PxsIndexedInteraction::eARTICULATION; } else { @@ -976,8 +950,7 @@ void DynamicsTGSContext::prepareBodiesAndConstraints(const SolverIslandObjectsSt if (node2.getNodeType() == IG::Node::eARTICULATION_TYPE) { indexedManager.articulation1 = nodeIndex2.getInd(); - const PxU32 linkId = nodeIndex2.articulationLinkId(); - node2.getArticulation()->fillIndexType(linkId, indexedManager.indexType1); + indexedManager.indexType1 = PxsIndexedInteraction::eARTICULATION; } else { @@ -1105,7 +1078,7 @@ void DynamicsTGSContext::preIntegrateBodies(PxsBodyCore** bodyArray, PxsRigidBod void DynamicsTGSContext::createSolverConstraints(PxSolverConstraintDesc* contactDescPtr, PxConstraintBatchHeader* headers, PxU32 nbHeaders, PxsContactManagerOutputIterator& outputs, Dy::ThreadContext& islandThreadContext, Dy::ThreadContext& threadContext, PxReal stepDt, PxReal totalDt, PxReal invStepDt, - const PxReal biasCoefficient, PxI32 velIters) + const PxReal biasCoefficient) { PX_UNUSED(totalDt); //PX_PROFILE_ZONE("CreateConstraints", 0); @@ -1116,11 +1089,7 @@ void DynamicsTGSContext::createSolverConstraints(PxSolverConstraintDesc* contact PxTGSSolverBodyTxInertia* txInertias = mSolverBodyTxInertiaPool.begin(); PxTGSSolverBodyData* solverBodyDatas = mSolverBodyDataPool2.begin(); - const PxReal invTotalDt = 1.f / totalDt; - PxReal denom = (totalDt); - if (velIters) - denom += stepDt; - const PxReal invTotalDtPlusStep = 1.f / denom; + const PxReal invTotalDt = 1.0f / totalDt; for (PxU32 h = 0; h < nbHeaders; ++h) { @@ -1223,7 +1192,7 @@ void DynamicsTGSContext::createSolverConstraints(PxSolverConstraintDesc* contact blockDescs, invStepDt, totalDt, - invTotalDtPlusStep, + invTotalDt, stepDt, mBounceThreshold, mFrictionOffsetThreshold, @@ -1245,7 +1214,7 @@ void DynamicsTGSContext::createSolverConstraints(PxSolverConstraintDesc* contact //PX_ASSERT(output.nbContacts != 0); createFinalizeSolverContactsStep(blockDescs[i], output, threadContext, - invStepDt, invTotalDtPlusStep, totalDt, stepDt, mBounceThreshold, mFrictionOffsetThreshold, mCorrelationDistance, biasCoefficient, + invStepDt, invTotalDt, totalDt, stepDt, mBounceThreshold, mFrictionOffsetThreshold, mCorrelationDistance, biasCoefficient, blockAllocator); getContactManagerConstraintDesc(output, *cm, desc); @@ -2089,7 +2058,6 @@ class SetupSolverConstraintsSubTask : public Cm::Task PxReal mBiasCoefficient; DynamicsTGSContext& mContext; ThreadContext& mIslandThreadContext; - PxI32 mVelIters; PX_NOCOPY(SetupSolverConstraintsSubTask) @@ -2099,10 +2067,9 @@ class SetupSolverConstraintsSubTask : public Cm::Task SetupSolverConstraintsSubTask(PxSolverConstraintDesc* contactDescPtr, PxConstraintBatchHeader* headers, PxU32 nbHeaders, PxsContactManagerOutputIterator& outputs, PxReal stepDt, PxReal totalDt, PxReal invStepDt, PxReal invDtTotal, - PxReal biasCoefficient, ThreadContext& islandThreadContext, DynamicsTGSContext& context, PxI32 velIters) : Cm::Task(context.getContextId()), + PxReal biasCoefficient, ThreadContext& islandThreadContext, DynamicsTGSContext& context) : Cm::Task(context.getContextId()), mContactDescPtr(contactDescPtr), mHeaders(headers), mNbHeaders(nbHeaders), mOutputs(outputs), mStepDt(stepDt), mTotalDt(totalDt), mInvStepDt(invStepDt), - mInvDtTotal(invDtTotal), mBiasCoefficient(biasCoefficient), mContext(context), mIslandThreadContext(islandThreadContext), - mVelIters(velIters) + mInvDtTotal(invDtTotal), mBiasCoefficient(biasCoefficient), mContext(context), mIslandThreadContext(islandThreadContext) { } @@ -2113,7 +2080,7 @@ class SetupSolverConstraintsSubTask : public Cm::Task ThreadContext* tempContext = mContext.getThreadContext(); tempContext->mConstraintBlockStream.reset(); mContext.createSolverConstraints(mContactDescPtr, mHeaders, mNbHeaders, mOutputs, mIslandThreadContext, *tempContext, mStepDt, mTotalDt, mInvStepDt, - mBiasCoefficient, mVelIters); + mBiasCoefficient); mContext.putThreadContext(tempContext); } }; @@ -2148,10 +2115,7 @@ class PxsCreateArticConstraintsSubTask : public Cm::Task const PxReal dt = mDynamicsContext.getDt(); const PxReal invStepDt = PxMin(mDynamicsContext.getMaxBiasCoefficient(), mIslandContext.mInvStepDt); - PxReal denom = dt; - if (mIslandContext.mVelIters) - denom += mIslandContext.mStepDt; - PxReal invDt = 1.f / denom; + const PxReal invDt = 1.0f / dt; ThreadContext* threadContext = mDynamicsContext.getThreadContext(); threadContext->mConstraintBlockStream.reset(); //ensure there's no left-over memory that belonged to another island @@ -2220,8 +2184,7 @@ class SetupSolverConstraintsTask : public Cm::Task { const PxU32 nbConstraints = PxMin(nbBatches - a, SetupSolverConstraintsSubTask::MaxPerTask); SetupSolverConstraintsSubTask* task = PX_PLACEMENT_NEW(mContext.mTaskPool.allocate(sizeof(SetupSolverConstraintsSubTask)), SetupSolverConstraintsSubTask) - (mContactDescPtr, hdr + a, nbConstraints, mOutputs, mIslandContext.mStepDt, mTotalDt, mIslandContext.mInvStepDt, mContext.mInvDt, mIslandContext.mBiasCoefficient, mThreadContext, mContext, - mIslandContext.mVelIters); + (mContactDescPtr, hdr + a, nbConstraints, mOutputs, mIslandContext.mStepDt, mTotalDt, mIslandContext.mInvStepDt, mContext.mInvDt, mIslandContext.mBiasCoefficient, mThreadContext, mContext); task->setContinuation(mCont); task->removeReference(); diff --git a/physx/source/lowleveldynamics/src/DyTGSDynamics.h b/physx/source/lowleveldynamics/src/DyTGSDynamics.h index c14087fa4..b5f0a1320 100644 --- a/physx/source/lowleveldynamics/src/DyTGSDynamics.h +++ b/physx/source/lowleveldynamics/src/DyTGSDynamics.h @@ -257,7 +257,7 @@ class DynamicsTGSContext : public Context void createSolverConstraints(PxSolverConstraintDesc* contactDescPtr, PxConstraintBatchHeader* headers, PxU32 nbHeaders, PxsContactManagerOutputIterator& outputs, Dy::ThreadContext& islandThreadContext, Dy::ThreadContext& threadContext, PxReal stepDt, PxReal totalDt, - PxReal invStepDt, PxReal biasCoefficient, PxI32 velIters); + PxReal invStepDt, PxReal biasCoefficient); void solveConstraintsIteration(const PxSolverConstraintDesc* const contactDescPtr, const PxConstraintBatchHeader* const batchHeaders, PxU32 nbHeaders, PxReal invStepDt, const PxTGSSolverBodyTxInertia* const solverTxInertia, PxReal elapsedTime, PxReal minPenetration, SolverContext& cache); diff --git a/physx/source/physx/src/NpRigidDynamic.cpp b/physx/source/physx/src/NpRigidDynamic.cpp index 2d6a4cc1b..2b7c23239 100644 --- a/physx/source/physx/src/NpRigidDynamic.cpp +++ b/physx/source/physx/src/NpRigidDynamic.cpp @@ -242,6 +242,16 @@ void NpRigidDynamic::setLinearVelocity(const PxVec3& velocity, bool autowake) scSetLinearVelocity(velocity); + if(npScene && npScene->getFlagsFast() & PxSceneFlag::eENABLE_BODY_ACCELERATIONS) + { + const PxU32 index = getRigidActorArrayIndex(); + + if(index>=npScene->mRigidDynamicsAccelerations.size()) + npScene->mRigidDynamicsAccelerations.resize(index+1); + + npScene->mRigidDynamicsAccelerations[index].mPrevLinVel = velocity; + } + OMNI_PVD_SET(OMNI_PVD_CONTEXT_HANDLE, PxRigidBody, linearVelocity, *static_cast(this), velocity); if(npScene) @@ -260,6 +270,16 @@ void NpRigidDynamic::setAngularVelocity(const PxVec3& velocity, bool autowake) scSetAngularVelocity(velocity); + if(npScene && npScene->getFlagsFast() & PxSceneFlag::eENABLE_BODY_ACCELERATIONS) + { + const PxU32 index = getRigidActorArrayIndex(); + + if(index>=npScene->mRigidDynamicsAccelerations.size()) + npScene->mRigidDynamicsAccelerations.resize(index+1); + + npScene->mRigidDynamicsAccelerations[index].mPrevAngVel = velocity; + } + OMNI_PVD_SET(OMNI_PVD_CONTEXT_HANDLE, PxRigidBody, angularVelocity, *static_cast(this), velocity); if (npScene && (npScene->getFlags() & PxSceneFlag::eENABLE_DIRECT_GPU_API) && npScene->isDirectGPUAPIInitialized()) diff --git a/physx/source/physx/src/NpSceneFetchResults.cpp b/physx/source/physx/src/NpSceneFetchResults.cpp index e21b758ef..abb132408 100644 --- a/physx/source/physx/src/NpSceneFetchResults.cpp +++ b/physx/source/physx/src/NpSceneFetchResults.cpp @@ -141,7 +141,7 @@ void NpScene::fetchResultsPostContactCallbacks() { // PT: I put this here for now, as initially we even considered making this a PxExtensions helper. To make it more // efficient / multithread it we could eventually move this deeper in the Sc-level pipeline. - if(mScene.getFlags() & PxSceneFlag::eENABLE_BODY_ACCELERATIONS) + if((mScene.getFlags() & PxSceneFlag::eENABLE_BODY_ACCELERATIONS) && !(mScene.getFlags() & PxSceneFlag::eENABLE_DIRECT_GPU_API)) { // PT: we store the acceleration data in a separate/dedicated array, so that memory usage doesn't increase for // people who don't use the flag (i.e. most users). The drawback is that there's more cache misses here during the @@ -151,73 +151,37 @@ void NpScene::fetchResultsPostContactCallbacks() const float oneOverDt = mElapsedTime != 0.0f ? 1.0f/mElapsedTime : 0.0f; - if(1) - { - // PT: this version assumes we index mRigidDynamicsAccelerations as we do mRigidDynamics (with getRigidActorArrayIndex), i.e. we - // need to update that array when objects are removed (see removeFromRigidActorListT) - - PxU32 size = mRigidDynamics.size(); - if(mRigidDynamicsAccelerations.size()!=size) - { - mRigidDynamicsAccelerations.resize(size); - } + // PT: this version assumes we index mRigidDynamicsAccelerations as we do mRigidDynamics (with getRigidActorArrayIndex), i.e. we + // need to update that array when objects are removed (see removeFromRigidActorListT) - NpRigidDynamic** rigidDynamics = mRigidDynamics.begin(); - Acceleration* accels = mRigidDynamicsAccelerations.begin(); - while(size--) - { - const NpRigidDynamic* current = *rigidDynamics++; - const Sc::BodyCore& core = current->getCore(); - - const PxVec3 linVel = core.getLinearVelocity(); - const PxVec3 angVel = core.getAngularVelocity(); + // PT: another (archived) version used getRigidActorSceneIndex(). The acceleration array could become larger than necessary, + // but the index was constant for the lifetime of the object. At this point we could just have used a hashmap. - const PxVec3 deltaLinVel = linVel - accels->mPrevLinVel; - const PxVec3 deltaAngVel = angVel - accels->mPrevAngVel; + PxU32 size = mRigidDynamics.size(); + NpRigidDynamic** rigidDynamics = mRigidDynamics.begin(); - accels->mLinAccel = deltaLinVel * oneOverDt; - accels->mAngAccel = deltaAngVel * oneOverDt; + if(mRigidDynamicsAccelerations.size()!=size) + mRigidDynamicsAccelerations.resize(size); - accels->mPrevLinVel = linVel; - accels->mPrevAngVel = angVel; - - accels++; - } - } - else + Acceleration* accels = mRigidDynamicsAccelerations.begin(); + while(size--) { - // PT: this version uses getRigidActorSceneIndex(). The acceleration array can become larger than necessary, - // but the index is constant for the lifetime of the object. At this point we could just use a hashmap. - - PxU32 size = mRigidDynamics.size(); - NpRigidDynamic** rigidDynamics = mRigidDynamics.begin(); - while(size--) - { - const NpRigidDynamic* current = *rigidDynamics++; - - const PxU32 index = current->getRigidActorSceneIndex(); - if(index+1>mRigidDynamicsAccelerations.size()) - { - mRigidDynamicsAccelerations.resize(index+1); - } - Acceleration* accels = mRigidDynamicsAccelerations.begin(); - accels += index; + const NpRigidDynamic* current = *rigidDynamics++; + const Sc::BodyCore& core = current->getCore(); - const Sc::BodyCore& core = current->getCore(); + const PxVec3 linVel = core.getLinearVelocity(); + const PxVec3 angVel = core.getAngularVelocity(); - const PxVec3 linVel = core.getLinearVelocity(); - const PxVec3 angVel = core.getAngularVelocity(); + const PxVec3 deltaLinVel = linVel - accels->mPrevLinVel; + const PxVec3 deltaAngVel = angVel - accels->mPrevAngVel; - const PxVec3 deltaLinVel = linVel - accels->mPrevLinVel; - const PxVec3 deltaAngVel = angVel - accels->mPrevAngVel; + accels->mLinAccel = deltaLinVel * oneOverDt; + accels->mAngAccel = deltaAngVel * oneOverDt; - accels->mLinAccel = deltaLinVel * oneOverDt; - accels->mAngAccel = deltaAngVel * oneOverDt; - - accels->mPrevLinVel = linVel; - accels->mPrevAngVel = angVel; - } + accels->mPrevLinVel = linVel; + accels->mPrevAngVel = angVel; + accels++; } } diff --git a/physx/version.txt b/physx/version.txt index 6d3e30c71..30accbe15 100644 --- a/physx/version.txt +++ b/physx/version.txt @@ -1 +1 @@ -5.4.1.82786122 \ No newline at end of file +5.4.2.9950ad0d \ No newline at end of file